diff --git a/Engine/source/gfx/gl/gfxGLCubemap.cpp b/Engine/source/gfx/gl/gfxGLCubemap.cpp index 541cd4fc7..99f3f02a8 100644 --- a/Engine/source/gfx/gl/gfxGLCubemap.cpp +++ b/Engine/source/gfx/gl/gfxGLCubemap.cpp @@ -31,13 +31,6 @@ #include "gfx/bitmap/imageUtils.h" -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, - GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z -}; - GFXGLCubemap::GFXGLCubemap() : mCubemap(0), mDynamicTexSize(0), @@ -59,7 +52,7 @@ GFXGLCubemap::~GFXGLCubemap() GLenum GFXGLCubemap::getEnumForFaceNumber(U32 face) { - return faceList[face]; + return GFXGLFaceType[face]; } void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces) @@ -105,14 +98,14 @@ void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces) const U32 mipDataSize = getCompressedSurfaceSize( mFaceFormat, mWidth, mHeight, mip ); U8* buf = glTex->getTextureData( mip ); - glCompressedTexImage2D(faceList[i], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, mipDataSize, buf); + glCompressedTexImage2D(GFXGLFaceType[i], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, mipDataSize, buf); delete[] buf; } } else { U8* buf = glTex->getTextureData(); - glTexImage2D(faceList[i], 0, GFXGLTextureInternalFormat[faceFormat], mWidth, mHeight, + glTexImage2D(GFXGLFaceType[i], 0, GFXGLTextureInternalFormat[faceFormat], mWidth, mHeight, 0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], buf); delete[] buf; } @@ -181,9 +174,9 @@ void GFXGLCubemap::initStatic( DDSFile *dds ) const U32 mipWidth = getMax( U32(1), mWidth >> mip ); const U32 mipHeight = getMax( U32(1), mHeight >> mip ); if (isCompressed) - glCompressedTexImage2D(faceList[faceIndex], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, dds->getSurfaceSize(mip), dds->mSurfaces[i]->mMips[mip]); + glCompressedTexImage2D(GFXGLFaceType[faceIndex], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, dds->getSurfaceSize(mip), dds->mSurfaces[i]->mMips[mip]); else - glTexImage2D(faceList[faceIndex], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, + glTexImage2D(GFXGLFaceType[faceIndex], mip, GFXGLTextureInternalFormat[mFaceFormat], mipWidth, mipHeight, 0, GFXGLTextureFormat[mFaceFormat], GFXGLTextureType[mFaceFormat], dds->mSurfaces[i]->mMips[mip]); } } @@ -195,7 +188,7 @@ void GFXGLCubemap::initDynamic(U32 texSize, GFXFormat faceFormat, U32 mipLevels) mDynamicTexSize = texSize; mFaceFormat = faceFormat; const bool isCompressed = ImageUtil::isCompressedFormat(faceFormat); - mMipMapLevels = getMax( (U32)1, getMaxMipmaps( texSize, texSize, 1 ) ); + mMipMapLevels = ImageUtil::getMaxMipCount( texSize, texSize); glGenTextures(1, &mCubemap); PRESERVE_CUBEMAP_TEXTURE(); @@ -217,17 +210,17 @@ void GFXGLCubemap::initDynamic(U32 texSize, GFXFormat faceFormat, U32 mipLevels) { 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); + glCompressedTexImage2D(GFXGLFaceType[i], mip, GFXGLTextureInternalFormat[mFaceFormat], mipSize, mipSize, 0, mipDataSize, NULL); } } else { - glTexImage2D( faceList[i], 0, GFXGLTextureInternalFormat[faceFormat], texSize, texSize, + glTexImage2D( GFXGLFaceType[i], 0, GFXGLTextureInternalFormat[faceFormat], texSize, texSize, 0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], NULL); } } - if( !isCompressed ) + if( !isCompressed && !mipLevels) glGenerateMipmap(GL_TEXTURE_CUBE_MAP); mInitialized = true; } @@ -302,9 +295,9 @@ U8* GFXGLCubemap::getTextureData(U32 face, U32 mip) glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap); if (ImageUtil::isCompressedFormat(mFaceFormat)) - glGetCompressedTexImage(faceList[face], mip, data); + glGetCompressedTexImage(GFXGLFaceType[face], mip, data); else - glGetTexImage(faceList[face], mip, GFXGLTextureFormat[mFaceFormat], GFXGLTextureType[mFaceFormat], data); + glGetTexImage(GFXGLFaceType[face], mip, GFXGLTextureFormat[mFaceFormat], GFXGLTextureType[mFaceFormat], data); return data; } @@ -480,7 +473,7 @@ void GFXGLCubemapArray::copyTo(GFXCubemapArray *pDstCubemap) /*if (isCompressed) { const U32 mipDataSize = getCompressedSurfaceSize(mFormat, mSize, mSize, currentMip); - glCompressedTexImage2D(faceList[face], currentMip, GFXGLTextureInternalFormat[mFormat], mipSize, mipSize, 0, mipDataSize, pixelData); + glCompressedTexImage2D(GFXGLFaceType[face], currentMip, GFXGLTextureInternalFormat[mFormat], mipSize, mipSize, 0, mipDataSize, pixelData); } else {*/ //TODO figure out xyzOffsets diff --git a/Engine/source/gfx/gl/gfxGLDevice.cpp b/Engine/source/gfx/gl/gfxGLDevice.cpp index 9a11ac358..c90080b3f 100644 --- a/Engine/source/gfx/gl/gfxGLDevice.cpp +++ b/Engine/source/gfx/gl/gfxGLDevice.cpp @@ -471,32 +471,61 @@ void GFXGLDevice::copyResource(GFXTextureObject* pDst, GFXCubemap* pSrc, const U GFXGLTextureObject* gGLDst = static_cast(pDst); GFXGLCubemap* pGLSrc = static_cast(pSrc); - GFXFormat format = pGLSrc->getFormat(); - + const GFXFormat format = pGLSrc->getFormat(); const bool isCompressed = ImageUtil::isCompressedFormat(format); + const U32 mipLevels = pGLSrc->getMipMapLevels(); + const U32 texSize = pGLSrc->getSize(); + + //set up pbo if we don't have copyImage support + if (!GFXGL->mCapabilities.copyImage) + { + const GLuint pbo = gGLDst->getBuffer(); + glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo); + //allocate data + glBufferData(GL_PIXEL_PACK_BUFFER, texSize * texSize * GFXFormat_getByteSize(format), NULL, GL_STREAM_COPY); + } - 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 mipSize = texSize >> mip; + if (GFXGL->mCapabilities.copyImage) { - const U32 mipDataSize = getCompressedSurfaceSize(format, pGLSrc->getSize(), pGLSrc->getSize(), 0); - - glCompressedTexSubImage2D(gGLDst->getBinding(), mip, 0, 0, mipSize, mipSize, GFXGLTextureFormat[format], mipDataSize, pixelData); + glCopyImageSubData(pGLSrc->mCubemap, GL_TEXTURE_CUBE_MAP, mip, 0, 0, face, gGLDst->getHandle(), GL_TEXTURE_2D, mip, 0, 0, 0, mipSize, mipSize, 1); } 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); + //pbo id + const GLuint pbo = gGLDst->getBuffer(); - delete[] pixelData; + //copy source texture data to pbo + glBindTexture(GL_TEXTURE_CUBE_MAP, pGLSrc->mCubemap); + glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo); + + if (isCompressed) + glGetCompressedTexImage(GFXGLFaceType[face], mip, NULL); + else + glGetTexImage(GFXGLFaceType[face], mip, GFXGLTextureFormat[format], GFXGLTextureType[format], NULL); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + + //copy data from pbo to destination + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); + glBindTexture(gGLDst->getBinding(), gGLDst->getHandle()); + + if (isCompressed) + { + const U32 mipDataSize = getCompressedSurfaceSize(format, pGLSrc->getSize(), pGLSrc->getSize(), 0); + glCompressedTexSubImage2D(gGLDst->getBinding(), mip, 0, 0, mipSize, mipSize, GFXGLTextureFormat[format], mipDataSize, NULL); + } + else + { + glTexSubImage2D(gGLDst->getBinding(), mip, 0, 0, mipSize, mipSize, GFXGLTextureFormat[format], GFXGLTextureType[format], NULL); + } + + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glBindTexture(gGLDst->getBinding(), 0); + } } } diff --git a/Engine/source/gfx/gl/gfxGLEnumTranslate.cpp b/Engine/source/gfx/gl/gfxGLEnumTranslate.cpp index 0ab380db5..422f25bc1 100644 --- a/Engine/source/gfx/gl/gfxGLEnumTranslate.cpp +++ b/Engine/source/gfx/gl/gfxGLEnumTranslate.cpp @@ -38,6 +38,7 @@ GLint* GFXGLTextureSwizzle[GFXFormat_COUNT]; GLenum GFXGLBufferType[GFXBufferType_COUNT]; GLenum GFXGLCullMode[GFXCull_COUNT]; GLenum GFXGLFillMode[GFXFill_COUNT]; +GLenum GFXGLFaceType[6]; void GFXGLEnumTranslate::init() { @@ -273,4 +274,12 @@ void GFXGLEnumTranslate::init() GFXGLFillMode[GFXFillPoint] = GL_POINT; GFXGLFillMode[GFXFillWireframe] = GL_LINE; GFXGLFillMode[GFXFillSolid] = GL_FILL; + + //cubemap face type + GFXGLFaceType[0] = GL_TEXTURE_CUBE_MAP_POSITIVE_X; + GFXGLFaceType[1] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; + GFXGLFaceType[2] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; + GFXGLFaceType[3] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; + GFXGLFaceType[4] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; + GFXGLFaceType[5] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; } diff --git a/Engine/source/gfx/gl/gfxGLEnumTranslate.h b/Engine/source/gfx/gl/gfxGLEnumTranslate.h index 000f64093..02a6b87b6 100644 --- a/Engine/source/gfx/gl/gfxGLEnumTranslate.h +++ b/Engine/source/gfx/gl/gfxGLEnumTranslate.h @@ -50,4 +50,6 @@ extern GLenum GFXGLCullMode[GFXCull_COUNT]; extern GLenum GFXGLFillMode[GFXFill_COUNT]; +extern GLenum GFXGLFaceType[6]; + #endif diff --git a/Engine/source/gfx/gl/gfxGLTextureObject.cpp b/Engine/source/gfx/gl/gfxGLTextureObject.cpp index 4dac801d3..fd686854a 100644 --- a/Engine/source/gfx/gl/gfxGLTextureObject.cpp +++ b/Engine/source/gfx/gl/gfxGLTextureObject.cpp @@ -177,7 +177,6 @@ bool GFXGLTextureObject::copyToBmp(GBitmap * bmp) U32 mipLevels = getMipLevels(); - if (mipLevels < 1) mipLevels = 1;//ensure we loop at least the once for (U32 mip = 0; mip < mipLevels; mip++) { U32 srcPixelCount = bmp->getSurfaceSize(mip)/ srcBytesPerPixel; @@ -190,7 +189,7 @@ bool GFXGLTextureObject::copyToBmp(GBitmap * bmp) PROFILE_START(GFXGLTextureObject_copyToBmp_pixCopy); if (mFormat == GFXFormatR16G16B16A16F) { - dMemcpy(dest, orig, srcPixelCount * sizeof(U16) * 4); + dMemcpy(dest, orig, srcPixelCount * srcBytesPerPixel); } else { @@ -207,6 +206,7 @@ bool GFXGLTextureObject::copyToBmp(GBitmap * bmp) } } } + glBindTexture(mBinding, NULL); PROFILE_END(); return true;