123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "gfx/gl/gfxGLDevice.h"
- #include "gfx/gl/gfxGLTextureObject.h"
- #include "gfx/gl/gfxGLEnumTranslate.h"
- #include "gfx/gl/gfxGLUtils.h"
- #include "gfx/gl/gfxGLCubemap.h"
- #include "gfx/gfxTextureManager.h"
- #include "gfx/gfxCardProfile.h"
- #include "gfx/bitmap/ddsFile.h"
- #include "gfx/bitmap/imageUtils.h"
- GFXGLCubemap::GFXGLCubemap() :
- mCubemap(0),
- mDynamicTexSize(0),
- mWidth(0),
- mHeight(0),
- mFaceFormat( GFXFormatR8G8B8A8 )
- {
- for(U32 i = 0; i < 6; i++)
- mTextures[i] = NULL;
-
- GFXTextureManager::addEventDelegate( this, &GFXGLCubemap::_onTextureEvent );
- }
- GFXGLCubemap::~GFXGLCubemap()
- {
- glDeleteTextures(1, &mCubemap);
- GFXTextureManager::removeEventDelegate( this, &GFXGLCubemap::_onTextureEvent );
- }
- GLenum GFXGLCubemap::getEnumForFaceNumber(U32 face)
- {
- return GFXGLFaceType[face];
- }
- void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces)
- {
- AssertFatal( faces, "");
- AssertFatal( faces[0]->mMipLevels > 0, "");
- PRESERVE_CUBEMAP_TEXTURE();
- glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, faces[0]->mMipLevels - 1 );
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
-
- U32 reqWidth = faces[0]->getWidth();
- U32 reqHeight = faces[0]->getHeight();
- GFXFormat regFaceFormat = faces[0]->getFormat();
- const bool isCompressed = ImageUtil::isCompressedFormat(regFaceFormat);
- mWidth = reqWidth;
- mHeight = reqHeight;
- mFaceFormat = regFaceFormat;
- mMipMapLevels = getMax( (U32)1, faces[0]->mMipLevels);
- AssertFatal(reqWidth == reqHeight, "GFXGLCubemap::fillCubeTextures - Width and height must be equal!");
-
- for(U32 i = 0; i < 6; i++)
- {
- AssertFatal(faces[i], avar("GFXGLCubemap::fillCubeFaces - texture %i is NULL!", i));
- AssertFatal((faces[i]->getWidth() == reqWidth) && (faces[i]->getHeight() == reqHeight), "GFXGLCubemap::fillCubeFaces - All textures must have identical dimensions!");
- AssertFatal(faces[i]->getFormat() == regFaceFormat, "GFXGLCubemap::fillCubeFaces - All textures must have identical formats!");
-
- mTextures[i] = faces[i];
- GFXFormat faceFormat = faces[i]->getFormat();
- GFXGLTextureObject* glTex = static_cast<GFXGLTextureObject*>(faces[i].getPointer());
- if( isCompressed )
- {
- for( U32 mip = 0; mip < mMipMapLevels; ++mip )
- {
- const U32 mipWidth = getMax( U32(1), faces[i]->getWidth() >> mip );
- const U32 mipHeight = getMax( U32(1), faces[i]->getHeight() >> mip );
- const U32 mipDataSize = getCompressedSurfaceSize( mFaceFormat, mWidth, mHeight, mip );
- U8* buf = glTex->getTextureData( mip );
- glCompressedTexImage2D(GFXGLFaceType[i], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, mipDataSize, buf);
- delete[] buf;
- }
- }
- else
- {
- U8* buf = glTex->getTextureData();
- glTexImage2D(GFXGLFaceType[i], 0, GFXGLTextureInternalFormat[faceFormat], mWidth, mHeight,
- 0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], buf);
- delete[] buf;
- }
- }
-
- if( !isCompressed )
- glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
- }
- void GFXGLCubemap::initStatic(GFXTexHandle* faces)
- {
- if(mCubemap)
- return;
-
- if(faces)
- {
- AssertFatal(faces[0], "GFXGLCubemap::initStatic - empty texture passed");
- glGenTextures(1, &mCubemap);
- fillCubeTextures(faces);
- }
- mInitialized = true;
- }
- void GFXGLCubemap::initStatic( DDSFile *dds )
- {
- if(mCubemap)
- return;
-
- AssertFatal( dds, "GFXGLCubemap::initStatic - Got null DDS file!" );
- AssertFatal( dds->isCubemap(), "GFXGLCubemap::initStatic - Got non-cubemap DDS file!" );
- AssertFatal( dds->mSurfaces.size() == 6, "GFXGLCubemap::initStatic - DDS has less than 6 surfaces!" );
- mWidth = dds->getWidth();
- mHeight = dds->getHeight();
- mFaceFormat = dds->getFormat();
- mMipMapLevels = dds->getMipLevels();
- const bool isCompressed = ImageUtil::isCompressedFormat(mFaceFormat);
- glGenTextures(1, &mCubemap);
- PRESERVE_CUBEMAP_TEXTURE();
- glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, mMipMapLevels - 1);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
- AssertFatal(mWidth == mHeight, "GFXGLCubemap::initStatic - Width and height must be equal!");
-
- for(U32 i = 0; i < 6; i++)
- {
- if ( !dds->mSurfaces[i] )
- {
- // TODO: The DDS can skip surfaces, but i'm unsure what i should
- // do here when creating the cubemap. Ignore it for now.
- continue;
- }
- // convert to Z up
- const U32 faceIndex = zUpFaceIndex(i);
- // Now loop thru the mip levels!
- for (U32 mip = 0; mip < mMipMapLevels; ++mip)
- {
- const U32 mipWidth = getMax( U32(1), mWidth >> mip );
- const U32 mipHeight = getMax( U32(1), mHeight >> mip );
- if (isCompressed)
- glCompressedTexImage2D(GFXGLFaceType[faceIndex], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, dds->getSurfaceSize(mip), dds->mSurfaces[i]->mMips[mip]);
- else
- glTexImage2D(GFXGLFaceType[faceIndex], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0,
- GFXGLTextureFormat[mFaceFormat], GFXGLTextureType[mFaceFormat], dds->mSurfaces[i]->mMips[mip]);
- }
- }
- mInitialized = true;
- }
- void GFXGLCubemap::initDynamic(U32 texSize, GFXFormat faceFormat, U32 mipLevels)
- {
- mDynamicTexSize = texSize;
- mFaceFormat = faceFormat;
- const bool isCompressed = ImageUtil::isCompressedFormat(faceFormat);
- mMipMapLevels = ImageUtil::getMaxMipCount( texSize, texSize);
- glGenTextures(1, &mCubemap);
- PRESERVE_CUBEMAP_TEXTURE();
- glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, mMipMapLevels - 1);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
- mWidth = texSize;
- mHeight = texSize;
- for(U32 i = 0; i < 6; i++)
- {
- if( ImageUtil::isCompressedFormat(faceFormat) )
- {
- for( U32 mip = 0; mip < mMipMapLevels; ++mip )
- {
- const U32 mipSize = getMax( U32(1), texSize >> mip );
- const U32 mipDataSize = getCompressedSurfaceSize( mFaceFormat, texSize, texSize, mip );
- glCompressedTexImage2D(GFXGLFaceType[i], mip, GFXGLTextureInternalFormat[mFaceFormat], mipSize, mipSize, 0, mipDataSize, NULL);
- }
- }
- else
- {
- glTexImage2D( GFXGLFaceType[i], 0, GFXGLTextureInternalFormat[faceFormat], texSize, texSize,
- 0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], NULL);
- }
- }
- if( !isCompressed && !mipLevels)
- glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
- mInitialized = true;
- }
- void GFXGLCubemap::zombify()
- {
- glDeleteTextures(1, &mCubemap);
- mCubemap = 0;
- }
- void GFXGLCubemap::resurrect()
- {
- // Handled in tmResurrect
- }
- void GFXGLCubemap::tmResurrect()
- {
- if(mDynamicTexSize)
- initDynamic(mDynamicTexSize,mFaceFormat);
- else
- {
- if ( mDDSFile )
- initStatic( mDDSFile );
- else
- initStatic( mTextures );
- }
- }
- void GFXGLCubemap::setToTexUnit(U32 tuNum)
- {
- static_cast<GFXGLDevice*>(getOwningDevice())->setCubemapInternal(tuNum, this);
- }
- void GFXGLCubemap::bind(U32 textureUnit) const
- {
- glActiveTexture(GL_TEXTURE0 + textureUnit);
- glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap);
- static_cast<GFXGLDevice*>(getOwningDevice())->getOpenglCache()->setCacheBindedTex(textureUnit, GL_TEXTURE_CUBE_MAP, 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, GL_TEXTURE_MIN_FILTER, minificationFilter(ssd.minFilter, ssd.mipFilter, 0));
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GFXGLTextureFilter[ssd.magFilter]);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GFXGLTextureAddress[ssd.addressModeU]);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GFXGLTextureAddress[ssd.addressModeV]);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GFXGLTextureAddress[ssd.addressModeW]);
- }
- void GFXGLCubemap::_onTextureEvent( GFXTexCallbackCode code )
- {
- if ( code == GFXZombify )
- zombify();
- else
- tmResurrect();
- }
- U8* GFXGLCubemap::getTextureData(U32 face, U32 mip)
- {
- AssertFatal(mMipMapLevels, "");
- mip = (mip < mMipMapLevels) ? mip : 0;
- const U32 bytesPerTexel = 8; //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(GFXGLFaceType[face], mip, data);
- else
- glGetTexImage(GFXGLFaceType[face], mip, GFXGLTextureFormat[mFaceFormat], GFXGLTextureType[mFaceFormat], data);
- return data;
- }
- //-----------------------------------------------------------------------------
- // Cubemap Array
- //-----------------------------------------------------------------------------
- GFXGLCubemapArray::GFXGLCubemapArray()
- {
- mCubemap = 0;
- }
- 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!");
- setCubeTexSize(cubemaps);
- mFormat = cubemaps[0]->getFormat();
- 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, mMin(mMipMapLevels - 1, 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());
- //yes checking the first one(cubemap at index 0) is pointless but saves a further if statement
- if (cubemaps[i]->getSize() != mSize || cubemaps[i]->getFormat() != mFormat || cubemaps[i]->getMipMapLevels() != mMipMapLevels)
- {
- Con::printf("Trying to add an invalid Cubemap to a CubemapArray");
- //destroy array here first
- AssertFatal(false, "GFXD3D11CubemapArray::initStatic - invalid cubemap");
- }
- for (U32 face = 0; face < 6; face++)
- {
- for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
- {
- U8 *pixelData = glTex->getTextureData(face, currentMip);
- glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
- const U32 mipSize = getMax(U32(1), mSize >> currentMip);
- if (isCompressed)
- {
- const U32 mipDataSize = getCompressedSurfaceSize(mFormat, mSize, mSize, currentMip);
- glCompressedTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, i * 6 + face, mipSize, mipSize, 1, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
- }
- else
- {
- glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, i * 6 + face, mipSize, mipSize, 1, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
- }
- glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
- 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)
- {
- setCubeTexSize(cubemapFaceSize);
- mFormat = format;
- mNumCubemaps = cubemapCount;
- const bool isCompressed = ImageUtil::isCompressedFormat(mFormat);
- glGenTextures(1, &mCubemap);
- PRESERVE_CUBEMAP_ARRAY_TEXTURE();
- glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
- for (U32 i = 0; i < mMipMapLevels; i++)
- {
- const U32 mipSize = getMax(U32(1), mSize >> i);
- glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, GFXGLTextureInternalFormat[mFormat], mipSize, mipSize, cubemapCount * 6, 0, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], NULL);
- }
- 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);
- }
- 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!");
- if (!cubemap->isInitialized())
- return;
- 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++)
- {
- U8 *pixelData = glTex->getTextureData(face, currentMip);
- glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, mCubemap);
- const U32 mipSize = getMax(U32(1), mSize >> currentMip);
- if (isCompressed)
- {
- const U32 mipDataSize = getCompressedSurfaceSize(mFormat, mSize, mSize, currentMip);
- glCompressedTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, slot * 6 + face, mipSize, mipSize, 1, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
- }
- else
- {
- glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, slot * 6 + face, mipSize, mipSize, 1, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], pixelData);
- }
- glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
- 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(GFXGLFaceType[face], currentMip, GFXGLTextureInternalFormat[mFormat], mipSize, mipSize, 0, mipDataSize, pixelData);
- }
- else
- {*/ //TODO figure out xyzOffsets
- glCopyImageSubData(mCubemap, GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, cubeMap * face, pDstCube->mCubemap, GL_TEXTURE_CUBE_MAP_ARRAY, currentMip, 0, 0, cubeMap * face, 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]);
- }
|