OpenGL: Mipmaps for GFXGLCubemap.

This commit is contained in:
LuisAntonRebollo 2014-12-26 20:58:22 +01:00
parent ca04726ad6
commit 9150c7f5ab
3 changed files with 45 additions and 19 deletions

View file

@ -56,9 +56,12 @@ GFXGLCubemap::~GFXGLCubemap()
void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces) void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces)
{ {
AssertFatal( faces, "");
AssertFatal( faces[0]->mMipLevels > 0, "");
PRESERVE_CUBEMAP_TEXTURE(); PRESERVE_CUBEMAP_TEXTURE();
glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap); 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_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_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_S, GL_CLAMP_TO_EDGE);
@ -68,10 +71,11 @@ void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces)
U32 reqWidth = faces[0]->getWidth(); U32 reqWidth = faces[0]->getWidth();
U32 reqHeight = faces[0]->getHeight(); U32 reqHeight = faces[0]->getHeight();
GFXFormat regFaceFormat = faces[0]->getFormat(); GFXFormat regFaceFormat = faces[0]->getFormat();
const bool isCompressed = isCompressedFormat(regFaceFormat);
mWidth = reqWidth; mWidth = reqWidth;
mHeight = reqHeight; mHeight = reqHeight;
mFaceFormat = regFaceFormat; 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!"); AssertFatal(reqWidth == reqHeight, "GFXGLCubemap::fillCubeTextures - Width and height must be equal!");
for(U32 i = 0; i < 6; i++) for(U32 i = 0; i < 6; i++)
@ -83,14 +87,19 @@ void GFXGLCubemap::fillCubeTextures(GFXTexHandle* faces)
mTextures[i] = faces[i]; mTextures[i] = faces[i];
GFXFormat faceFormat = faces[i]->getFormat(); GFXFormat faceFormat = faces[i]->getFormat();
GFXGLTextureObject* glTex = static_cast<GFXGLTextureObject*>(faces[i].getPointer()); GFXGLTextureObject* glTex = static_cast<GFXGLTextureObject*>(faces[i].getPointer());
U8* buf = glTex->getTextureData(); const U32 mipCount = isCompressed ? mMipLevels : 1;
glTexImage2D(faceList[i], 0, GFXGLTextureInternalFormat[faceFormat], faces[i]->getWidth(), faces[i]->getHeight(), for( U32 mip = 0; mip < mipCount; ++mip )
0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], buf); {
delete[] buf; 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) 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 // TODO: The DDS can skip surfaces, but i'm unsure what i should
// do here when creating the cubemap. Ignore it for now. // do here when creating the cubemap. Ignore it for now.
continue; continue;
} }
// Now loop thru the mip levels! // Now loop thru the mip levels!
for (U32 j = 0; j < mMipLevels; j++) for (U32 j = 0; j < mMipLevels; j++)
glCompressedTexImage2D(faceList[i], j, GFXGLTextureInternalFormat[mFaceFormat], mWidth, mHeight, 0, dds->getSurfaceSize(j), dds->mSurfaces[i]->mMips[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; mDynamicTexSize = texSize;
mFaceFormat = faceFormat; mFaceFormat = faceFormat;
const bool isCompressed = isCompressedFormat(faceFormat);
mMipLevels = getMax( (U32)1, getMaxMipmaps( texSize, texSize, 1 ) );
glGenTextures(1, &mCubemap); glGenTextures(1, &mCubemap);
PRESERVE_CUBEMAP_TEXTURE(); PRESERVE_CUBEMAP_TEXTURE();
glBindTexture(GL_TEXTURE_CUBE_MAP, mCubemap); 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_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_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_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); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
mWidth = texSize; mWidth = texSize;
mHeight = texSize; mHeight = texSize;
mMipLevels = 1;
for(U32 i = 0; i < 6; i++) for(U32 i = 0; i < 6; i++)
{ {
glTexImage2D( faceList[i], 0, GFXGLTextureInternalFormat[faceFormat], texSize, texSize, const U32 mipCount = isCompressed ? mMipLevels : 1;
0, GFXGLTextureFormat[faceFormat], GFXGLTextureType[faceFormat], NULL); 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() void GFXGLCubemap::zombify()

View file

@ -243,12 +243,19 @@ void GFXGLTextureObject::bind(U32 textureUnit)
mSampler = ssd; 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); PRESERVE_TEXTURE(mBinding);
glBindTexture(mBinding, mHandle); glBindTexture(mBinding, mHandle);
glGetTexImage(mBinding, 0, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], data); glGetTexImage(mBinding, mip, GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], data);
return data; return data;
} }

View file

@ -51,7 +51,7 @@ public:
/// @return An array containing the texture data /// @return An array containing the texture data
/// @note You are responsible for deleting the returned data! (Use delete[]) /// @note You are responsible for deleting the returned data! (Use delete[])
U8* getTextureData(); U8* getTextureData( U32 mip = 0);
virtual F32 getMaxUCoord() const; virtual F32 getMaxUCoord() const;
virtual F32 getMaxVCoord() const; virtual F32 getMaxVCoord() const;