Commit 947a1c92 authored by nadro's avatar nadro

- Prepared COGLCoreTexture to support Cubemaps.

- Fixed issue related to sphere mapping on the whole scene (visible eg. in Tech Demo). Thanks AReichl for report this issue.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@5185 dfc29bdd-3216-0410-991c-e03cc46cb475
parent a9bb0ccd
......@@ -153,12 +153,14 @@ public:
//! Regenerates the mip map levels of the texture.
/** Required after modifying the texture, usually after calling unlock().
\param mipmapData Optional parameter to pass in image data which will be
\param data Optional parameter to pass in image data which will be
used instead of the previously stored or automatically generated mipmap
data. The data has to be a continuous pixel data for all mipmaps until
1x1 pixel. Each mipmap has to be half the width and height of the previous
level. At least one pixel will be always kept.*/
virtual void regenerateMipMapLevels(void* mipmapData = 0) = 0;
level. At least one pixel will be always kept.
\param layer It informs a texture about layer which needs
mipmaps regeneration. */
virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) = 0;
//! Get original size of the texture.
/** The texture is usually scaled, if it was created with an unoptimal
......
......@@ -591,18 +591,15 @@ void CD3D9Texture::copy32BitMipMap(char* src, char* tgt,
}
}
//! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture
void CD3D9Texture::regenerateMipMapLevels(void* mipmapData)
void CD3D9Texture::regenerateMipMapLevels(void* data, u32 layer)
{
if (!HasMipMaps)
return;
if (IsCompressed && !mipmapData)
if (IsCompressed && !data)
return;
if (mipmapData)
if (data)
{
u32 compressedDataSize = 0;
core::dimension2du size = Size;
......@@ -641,13 +638,13 @@ void CD3D9Texture::regenerateMipMapLevels(void* mipmapData)
else if (ColorFormat == ECF_DXT2 || ColorFormat == ECF_DXT3 || ColorFormat == ECF_DXT4 || ColorFormat == ECF_DXT5)
compressedDataSize = ((size.Width + 3) / 4) * ((size.Height + 3) / 4) * 16;
memcpy(miplr.pBits, mipmapData, compressedDataSize);
mipmapData = static_cast<u8*>(mipmapData)+compressedDataSize;
memcpy(miplr.pBits, data, compressedDataSize);
data = static_cast<u8*>(data)+compressedDataSize;
}
else
{
memcpy(miplr.pBits, mipmapData, size.getArea()*getPitch() / Size.Width);
mipmapData = (u8*)mipmapData + size.getArea()*getPitch() / Size.Width;
memcpy(miplr.pBits, data, size.getArea()*getPitch() / Size.Width);
data = (u8*)data + size.getArea()*getPitch() / Size.Width;
}
// unlock
......
......@@ -47,9 +47,7 @@ public:
//! unlock function
virtual void unlock() _IRR_OVERRIDE_;
//! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture
virtual void regenerateMipMapLevels(void* mipmapData = 0) _IRR_OVERRIDE_;
virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_;
//! returns the DIRECT3D9 Texture
IDirect3DTexture9* getDX9Texture() const;
......
......@@ -760,7 +760,7 @@ namespace video
virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0) _IRR_OVERRIDE_ { return 0; }
virtual void unlock()_IRR_OVERRIDE_ {}
virtual void regenerateMipMapLevels(void* mipmapData=0) _IRR_OVERRIDE_ {}
virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_ {}
};
core::array<SSurface> Textures;
......
......@@ -75,12 +75,25 @@ class COGLCoreCacheHandler
{
texture->grab();
const TOGLTexture* curTexture = static_cast<const TOGLTexture*>(texture);
const GLenum curTextureType = curTexture->getOpenGLTextureType();
const GLenum prevTextureType = (prevTexture) ? prevTexture->getOpenGLTextureType() : curTextureType;
if (curTextureType != prevTextureType)
{
glBindTexture(prevTextureType, 0);
#if defined(IRR_OPENGL_VERSION) && IRR_OPENGL_VERSION < 20
if (!prevTexture)
glEnable(GL_TEXTURE_2D);
glDisable(prevTextureType);
glEnable(curTextureType);
#endif
}
#if defined(IRR_OPENGL_VERSION) && IRR_OPENGL_VERSION < 20
else if (!prevTexture)
glEnable(curTextureType);
#endif
glBindTexture(GL_TEXTURE_2D, static_cast<const TOGLTexture*>(texture)->getOpenGLTextureName());
glBindTexture(curTextureType, static_cast<const TOGLTexture*>(texture)->getOpenGLTextureName());
}
else
{
......@@ -90,13 +103,14 @@ class COGLCoreCacheHandler
}
}
if (!texture)
if (!texture && prevTexture)
{
glBindTexture(GL_TEXTURE_2D, 0);
const GLenum prevTextureType = prevTexture->getOpenGLTextureType();
glBindTexture(prevTextureType, 0);
#if defined(IRR_OPENGL_VERSION) && IRR_OPENGL_VERSION < 20
if (prevTexture)
glDisable(GL_TEXTURE_2D);
glDisable(prevTextureType);
#endif
}
......
......@@ -84,8 +84,8 @@ public:
const COGLCoreTexture* prevTexture = Driver->getCacheHandler()->getTextureCache().get(0);
Driver->getCacheHandler()->getTextureCache().set(0, this);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(TextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(TextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if (HasMipMaps && AutoGenerateMipMaps)
{
......@@ -99,14 +99,16 @@ public:
#if defined(IRR_OPENGL_VERSION) && IRR_OPENGL_VERSION < 20
if (HasMipMaps)
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, (AutoGenerateMipMaps) ? GL_TRUE : GL_FALSE);
glTexParameteri(TextureType, GL_GENERATE_MIPMAP, (AutoGenerateMipMaps) ? GL_TRUE : GL_FALSE);
#endif
uploadTexture(true, 0, (*tmpImage)[0]->getData());
for (u32 i = 0; i < (*tmpImage).size(); ++i)
uploadTexture(true, i, 0, (*tmpImage)[i]->getData());
Driver->getCacheHandler()->getTextureCache().set(0, prevTexture);
regenerateMipMapLevels((*tmpImage)[0]->getMipMapsData());
for (u32 i = 0; i < (*tmpImage).size(); ++i)
regenerateMipMapLevels((*tmpImage)[i]->getMipMapsData(), i);
if (!KeepImage)
{
......@@ -271,7 +273,7 @@ public:
const COGLCoreTexture* prevTexture = Driver->getCacheHandler()->getTextureCache().get(0);
Driver->getCacheHandler()->getTextureCache().set(0, this);
uploadTexture(false, LockLevel, LockImage->getData());
uploadTexture(false, 0, LockLevel, LockImage->getData());
Driver->getCacheHandler()->getTextureCache().set(0, prevTexture);
......@@ -286,19 +288,19 @@ public:
LockLevel = 0;
}
virtual void regenerateMipMapLevels(void* mipMapsData = 0) _IRR_OVERRIDE_
virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_
{
if (!HasMipMaps || (!mipMapsData && !AutoGenerateMipMaps) || (Size.Width <= 1 && Size.Height <= 1))
if (!HasMipMaps || (!data && !AutoGenerateMipMaps) || (Size.Width <= 1 && Size.Height <= 1))
return;
const COGLCoreTexture* prevTexture = Driver->getCacheHandler()->getTextureCache().get(0);
Driver->getCacheHandler()->getTextureCache().set(0, this);
if (mipMapsData)
if (data)
{
u32 width = Size.Width;
u32 height = Size.Height;
u8* data = static_cast<u8*>(mipMapsData);
u32 width = Size.Width >> layer;
u32 height = Size.Height >> layer;
u8* tmpData = static_cast<u8*>(data);
u32 dataSize = 0;
u32 level = 0;
......@@ -313,16 +315,16 @@ public:
dataSize = IImage::getDataSizeFromFormat(ColorFormat, width, height);
++level;
uploadTexture(true, level, data);
uploadTexture(true, layer, level, tmpData);
data += dataSize;
tmpData += dataSize;
}
while (width != 1 || height != 1);
}
else
{
#if defined(IRR_OPENGL_VERSION) && IRR_OPENGL_VERSION >= 20
Driver->irrGlGenerateMipmap(GL_TEXTURE_2D);
Driver->irrGlGenerateMipmap(TextureType);
#endif
}
......@@ -427,7 +429,7 @@ protected:
Size = Size.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT));
}
void uploadTexture(bool initTexture, u32 level, void* data)
void uploadTexture(bool initTexture, u32 layer, u32 level, void* data)
{
if (!data)
return;
......@@ -435,6 +437,15 @@ protected:
u32 width = Size.Width >> level;
u32 height = Size.Height >> level;
const GLenum cubeTextureType[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
};
GLenum tmpTextureType = (TextureType == GL_TEXTURE_CUBE_MAP) ? cubeTextureType[(layer < 6) ? layer : 0] : TextureType;
if (!IImage::isCompressedFormat(ColorFormat))
{
CImage* tmpImage = 0;
......@@ -450,10 +461,19 @@ protected:
Converter(data, tmpImageSize.getArea(), tmpData);
}
if (initTexture)
glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, width, height, 0, PixelFormat, PixelType, tmpData);
else
glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, width, height, PixelFormat, PixelType, tmpData);
switch (TextureType)
{
case GL_TEXTURE_2D:
case GL_TEXTURE_CUBE_MAP:
if (initTexture)
glTexImage2D(tmpTextureType, level, InternalFormat, width, height, 0, PixelFormat, PixelType, tmpData);
else
glTexSubImage2D(tmpTextureType, level, 0, 0, width, height, PixelFormat, PixelType, tmpData);
break;
default:
break;
}
delete tmpImage;
}
......@@ -461,10 +481,19 @@ protected:
{
u32 dataSize = IImage::getDataSizeFromFormat(ColorFormat, Size.Width, height);
if (initTexture)
Driver->irrGlCompressedTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, width, height, 0, dataSize, data);
else
Driver->irrGlCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, width, height, PixelFormat, dataSize, data);
switch (TextureType)
{
case GL_TEXTURE_2D:
case GL_TEXTURE_CUBE_MAP:
if (initTexture)
Driver->irrGlCompressedTexImage2D(tmpTextureType, level, InternalFormat, width, height, 0, dataSize, data);
else
Driver->irrGlCompressedTexSubImage2D(tmpTextureType, level, 0, 0, width, height, PixelFormat, dataSize, data);
break;
default:
break;
}
}
}
......
......@@ -2579,6 +2579,8 @@ void COpenGLDriver::setMaterial(const SMaterial& material)
CacheHandler->getTextureCache().set(i, material.getTexture(i));
setTransform((E_TRANSFORMATION_STATE)(ETS_TEXTURE_0 + i), material.getTextureMatrix(i));
}
CacheHandler->setActiveTexture(GL_TEXTURE0_ARB);
}
......
......@@ -109,10 +109,7 @@ CImage* CSoftwareTexture::getTexture()
return Texture;
}
//! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture
void CSoftwareTexture::regenerateMipMapLevels(void* mipmapData)
void CSoftwareTexture::regenerateMipMapLevels(void* data, u32 layer)
{
// our software textures don't have mip maps
}
......
......@@ -41,9 +41,7 @@ public:
//! returns texture surface
virtual CImage* getTexture();
//! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture
virtual void regenerateMipMapLevels(void* mipmapData=0) _IRR_OVERRIDE_;
virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_;
private:
CImage* Image;
......
......@@ -102,7 +102,7 @@ CSoftwareTexture2::~CSoftwareTexture2()
//! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture
void CSoftwareTexture2::regenerateMipMapLevels(void* mipmapData)
void CSoftwareTexture2::regenerateMipMapLevels(void* data, u32 layer)
{
if (!hasMipMaps())
return;
......@@ -127,11 +127,11 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* mipmapData)
origSize.Width = core::s32_max(1, origSize.Width >> 1);
origSize.Height = core::s32_max(1, origSize.Height >> 1);
if (mipmapData)
if (data)
{
if (OriginalFormat != BURNINGSHADER_COLOR_FORMAT)
{
IImage* tmpImage = new CImage(OriginalFormat, origSize, mipmapData, true, false);
IImage* tmpImage = new CImage(OriginalFormat, origSize, data, true, false);
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
if (origSize==newSize)
tmpImage->copyTo(MipMap[i]);
......@@ -142,16 +142,16 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* mipmapData)
else
{
if (origSize==newSize)
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize, mipmapData, false);
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize, data, false);
else
{
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
IImage* tmpImage = new CImage(BURNINGSHADER_COLOR_FORMAT, origSize, mipmapData, true, false);
IImage* tmpImage = new CImage(BURNINGSHADER_COLOR_FORMAT, origSize, data, true, false);
tmpImage->copyToScalingBoxFilter(MipMap[i]);
tmpImage->drop();
}
}
mipmapData = (u8*)mipmapData+origSize.getArea()*IImage::getBitsPerPixelFromFormat(OriginalFormat)/8;
data = (u8*)data +origSize.getArea()*IImage::getBitsPerPixelFromFormat(OriginalFormat)/8;
}
else
{
......
......@@ -74,9 +74,7 @@ public:
return MipMap[MipMapLOD];
}
//! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture
virtual void regenerateMipMapLevels(void* mipmapData=0) _IRR_OVERRIDE_;
virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_;
private:
f32 OrigImageDataSizeInPixels;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment