From 0cf36a890682f8eb44037a3c8f0606c95e50c401 Mon Sep 17 00:00:00 2001 From: Anis Date: Mon, 15 Dec 2014 18:59:42 +0100 Subject: [PATCH 1/6] mipmap support on DDS for openGL cubemap --- Engine/source/gfx/gl/gfxGLCubemap.cpp | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/Engine/source/gfx/gl/gfxGLCubemap.cpp b/Engine/source/gfx/gl/gfxGLCubemap.cpp index cdc41641e..41f2bf471 100644 --- a/Engine/source/gfx/gl/gfxGLCubemap.cpp +++ b/Engine/source/gfx/gl/gfxGLCubemap.cpp @@ -123,24 +123,21 @@ void GFXGLCubemap::initStatic( DDSFile *dds ) mDDSFile = ResourceManager::get().load( dds->getSourcePath() ); AssertFatal( mDDSFile == dds, "GFXGLCubemap::initStatic - Couldn't find DDSFile resource!" ); + mWidth = dds->getWidth(); + mHeight = dds->getHeight(); + mFaceFormat = dds->getFormat(); + mMipLevels = dds->getMipLevels(); + glGenTextures(1, &mCubemap); PRESERVE_CUBEMAP_TEXTURE(); glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0 ); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 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); - - mWidth = dds->getWidth(); - mHeight = dds->getHeight(); - mFaceFormat = dds->getFormat(); - mMipLevels = 1; - - // TODO: Support mipmaps here as well as decompressing the - // DDS if the format is unsupported. AssertFatal(mWidth == mHeight, "GFXGLCubemap::initStatic - Width and height must be equal!"); @@ -151,13 +148,11 @@ void GFXGLCubemap::initStatic( DDSFile *dds ) // TODO: The DDS can skip surfaces, but i'm unsure what i should // do here when creating the cubemap. Ignore it for now. continue; - } + } - const U8 *buffer = dds->mSurfaces[i]->mMips[0]; - U32 surfaceSize = dds->getSurfaceSize( mHeight, mWidth, i ); - - glCompressedTexImage2D( faceList[i], 0, GFXGLTextureInternalFormat[mFaceFormat], - mWidth, mHeight, 0, surfaceSize, buffer ); + // Now loop thru the mip levels! + for (U32 j = 0; j < mMipLevels; j++) + glCompressedTexImage2D(faceList[i], j, GFXGLTextureInternalFormat[mFaceFormat], mWidth, mHeight, 0, dds->getSurfaceSize(j), dds->mSurfaces[i]->mMips[j]); } } From ca04726ad62d6b0d8b83f3d98749bf60a79ac6a3 Mon Sep 17 00:00:00 2001 From: Anis Date: Tue, 16 Dec 2014 15:14:30 +0100 Subject: [PATCH 2/6] glGenerateMipmap on uncompressed cubemap --- Engine/source/gfx/gl/gfxGLCubemap.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Engine/source/gfx/gl/gfxGLCubemap.cpp b/Engine/source/gfx/gl/gfxGLCubemap.cpp index 41f2bf471..b20f27bf1 100644 --- a/Engine/source/gfx/gl/gfxGLCubemap.cpp +++ b/Engine/source/gfx/gl/gfxGLCubemap.cpp @@ -89,6 +89,8 @@ void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces) 0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], buf); delete[] buf; } + + glGenerateMipmap(GL_TEXTURE_CUBE_MAP); } void GFXGLCubemap::initStatic(GFXTexHandle* faces) From 9150c7f5ab23c90360f0a4fba4b561dbcbd425c9 Mon Sep 17 00:00:00 2001 From: LuisAntonRebollo Date: Fri, 26 Dec 2014 20:58:22 +0100 Subject: [PATCH 3/6] OpenGL: Mipmaps for GFXGLCubemap. --- Engine/source/gfx/gl/gfxGLCubemap.cpp | 49 ++++++++++++++------- Engine/source/gfx/gl/gfxGLTextureObject.cpp | 13 ++++-- Engine/source/gfx/gl/gfxGLTextureObject.h | 2 +- 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/Engine/source/gfx/gl/gfxGLCubemap.cpp b/Engine/source/gfx/gl/gfxGLCubemap.cpp index b20f27bf1..381df9114 100644 --- a/Engine/source/gfx/gl/gfxGLCubemap.cpp +++ b/Engine/source/gfx/gl/gfxGLCubemap.cpp @@ -56,9 +56,12 @@ GFXGLCubemap::~GFXGLCubemap() 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, 0 ); // TODO OPENGL GFXGLCubemap mipmaps + 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); @@ -68,10 +71,11 @@ void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces) U32 reqWidth = faces[0]->getWidth(); U32 reqHeight = faces[0]->getHeight(); GFXFormat regFaceFormat = faces[0]->getFormat(); + const bool isCompressed = isCompressedFormat(regFaceFormat); mWidth = reqWidth; mHeight = reqHeight; mFaceFormat = regFaceFormat; - mMipLevels = 1; // Lie for now + mMipLevels = getMax( (U32)1, faces[0]->mMipLevels); AssertFatal(reqWidth == reqHeight, "GFXGLCubemap::fillCubeTextures - Width and height must be equal!"); for(U32 i = 0; i < 6; i++) @@ -83,14 +87,19 @@ void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces) mTextures[i] = faces[i]; GFXFormat faceFormat = faces[i]->getFormat(); - GFXGLTextureObject* glTex = static_cast(faces[i].getPointer()); - U8* buf = glTex->getTextureData(); - glTexImage2D(faceList[i], 0, GFXGLTextureInternalFormat[faceFormat], faces[i]->getWidth(), faces[i]->getHeight(), - 0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], buf); - delete[] buf; + GFXGLTextureObject* glTex = static_cast(faces[i].getPointer()); + const U32 mipCount = isCompressed ? mMipLevels : 1; + for( U32 mip = 0; mip < mipCount; ++mip ) + { + U8* buf = glTex->getTextureData( mip ); + glTexImage2D(faceList[i], mip, GFXGLTextureInternalFormat[faceFormat], faces[i]->getWidth(), faces[i]->getHeight(), + 0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], buf); + delete[] buf; + } } - glGenerateMipmap(GL_TEXTURE_CUBE_MAP); + if( !isCompressed ) + glGenerateMipmap(GL_TEXTURE_CUBE_MAP); } void GFXGLCubemap::initStatic(GFXTexHandle* faces) @@ -150,11 +159,11 @@ void GFXGLCubemap::initStatic( DDSFile *dds ) // TODO: The DDS can skip surfaces, but i'm unsure what i should // do here when creating the cubemap. Ignore it for now. continue; - } + } - // Now loop thru the mip levels! - for (U32 j = 0; j < mMipLevels; j++) - glCompressedTexImage2D(faceList[i], j, GFXGLTextureInternalFormat[mFaceFormat], mWidth, mHeight, 0, dds->getSurfaceSize(j), dds->mSurfaces[i]->mMips[j]); + // Now loop thru the mip levels! + for (U32 j = 0; j < mMipLevels; j++) + glCompressedTexImage2D(faceList[i], j, GFXGLTextureInternalFormat[mFaceFormat], mWidth, mHeight, 0, dds->getSurfaceSize(j), dds->mSurfaces[i]->mMips[j]); } } @@ -162,10 +171,13 @@ void GFXGLCubemap::initDynamic(U32 texSize, GFXFormat faceFormat) { mDynamicTexSize = texSize; mFaceFormat = faceFormat; + const bool isCompressed = isCompressedFormat(faceFormat); + mMipLevels = getMax( (U32)1, getMaxMipmaps( texSize, texSize, 1 ) ); glGenTextures(1, &mCubemap); PRESERVE_CUBEMAP_TEXTURE(); glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 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); @@ -173,12 +185,19 @@ void GFXGLCubemap::initDynamic(U32 texSize, GFXFormat faceFormat) glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); mWidth = texSize; mHeight = texSize; - mMipLevels = 1; + for(U32 i = 0; i < 6; i++) { - glTexImage2D( faceList[i], 0, GFXGLTextureInternalFormat[faceFormat], texSize, texSize, - 0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], NULL); + const U32 mipCount = isCompressed ? mMipLevels : 1; + for( U32 mip = 0; mip < mipCount; ++mip ) + { + glTexImage2D( faceList[i], mip, GFXGLTextureInternalFormat[faceFormat], texSize, texSize, + 0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], NULL); + } } + + if( !isCompressed ) + glGenerateMipmap(GL_TEXTURE_CUBE_MAP); } void GFXGLCubemap::zombify() diff --git a/Engine/source/gfx/gl/gfxGLTextureObject.cpp b/Engine/source/gfx/gl/gfxGLTextureObject.cpp index 423899f70..8e2627a79 100644 --- a/Engine/source/gfx/gl/gfxGLTextureObject.cpp +++ b/Engine/source/gfx/gl/gfxGLTextureObject.cpp @@ -243,12 +243,19 @@ void GFXGLTextureObject::bind(U32 textureUnit) mSampler = ssd; } -U8* GFXGLTextureObject::getTextureData() +U8* GFXGLTextureObject::getTextureData( U32 mip ) { - U8* data = new U8[mTextureSize.x * mTextureSize.y * mBytesPerTexel]; + AssertFatal( mMipLevels, ""); + mip = (mip < mMipLevels) ? mip : 0; + + const U32 dataSize = isCompressedFormat(mFormat) + ? getCompressedSurfaceSize( mFormat, mTextureSize.x, mTextureSize.y, mip ) + : (mTextureSize.x >> mip) * (mTextureSize.y >> mip) * mBytesPerTexel; + + U8* data = new U8[dataSize]; PRESERVE_TEXTURE(mBinding); glBindTexture(mBinding, mHandle); - glGetTexImage(mBinding, 0, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], data); + glGetTexImage(mBinding, mip, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], data); return data; } diff --git a/Engine/source/gfx/gl/gfxGLTextureObject.h b/Engine/source/gfx/gl/gfxGLTextureObject.h index c3ebe9e23..90d748bab 100644 --- a/Engine/source/gfx/gl/gfxGLTextureObject.h +++ b/Engine/source/gfx/gl/gfxGLTextureObject.h @@ -51,7 +51,7 @@ public: /// @return An array containing the texture data /// @note You are responsible for deleting the returned data! (Use delete[]) - U8* getTextureData(); + U8* getTextureData( U32 mip = 0); virtual F32 getMaxUCoord() const; virtual F32 getMaxVCoord() const; From 2f8f89d4860e7d6592af4bc400a09603f742ae99 Mon Sep 17 00:00:00 2001 From: LuisAntonRebollo Date: Fri, 26 Dec 2014 21:24:14 +0100 Subject: [PATCH 4/6] OpenGL: Mipmaps for GFXGLCubemap. Fix mipmaps size. --- Engine/source/gfx/gl/gfxGLCubemap.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Engine/source/gfx/gl/gfxGLCubemap.cpp b/Engine/source/gfx/gl/gfxGLCubemap.cpp index 381df9114..a96bdfb60 100644 --- a/Engine/source/gfx/gl/gfxGLCubemap.cpp +++ b/Engine/source/gfx/gl/gfxGLCubemap.cpp @@ -92,7 +92,9 @@ void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces) for( U32 mip = 0; mip < mipCount; ++mip ) { U8* buf = glTex->getTextureData( mip ); - glTexImage2D(faceList[i], mip, GFXGLTextureInternalFormat[faceFormat], faces[i]->getWidth(), faces[i]->getHeight(), + const U32 mipWidth = getMax( U32(1), faces[i]->getWidth() >> mip ); + const U32 mipHeight = getMax( U32(1), faces[i]->getHeight() >> mip ); + glTexImage2D(faceList[i], mip, GFXGLTextureInternalFormat[faceFormat], mipWidth, mipHeight, 0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], buf); delete[] buf; } @@ -162,8 +164,12 @@ void GFXGLCubemap::initStatic( DDSFile *dds ) } // Now loop thru the mip levels! - for (U32 j = 0; j < mMipLevels; j++) - glCompressedTexImage2D(faceList[i], j, GFXGLTextureInternalFormat[mFaceFormat], mWidth, mHeight, 0, dds->getSurfaceSize(j), dds->mSurfaces[i]->mMips[j]); + for (U32 mip = 0; mip < mMipLevels; ++mip) + { + const U32 mipWidth = getMax( U32(1), mWidth >> mip ); + const U32 mipHeight = getMax( U32(1), mHeight >> mip ); + glCompressedTexImage2D(faceList[i], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, dds->getSurfaceSize(mip), dds->mSurfaces[i]->mMips[mip]); + } } } @@ -191,7 +197,8 @@ void GFXGLCubemap::initDynamic(U32 texSize, GFXFormat faceFormat) const U32 mipCount = isCompressed ? mMipLevels : 1; for( U32 mip = 0; mip < mipCount; ++mip ) { - glTexImage2D( faceList[i], mip, GFXGLTextureInternalFormat[faceFormat], texSize, texSize, + const U32 mipSize = getMax( U32(1), texSize >> mip ); + glTexImage2D( faceList[i], mip, GFXGLTextureInternalFormat[faceFormat], mipSize, mipSize, 0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], NULL); } } From c2c9cf4a2dfa9d024e246845994c15850b43aee6 Mon Sep 17 00:00:00 2001 From: LuisAntonRebollo Date: Sat, 27 Dec 2014 00:01:21 +0100 Subject: [PATCH 5/6] OpenGL: Mipmaps for GFXGLCubemap. Fix compressed textures. --- Engine/source/gfx/gl/gfxGLCubemap.cpp | 43 ++++++++++++++------- Engine/source/gfx/gl/gfxGLTextureObject.cpp | 6 ++- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/Engine/source/gfx/gl/gfxGLCubemap.cpp b/Engine/source/gfx/gl/gfxGLCubemap.cpp index a96bdfb60..295b2c96f 100644 --- a/Engine/source/gfx/gl/gfxGLCubemap.cpp +++ b/Engine/source/gfx/gl/gfxGLCubemap.cpp @@ -88,13 +88,23 @@ void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces) GFXFormat faceFormat = faces[i]->getFormat(); GFXGLTextureObject* glTex = static_cast(faces[i].getPointer()); - const U32 mipCount = isCompressed ? mMipLevels : 1; - for( U32 mip = 0; mip < mipCount; ++mip ) + if( isCompressed ) { - U8* buf = glTex->getTextureData( mip ); - const U32 mipWidth = getMax( U32(1), faces[i]->getWidth() >> mip ); - const U32 mipHeight = getMax( U32(1), faces[i]->getHeight() >> mip ); - glTexImage2D(faceList[i], mip, GFXGLTextureInternalFormat[faceFormat], mipWidth, mipHeight, + for( U32 mip = 0; mip < mMipLevels; ++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(faceList[i], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, mipDataSize, buf); + delete[] buf; + } + } + else + { + U8* buf = glTex->getTextureData(); + glTexImage2D(faceList[i], 0, GFXGLTextureInternalFormat[faceFormat], mWidth, mHeight, 0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], buf); delete[] buf; } @@ -192,16 +202,23 @@ void GFXGLCubemap::initDynamic(U32 texSize, GFXFormat faceFormat) mWidth = texSize; mHeight = texSize; - for(U32 i = 0; i < 6; i++) - { - const U32 mipCount = isCompressed ? mMipLevels : 1; - for( U32 mip = 0; mip < mipCount; ++mip ) + for(U32 i = 0; i < 6; i++) + { + if( isCompressedFormat(faceFormat) ) { - const U32 mipSize = getMax( U32(1), texSize >> mip ); - glTexImage2D( faceList[i], mip, GFXGLTextureInternalFormat[faceFormat], mipSize, mipSize, + for( U32 mip = 0; mip < mMipLevels; ++mip ) + { + const U32 mipSize = getMax( U32(1), texSize >> mip ); + const U32 mipDataSize = getCompressedSurfaceSize( mFaceFormat, texSize, texSize, mip ); + glCompressedTexImage2D(faceList[i], mip, GFXGLTextureInternalFormat[mFaceFormat], mipSize, mipSize, 0, mipDataSize, NULL); + } + } + else + { + glTexImage2D( faceList[i], 0, GFXGLTextureInternalFormat[faceFormat], texSize, texSize, 0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], NULL); } - } + } if( !isCompressed ) glGenerateMipmap(GL_TEXTURE_CUBE_MAP); diff --git a/Engine/source/gfx/gl/gfxGLTextureObject.cpp b/Engine/source/gfx/gl/gfxGLTextureObject.cpp index 8e2627a79..ed229e5d9 100644 --- a/Engine/source/gfx/gl/gfxGLTextureObject.cpp +++ b/Engine/source/gfx/gl/gfxGLTextureObject.cpp @@ -255,7 +255,11 @@ U8* GFXGLTextureObject::getTextureData( U32 mip ) U8* data = new U8[dataSize]; PRESERVE_TEXTURE(mBinding); glBindTexture(mBinding, mHandle); - glGetTexImage(mBinding, mip, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], data); + + if( isCompressedFormat(mFormat) ) + glGetCompressedTexImage( mBinding, mip, data ); + else + glGetTexImage(mBinding, mip, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], data); return data; } From 6789270789c47fc0e40781e8f754aec63f827f9f Mon Sep 17 00:00:00 2001 From: LuisAntonRebollo Date: Sat, 27 Dec 2014 03:03:33 +0100 Subject: [PATCH 6/6] OpenGL: Mipmaps for GFXGLCubemap. Fix dynamic cubemaps. --- Engine/source/gfx/gl/gfxGLTextureTarget.cpp | 29 ++++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/Engine/source/gfx/gl/gfxGLTextureTarget.cpp b/Engine/source/gfx/gl/gfxGLTextureTarget.cpp index 9bbeb10e2..1569b9a85 100644 --- a/Engine/source/gfx/gl/gfxGLTextureTarget.cpp +++ b/Engine/source/gfx/gl/gfxGLTextureTarget.cpp @@ -170,12 +170,15 @@ void _GFXGLTextureTargetFBOImpl::applyState() if(color) { hasColor = true; - if( color->getBinding( ) == GL_TEXTURE_2D ) + const GLenum binding = color->getBinding(); + if( binding == GL_TEXTURE_2D || (binding >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && binding <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) ) glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, color->getBinding( ), color->getHandle( ), color->getMipLevel( ) ); - else if( color->getBinding( ) == GL_TEXTURE_1D ) + else if( binding == GL_TEXTURE_1D ) glFramebufferTexture1D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, color->getBinding( ), color->getHandle( ), color->getMipLevel( ) ); - else if( color->getBinding( ) == GL_TEXTURE_3D ) + else if( binding == GL_TEXTURE_3D ) glFramebufferTexture3D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, color->getBinding( ), color->getHandle( ), color->getMipLevel( ), color->getZOffset( ) ); + else + Con::errorf("_GFXGLTextureTargetFBOImpl::applyState - Bad binding"); } else { @@ -232,9 +235,12 @@ void _GFXGLTextureTargetFBOImpl::finish() // Generate mips if necessary // Assumes a 2D texture. - PRESERVE_TEXTURE(color->getBinding()); - glBindTexture(color->getBinding(), color->getHandle()); - glGenerateMipmapEXT(GL_TEXTURE_2D); + GLenum binding = color->getBinding(); + binding = (binding >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && binding <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) ? GL_TEXTURE_CUBE_MAP : binding; + + PRESERVE_TEXTURE( binding ); + glBindTexture( binding, color->getHandle() ); + glGenerateMipmap( binding ); } } @@ -385,9 +391,12 @@ void GFXGLTextureTarget::resolveTo(GFXTextureObject* obj) if( gglHasExtension(ARB_copy_image) && mTargets[Color0]->isCompatible(glTexture) ) { + GLenum binding = mTargets[Color0]->getBinding(); + binding = (binding >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && binding <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) ? GL_TEXTURE_CUBE_MAP : binding; + U32 srcStartDepth = binding == GL_TEXTURE_CUBE_MAP ? mTargets[Color0]->getBinding() - GL_TEXTURE_CUBE_MAP_POSITIVE_X : 0; glCopyImageSubData( - mTargets[Color0]->getHandle(), GL_TEXTURE_2D, 0, 0, 0, 0, - glTexture->getHandle(), GL_TEXTURE_2D, 0, 0, 0, 0, + mTargets[Color0]->getHandle(), binding, 0, 0, 0, srcStartDepth, + glTexture->getHandle(), glTexture->getBinding(), 0, 0, 0, 0, mTargets[Color0]->getWidth(), mTargets[Color0]->getHeight(), 1); return; @@ -396,10 +405,10 @@ void GFXGLTextureTarget::resolveTo(GFXTextureObject* obj) PRESERVE_FRAMEBUFFER(); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mCopyFboDst); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glTexture->getHandle(), 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glTexture->getBinding(), glTexture->getHandle(), 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, mCopyFboSrc); - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,mTargets[Color0]->getHandle(), 0); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTargets[Color0]->getBinding(), mTargets[Color0]->getHandle(), 0); glBlitFramebuffer(0, 0, mTargets[Color0]->getWidth(), mTargets[Color0]->getHeight(), 0, 0, glTexture->getWidth(), glTexture->getHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);