diff --git a/Engine/source/gfx/gl/gfxGLDevice.cpp b/Engine/source/gfx/gl/gfxGLDevice.cpp index 0b1932f6e..57066acf9 100644 --- a/Engine/source/gfx/gl/gfxGLDevice.cpp +++ b/Engine/source/gfx/gl/gfxGLDevice.cpp @@ -47,6 +47,7 @@ #include "gfx/gl/gfxGLVertexAttribLocation.h" #include "gfx/gl/gfxGLVertexDecl.h" #include "shaderGen/shaderGen.h" +#include "gfxGLUtils.h" GFXAdapter::CreateDeviceInstanceDelegate GFXGLDevice::mCreateDeviceInstance(GFXGLDevice::createInstance); @@ -462,6 +463,43 @@ void GFXGLDevice::endSceneInternal() mCanCurrentlyRender = false; } +void GFXGLDevice::copyResource(GFXTextureObject* pDst, GFXCubemap* pSrc, const U32 face) +{ + AssertFatal(pDst, "GFXGLDevice::copyResource: Destination texture is null"); + AssertFatal(pSrc, "GFXGLDevice::copyResource: Source cubemap is null"); + + GFXGLTextureObject* gGLDst = static_cast(pDst); + GFXGLCubemap* pGLSrc = static_cast(pSrc); + + GFXFormat format = pGLSrc->getFormat(); + + const bool isCompressed = ImageUtil::isCompressedFormat(format); + + U32 mipLevels = pGLSrc->getMipMapLevels(); + if (mipLevels < 1) mipLevels = 1;//ensure we loop at least the once + for (U32 mip = 0; mip < mipLevels; mip++) + { + U8* pixelData = pGLSrc->getTextureData(face, mip); + + glBindTexture(gGLDst->getBinding(), gGLDst->getHandle()); + const U32 mipSize = getMax(U32(1), pGLSrc->getSize() >> mip); + if (isCompressed) + { + const U32 mipDataSize = getCompressedSurfaceSize(format, pGLSrc->getSize(), pGLSrc->getSize(), 0); + + glCompressedTexSubImage2D(gGLDst->getBinding(), mip, 0, 0, mipSize, mipSize, GFXGLTextureFormat[format], mipDataSize, pixelData); + } + else + { + //glCopyImageSubData(pGLSrc->mCubemap, GFXGLCubemap::getEnumForFaceNumber(face), mip, 0, 0, face, gGLDst->getHandle(), GL_TEXTURE_2D, mip, 0, 0, 0, mipSize, mipSize, mip); + glTexSubImage2D(gGLDst->getBinding(), mip, 0, 0, mipSize, mipSize, GFXGLTextureFormat[format], GFXGLTextureType[format], pixelData); + } + glBindTexture(gGLDst->getBinding(), 0); + + delete[] pixelData; + } +} + void GFXGLDevice::clear(U32 flags, const LinearColorF& color, F32 z, U32 stencil) { // Make sure we have flushed our render target state. diff --git a/Engine/source/gfx/gl/gfxGLDevice.h b/Engine/source/gfx/gl/gfxGLDevice.h index a1234a158..3e127367e 100644 --- a/Engine/source/gfx/gl/gfxGLDevice.h +++ b/Engine/source/gfx/gl/gfxGLDevice.h @@ -118,7 +118,7 @@ public: virtual GFXShader* createShader(); //TODO: implement me! - virtual void copyResource(GFXTextureObject *pDst, GFXCubemap *pSrc, const U32 face) {}; + virtual void copyResource(GFXTextureObject *pDst, GFXCubemap *pSrc, const U32 face); virtual void clear( U32 flags, const LinearColorF& color, F32 z, U32 stencil ); virtual void clearColorAttachment(const U32 attachment, const LinearColorF& color); virtual bool beginSceneInternal(); diff --git a/Engine/source/gfx/gl/gfxGLTextureObject.cpp b/Engine/source/gfx/gl/gfxGLTextureObject.cpp index a7bc1d4f7..4dac801d3 100644 --- a/Engine/source/gfx/gl/gfxGLTextureObject.cpp +++ b/Engine/source/gfx/gl/gfxGLTextureObject.cpp @@ -175,30 +175,37 @@ bool GFXGLTextureObject::copyToBmp(GBitmap * bmp) FrameAllocatorMarker mem; - U32 srcPixelCount = mTextureSize.x * mTextureSize.y; - U8 *dest = bmp->getWritableBits(); - U8 *orig = (U8*)mem.alloc(srcPixelCount * srcBytesPerPixel); - glGetTexImage(mBinding, 0, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], orig); - - PROFILE_START(GFXGLTextureObject_copyToBmp_pixCopy); - if (mFormat == GFXFormatR16G16B16A16F) + U32 mipLevels = getMipLevels(); + if (mipLevels < 1) mipLevels = 1;//ensure we loop at least the once + for (U32 mip = 0; mip < mipLevels; mip++) { - dMemcpy(dest, orig, sizeof(U16) * 4); - } - else - { - for (int i = 0; i < srcPixelCount; ++i) - { - dest[0] = orig[0]; - dest[1] = orig[1]; - dest[2] = orig[2]; - if (dstBytesPerPixel == 4) - dest[3] = orig[3]; + U32 srcPixelCount = bmp->getSurfaceSize(mip)/ srcBytesPerPixel; - orig += srcBytesPerPixel; - dest += dstBytesPerPixel; - } + U8* dest = bmp->getWritableBits(mip); + U8* orig = (U8*)mem.alloc(srcPixelCount * srcBytesPerPixel); + + glGetTexImage(mBinding, mip, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], orig); + + PROFILE_START(GFXGLTextureObject_copyToBmp_pixCopy); + if (mFormat == GFXFormatR16G16B16A16F) + { + dMemcpy(dest, orig, srcPixelCount * sizeof(U16) * 4); + } + else + { + for (int i = 0; i < srcPixelCount; ++i) + { + dest[0] = orig[0]; + dest[1] = orig[1]; + dest[2] = orig[2]; + if (dstBytesPerPixel == 4) + dest[3] = orig[3]; + + orig += srcBytesPerPixel; + dest += dstBytesPerPixel; + } + } } PROFILE_END();