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