This commit is contained in:
Areloch 2019-04-15 23:11:18 -05:00
parent c025760422
commit 000c7b2263
21 changed files with 4102 additions and 108 deletions

View file

@ -31,7 +31,7 @@
#include "gfx/bitmap/imageUtils.h"
GLenum GFXGLCubemap::faceList[6] =
static GLenum faceList[6] =
{
GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
@ -55,6 +55,11 @@ GFXGLCubemap::~GFXGLCubemap()
GFXTextureManager::removeEventDelegate( this, &GFXGLCubemap::_onTextureEvent );
}
GLenum GFXGLCubemap::getEnumForFaceNumber(U32 face)
{
return faceList[face];
}
void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces)
{
AssertFatal( faces, "");
@ -280,3 +285,225 @@ void GFXGLCubemap::_onTextureEvent( GFXTexCallbackCode code )
else
tmResurrect();
}
U8* GFXGLCubemap::getTextureData(U32 face, U32 mip)
{
AssertFatal(mMipMapLevels, "");
mip = (mip < mMipMapLevels) ? mip : 0;
const U32 bytesPerTexel = 4; //TODO make work with more formats!!!!!
const U32 dataSize = ImageUtil::isCompressedFormat(mFaceFormat)
? getCompressedSurfaceSize(mFaceFormat, mWidth, mHeight, mip)
: (mWidth >> mip) * (mHeight >> mip) * bytesPerTexel;
U8* data = new U8[dataSize];
PRESERVE_TEXTURE(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap);
if (ImageUtil::isCompressedFormat(mFaceFormat))
glGetCompressedTexImage(faceList[face], mip, data);
else
glGetTexImage(faceList[face], mip, GFXGLTextureFormat[mFaceFormat], GFXGLTextureType[mFaceFormat], data);
return data;
}
//-----------------------------------------------------------------------------
// Cubemap Array
//-----------------------------------------------------------------------------
GFXGLCubemapArray::GFXGLCubemapArray()
{
}
GFXGLCubemapArray::~GFXGLCubemapArray()
{
glDeleteTextures(1, &mCubemap);
}
//TODO: really need a common private 'init' function to avoid code double up with these init* functions
void GFXGLCubemapArray::init(GFXCubemapHandle *cubemaps, const U32 cubemapCount)
{
AssertFatal(cubemaps, "GFXGLCubemapArray- Got null GFXCubemapHandle!");
AssertFatal(*cubemaps, "GFXGLCubemapArray - Got empty cubemap!");
//all cubemaps must be the same size,format and number of mipmaps. Grab the details from the first cubemap
mSize = cubemaps[0]->getSize();
mFormat = cubemaps[0]->getFormat();
mMipMapLevels = cubemaps[0]->getMipMapLevels();
mNumCubemaps = cubemapCount;
const bool isCompressed = ImageUtil::isCompressedFormat(mFormat);
glGenTextures(1, &mCubemap);
PRESERVE_CUBEMAP_ARRAY_TEXTURE();
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, mMipMapLevels - 1);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
for (U32 i = 0; i < cubemapCount; i++)
{
GFXGLCubemap* glTex = static_cast<GFXGLCubemap*>(cubemaps[i].getPointer());
for (U32 face = 0; face < 6; face++)
{
for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
//U32 currentMip = 0;
{
U8 *pixelData = glTex->getTextureData(face, currentMip);
const U32 mipSize = getMax(U32(1), mSize >> currentMip);
/*if (isCompressed)
{
const U32 mipDataSize = getCompressedSurfaceSize(mFormat, mSize, mSize, currentMip);
glCompressedTexImage2D(faceList[face], currentMip, GFXGLTextureInternalFormat[mFormat], mipSize, mipSize, 0, mipDataSize, pixelData);
}
else
{*/ //TODO figure out xyzOffsets
glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, 0, mipSize, mipSize, i * face, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
//}
delete[] pixelData;
}
}
}
}
//Just allocate the cubemap array but we don't upload any data
void GFXGLCubemapArray::init(const U32 cubemapCount, const U32 cubemapFaceSize, const GFXFormat format)
{
//all cubemaps must be the same size,format and number of mipmaps. Grab the details from the first cubemap
mSize = cubemapFaceSize;
mFormat = format;
mMipMapLevels = ImageUtil::getMaxMipCount(cubemapFaceSize, cubemapFaceSize);
mNumCubemaps = cubemapCount;
const bool isCompressed = ImageUtil::isCompressedFormat(mFormat);
glGenTextures(1, &mCubemap);
PRESERVE_CUBEMAP_ARRAY_TEXTURE();
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, mMipMapLevels - 1);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
/*for (U32 i = 0; i < cubemapCount; i++)
{
GFXGLCubemap* glTex = static_cast<GFXGLCubemap*>(cubemaps[i].getPointer());
for (U32 face = 0; face < 6; face++)
{
for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
{
U8 *pixelData = glTex->getTextureData(face, currentMip);
const U32 mipSize = getMax(U32(1), mSize >> currentMip);
if (isCompressed)
{
const U32 mipDataSize = getCompressedSurfaceSize(mFormat, mSize, mSize, currentMip);
glCompressedTexImage2D(faceList[face], currentMip, GFXGLTextureInternalFormat[mFormat], mipSize, mipSize, 0, mipDataSize, pixelData);
}
else
{
glTexImage2D(faceList[face], currentMip, GFXGLTextureInternalFormat[mFormat], mipSize, mipSize,
0, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
}
delete[] pixelData;
}
}
}*/
}
void GFXGLCubemapArray::updateTexture(const GFXCubemapHandle &cubemap, const U32 slot)
{
AssertFatal(slot <= mNumCubemaps, "GFXD3D11CubemapArray::updateTexture - trying to update a cubemap texture that is out of bounds!");
const bool isCompressed = ImageUtil::isCompressedFormat(mFormat);
GFXGLCubemap* glTex = static_cast<GFXGLCubemap*>(cubemap.getPointer());
for (U32 face = 0; face < 6; face++)
{
for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
//U32 currentMip = 0;
{
U8 *pixelData = glTex->getTextureData(face, currentMip);
const U32 mipSize = getMax(U32(1), mSize >> currentMip);
/*if (isCompressed)
{
const U32 mipDataSize = getCompressedSurfaceSize(mFormat, mSize, mSize, currentMip);
glCompressedTexImage2D(faceList[face], currentMip, GFXGLTextureInternalFormat[mFormat], mipSize, mipSize, 0, mipDataSize, pixelData);
}
else
{*/ //TODO figure out xyzOffsets
glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, 0, mipSize, mipSize, slot * face, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
//}
delete[] pixelData;
}
}
}
void GFXGLCubemapArray::copyTo(GFXCubemapArray *pDstCubemap)
{
AssertFatal(pDstCubemap, "GFXGLCubemapArray::copyTo - Got null GFXCubemapArray");
const U32 dstCount = pDstCubemap->getNumCubemaps();
const GFXFormat dstFmt = pDstCubemap->getFormat();
const U32 dstSize = pDstCubemap->getSize();
const U32 dstMips = pDstCubemap->getMipMapLevels();
AssertFatal(dstCount > mNumCubemaps, "GFXGLCubemapArray::copyTo - Destination too small");
AssertFatal(dstFmt == mFormat, "GFXGLCubemapArray::copyTo - Destination format doesn't match");
AssertFatal(dstSize == mSize, "GFXGLCubemapArray::copyTo - Destination size doesn't match");
AssertFatal(dstMips == mMipMapLevels, "GFXGLCubemapArray::copyTo - Destination mip levels doesn't match");
GFXGLCubemapArray* pDstCube = static_cast<GFXGLCubemapArray*>(pDstCubemap);
for (U32 cubeMap = 0; cubeMap < mNumCubemaps; cubeMap++)
{
for (U32 face = 0; face < CubeFaces; face++)
{
for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
//U32 currentMip = 0;
{
//U8 *pixelData = pDstCube->get->getTextureData(face, currentMip);
const U32 mipSize = getMax(U32(1), mSize >> currentMip);
/*if (isCompressed)
{
const U32 mipDataSize = getCompressedSurfaceSize(mFormat, mSize, mSize, currentMip);
glCompressedTexImage2D(faceList[face], currentMip, GFXGLTextureInternalFormat[mFormat], mipSize, mipSize, 0, mipDataSize, pixelData);
}
else
{*/ //TODO figure out xyzOffsets
glCopyImageSubData(mCubemap, GL_TEXTURE_CUBE_MAP_ARRAY, cubeMap * face, 0, 0, 0, pDstCube->mCubemap, GL_TEXTURE_CUBE_MAP_ARRAY, cubeMap * face, 0, 0, 0, mipSize, mipSize, 6);
//glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
//glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, 0, mipSize, mipSize, CubeFaces, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
//}
//delete[] pixelData;
}
}
}
}
void GFXGLCubemapArray::setToTexUnit(U32 tuNum)
{
static_cast<GFXGLDevice*>(getOwningDevice())->setCubemapArrayInternal(tuNum, this);
}
void GFXGLCubemapArray::bind(U32 textureUnit) const
{
glActiveTexture(GL_TEXTURE0 + textureUnit);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
static_cast<GFXGLDevice*>(getOwningDevice())->getOpenglCache()->setCacheBindedTex(textureUnit, GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
GFXGLStateBlockRef sb = static_cast<GFXGLDevice*>(GFX)->getCurrentStateBlock();
AssertFatal(sb, "GFXGLCubemap::bind - No active stateblock!");
if (!sb)
return;
const GFXSamplerStateDesc& ssd = sb->getDesc().samplers[textureUnit];
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, minificationFilter(ssd.minFilter, ssd.mipFilter, 0));
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GFXGLTextureFilter[ssd.magFilter]);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GFXGLTextureAddress[ssd.addressModeU]);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GFXGLTextureAddress[ssd.addressModeV]);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GFXGLTextureAddress[ssd.addressModeW]);
}