- Added support for texture cube in OpenGL driver.
- Fixed issue related to regenerateMipMapLevels in OpenGL driver. - Added missing files to VS2012 project. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@4610 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
2d4193888e
commit
5dca9a0a06
|
@ -133,6 +133,9 @@ namespace video
|
|||
//! Support for ETC2 compressed textures.
|
||||
EVDF_TEXTURE_COMPRESSED_ETC2,
|
||||
|
||||
//! Support for cube map textures.
|
||||
EVDF_TEXTURE_CUBE_MAP,
|
||||
|
||||
//! Only used for counting the elements of this enum
|
||||
EVDF_COUNT
|
||||
};
|
||||
|
|
|
@ -86,6 +86,38 @@ enum E_TEXTURE_LOCK_MODE
|
|||
ETLM_WRITE_ONLY
|
||||
};
|
||||
|
||||
//! Enumeration describing the type of ITexture.
|
||||
enum E_TEXTURE_TYPE
|
||||
{
|
||||
//! 2D texture.
|
||||
ETT_2D,
|
||||
|
||||
//! Cube texture.
|
||||
ETT_CUBE
|
||||
};
|
||||
|
||||
//! Enumeration describing the type of cube texture surfaces.
|
||||
enum E_TEXTURE_CUBE_SURFACE
|
||||
{
|
||||
//! Positive x-face of the cubemap
|
||||
ETCS_POSX = 0,
|
||||
|
||||
//! Negative x-face of the cubemap
|
||||
ETCS_NEGX = 1,
|
||||
|
||||
//! Positive y-face of the cubemap
|
||||
ETCS_POSY = 2,
|
||||
|
||||
//! Negative y-face of the cubemap
|
||||
ETCS_NEGY = 3,
|
||||
|
||||
//! Positive z-face of the cubemap
|
||||
ETCS_POSZ = 4,
|
||||
|
||||
//! Negative z-face of the cubemap
|
||||
ETCS_NEGZ = 5
|
||||
};
|
||||
|
||||
//! Interface of a Video Driver dependent Texture.
|
||||
/** An ITexture is created by an IVideoDriver by using IVideoDriver::addTexture
|
||||
or IVideoDriver::getTexture. After that, the texture may only be used by this
|
||||
|
@ -100,7 +132,7 @@ class ITexture : public virtual IReferenceCounted
|
|||
public:
|
||||
|
||||
//! constructor
|
||||
ITexture(const io::path& name) : NamedPath(name)
|
||||
ITexture(const io::path& name, E_TEXTURE_TYPE type = ETT_2D) : NamedPath(name), Type(type)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -189,6 +221,9 @@ public:
|
|||
|
||||
//! Get name of texture (in most cases this is the filename)
|
||||
const io::SNamedPath& getName() const { return NamedPath; }
|
||||
|
||||
//! Returns the type of texture
|
||||
E_TEXTURE_TYPE getType() const { return Type; }
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -209,6 +244,8 @@ protected:
|
|||
}
|
||||
|
||||
io::SNamedPath NamedPath;
|
||||
|
||||
E_TEXTURE_TYPE Type;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -427,6 +427,21 @@ namespace video
|
|||
should not be dropped. See IReferenceCounted::drop() for more
|
||||
information. */
|
||||
virtual ITexture* addTexture(const io::path& name, IImage* image, void* mipmapData=0) = 0;
|
||||
|
||||
//! Creates a cube texture from loaded IImages.
|
||||
/** \param name A name for the texture. Later calls of
|
||||
getTexture() with this name will return this texture
|
||||
\param posXImage Image (positive X) the texture is created from.
|
||||
\param negXImage Image (negative X) the texture is created from.
|
||||
\param posYImage Image (positive Y) the texture is created from.
|
||||
\param negYImage Image (negative Y) the texture is created from.
|
||||
\param posZImage Image (positive Z) the texture is created from.
|
||||
\param negZImage Image (negative Z) the texture is created from.
|
||||
\return Pointer to the newly created texture. This pointer
|
||||
should not be dropped. See IReferenceCounted::drop() for more
|
||||
information. */
|
||||
virtual ITexture* addTextureCube(const io::path& name, IImage* posXImage, IImage* negXImage,
|
||||
IImage* posYImage, IImage* negYImage, IImage* posZImage, IImage* negZImage) = 0;
|
||||
|
||||
//! Adds a new render target texture to the texture cache.
|
||||
/** \param size Size of the texture, in pixels. Width and
|
||||
|
|
|
@ -562,22 +562,6 @@ video::ITexture* CNullDriver::findTexture(const io::path& filename)
|
|||
}
|
||||
|
||||
|
||||
//! Creates a texture from a loaded IImage.
|
||||
ITexture* CNullDriver::addTexture(const io::path& name, IImage* image, void* mipmapData)
|
||||
{
|
||||
if ( 0 == name.size() || !image)
|
||||
return 0;
|
||||
|
||||
ITexture* t = createDeviceDependentTexture(image, name, mipmapData);
|
||||
if (t)
|
||||
{
|
||||
addTexture(t);
|
||||
t->drop();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
//! creates a Texture
|
||||
ITexture* CNullDriver::addTexture(const core::dimension2d<u32>& size,
|
||||
const io::path& name, ECOLOR_FORMAT format)
|
||||
|
@ -605,6 +589,37 @@ ITexture* CNullDriver::addTexture(const core::dimension2d<u32>& size,
|
|||
}
|
||||
|
||||
|
||||
//! Creates a texture from a loaded IImage.
|
||||
ITexture* CNullDriver::addTexture(const io::path& name, IImage* image, void* mipmapData)
|
||||
{
|
||||
if ( 0 == name.size() || !image)
|
||||
return 0;
|
||||
|
||||
ITexture* t = createDeviceDependentTexture(image, name, mipmapData);
|
||||
if (t)
|
||||
{
|
||||
addTexture(t);
|
||||
t->drop();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
//! Creates a cube texture from loaded IImages.
|
||||
ITexture* CNullDriver::addTextureCube(const io::path& name, IImage* posXImage, IImage* negXImage,
|
||||
IImage* posYImage, IImage* negYImage, IImage* posZImage, IImage* negZImage)
|
||||
{
|
||||
if ( 0 == name.size() || !posXImage || !negXImage || !posYImage || !negYImage || !posZImage || !negZImage)
|
||||
return 0;
|
||||
|
||||
ITexture* t = createDeviceDependentTextureCube(name, posXImage, negXImage, posYImage, negYImage, posZImage, negZImage);
|
||||
if (t)
|
||||
{
|
||||
addTexture(t);
|
||||
t->drop();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
//! returns a device dependent texture from a software surface (IImage)
|
||||
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
|
||||
|
@ -614,6 +629,14 @@ ITexture* CNullDriver::createDeviceDependentTexture(IImage* surface, const io::p
|
|||
}
|
||||
|
||||
|
||||
//! returns a device dependent texture from a software surface (IImage)
|
||||
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
|
||||
ITexture* CNullDriver::createDeviceDependentTextureCube(const io::path& name, IImage* posXImage, IImage* negXImage,
|
||||
IImage* posYImage, IImage* negYImage, IImage* posZImage, IImage* negZImage)
|
||||
{
|
||||
return new SDummyTexture(name);
|
||||
}
|
||||
|
||||
//! set or reset special render targets
|
||||
bool CNullDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
|
||||
bool clearZBuffer, SColor color)
|
||||
|
@ -2444,6 +2467,32 @@ bool CNullDriver::checkColorFormat(ECOLOR_FORMAT format, const core::dimension2d
|
|||
}
|
||||
|
||||
|
||||
// Check support for compression texture format.
|
||||
bool CNullDriver::checkTextureCube(IImage* posXImage, IImage* negXImage, IImage* posYImage, IImage* negYImage,
|
||||
IImage* posZImage, IImage* negZImage) const
|
||||
{
|
||||
if (!queryFeature(EVDF_TEXTURE_CUBE_MAP))
|
||||
return false;
|
||||
|
||||
IImage* image[6] = {
|
||||
posXImage,
|
||||
negXImage,
|
||||
posYImage,
|
||||
negYImage,
|
||||
posZImage,
|
||||
negZImage
|
||||
};
|
||||
|
||||
for (u32 i = 1; i < 6; ++i)
|
||||
{
|
||||
if (image[0]->getDimension() != image[i]->getDimension() || image[0]->getColorFormat() != image[i]->getColorFormat())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//! creates a video driver
|
||||
IVideoDriver* createNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize)
|
||||
{
|
||||
|
|
|
@ -100,6 +100,13 @@ namespace video
|
|||
//! creates a Texture
|
||||
virtual ITexture* addTexture(const core::dimension2d<u32>& size, const io::path& name, ECOLOR_FORMAT format = ECF_A8R8G8B8);
|
||||
|
||||
//! Creates a texture from a loaded IImage.
|
||||
virtual ITexture* addTexture(const io::path& name, IImage* image, void* mipmapData=0);
|
||||
|
||||
//! Creates a cube texture from loaded IImages.
|
||||
virtual ITexture* addTextureCube(const io::path& name, IImage* posXImage, IImage* negXImage,
|
||||
IImage* posYImage, IImage* negYImage, IImage* posZImage, IImage* negZImage);
|
||||
|
||||
//! sets a render target
|
||||
virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
|
||||
bool clearZBuffer, SColor color);
|
||||
|
@ -667,17 +674,19 @@ namespace video
|
|||
void deleteAllTextures();
|
||||
|
||||
//! opens the file and loads it into the surface
|
||||
video::ITexture* loadTextureFromFile(io::IReadFile* file, const io::path& hashName = "");
|
||||
ITexture* loadTextureFromFile(io::IReadFile* file, const io::path& hashName = "");
|
||||
|
||||
//! adds a surface, not loaded or created by the Irrlicht Engine
|
||||
void addTexture(video::ITexture* surface);
|
||||
|
||||
//! Creates a texture from a loaded IImage.
|
||||
virtual ITexture* addTexture(const io::path& name, IImage* image, void* mipmapData=0);
|
||||
void addTexture(ITexture* surface);
|
||||
|
||||
//! returns a device dependent texture from a software surface (IImage)
|
||||
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
|
||||
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0);
|
||||
virtual ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0);
|
||||
|
||||
//! returns a device dependent texture from a software surface (IImage)
|
||||
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
|
||||
virtual ITexture* createDeviceDependentTextureCube(const io::path& name, IImage* posXImage, IImage* negXImage,
|
||||
IImage* posYImage, IImage* negYImage, IImage* posZImage, IImage* negZImage);
|
||||
|
||||
//! checks triangle count and print warning if wrong
|
||||
bool checkPrimitiveCount(u32 prmcnt) const;
|
||||
|
@ -694,6 +703,10 @@ namespace video
|
|||
// Check support for compression texture format.
|
||||
bool checkColorFormat(ECOLOR_FORMAT format, const core::dimension2d<u32>& textureSize) const;
|
||||
|
||||
// Check support for compression texture format.
|
||||
bool checkTextureCube(IImage* posXImage, IImage* negXImage, IImage* posYImage, IImage* negYImage,
|
||||
IImage* posZImage, IImage* negZImage) const;
|
||||
|
||||
//! normal map lookup 32 bit version
|
||||
inline f32 nml32(int x, int y, int pitch, int height, s32 *p) const
|
||||
{
|
||||
|
|
|
@ -2188,7 +2188,7 @@ bool COpenGLDriver::disableTextures(u32 fromStage)
|
|||
for (u32 i=fromStage; i<MaxSupportedTextures; ++i)
|
||||
{
|
||||
result &= setActiveTexture(i, 0);
|
||||
BridgeCalls->setTexture(i, true);
|
||||
BridgeCalls->setTexture(i, GL_TEXTURE_2D, true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -2227,7 +2227,7 @@ inline void COpenGLDriver::getGLTextureMatrix(GLfloat *o, const core::matrix4& m
|
|||
|
||||
|
||||
//! returns a device dependent texture from a software surface (IImage)
|
||||
video::ITexture* COpenGLDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData)
|
||||
ITexture* COpenGLDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData)
|
||||
{
|
||||
COpenGLTexture* texture = 0;
|
||||
|
||||
|
@ -2238,6 +2238,23 @@ video::ITexture* COpenGLDriver::createDeviceDependentTexture(IImage* surface, co
|
|||
}
|
||||
|
||||
|
||||
//! returns a device dependent texture from a software surface (IImage)
|
||||
ITexture* COpenGLDriver::createDeviceDependentTextureCube(const io::path& name, IImage* posXImage, IImage* negXImage,
|
||||
IImage* posYImage, IImage* negYImage, IImage* posZImage, IImage* negZImage)
|
||||
{
|
||||
COpenGLTexture* texture = 0;
|
||||
|
||||
if (posXImage && negXImage && posYImage && negYImage && posZImage && negZImage &&
|
||||
checkTextureCube(posXImage, negXImage, posYImage, negYImage, posZImage, negZImage) &&
|
||||
checkColorFormat(posXImage->getColorFormat(), posXImage->getDimension()))
|
||||
{
|
||||
texture = new COpenGLTexture(name, posXImage, negXImage, posYImage, negYImage, posZImage, negZImage, this);
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
||||
//! Sets a material. All 3d drawing functions draw geometry now using this material.
|
||||
void COpenGLDriver::setMaterial(const SMaterial& material)
|
||||
{
|
||||
|
@ -2864,6 +2881,7 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
|
|||
for (s32 i = MaxTextureUnits-1; i>= 0; --i)
|
||||
{
|
||||
const COpenGLTexture* tmpTexture = static_cast<const COpenGLTexture*>(CurrentTexture[i]);
|
||||
GLenum tmpTextureType = (tmpTexture) ? tmpTexture->getOpenGLTextureType() : GL_TEXTURE_2D;
|
||||
|
||||
if(fixedPipeline)
|
||||
{
|
||||
|
@ -2872,13 +2890,13 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
|
|||
|
||||
if (!CurrentTexture[i])
|
||||
{
|
||||
BridgeCalls->setTexture(i, fixedPipeline);
|
||||
BridgeCalls->setTexture(i, tmpTextureType, fixedPipeline);
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
BridgeCalls->setTexture(i, fixedPipeline);
|
||||
BridgeCalls->setTexture(i, tmpTextureType, fixedPipeline);
|
||||
|
||||
setTransform ((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + i), material.getTextureMatrix(i));
|
||||
}
|
||||
|
@ -2887,7 +2905,7 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
|
|||
{
|
||||
if (CurrentTexture[i])
|
||||
{
|
||||
BridgeCalls->setTexture(i, fixedPipeline);
|
||||
BridgeCalls->setTexture(i, tmpTextureType, fixedPipeline);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
@ -2904,10 +2922,10 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
|
|||
if (material.TextureLayer[i].LODBias)
|
||||
{
|
||||
const float tmp = core::clamp(material.TextureLayer[i].LODBias * 0.125f, -MaxTextureLODBias, MaxTextureLODBias);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, tmp);
|
||||
glTexParameterf(tmpTextureType, GL_TEXTURE_LOD_BIAS, tmp);
|
||||
}
|
||||
else
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, 0.f);
|
||||
glTexParameterf(tmpTextureType, GL_TEXTURE_LOD_BIAS, 0.f);
|
||||
|
||||
tmpTexture->getStatesCache().LODBias = material.TextureLayer[i].LODBias;
|
||||
}
|
||||
|
@ -2938,7 +2956,7 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
|
|||
if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter ||
|
||||
material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||
glTexParameteri(tmpTextureType, GL_TEXTURE_MAG_FILTER,
|
||||
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST);
|
||||
|
||||
tmpTexture->getStatesCache().BilinearFilter = material.TextureLayer[i].BilinearFilter;
|
||||
|
@ -2950,7 +2968,7 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
|
|||
if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter ||
|
||||
material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter || !tmpTexture->getStatesCache().MipMapStatus)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
glTexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER,
|
||||
material.TextureLayer[i].TrilinearFilter ? GL_LINEAR_MIPMAP_LINEAR :
|
||||
material.TextureLayer[i].BilinearFilter ? GL_LINEAR_MIPMAP_NEAREST :
|
||||
GL_NEAREST_MIPMAP_NEAREST);
|
||||
|
@ -2965,7 +2983,7 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
|
|||
if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter ||
|
||||
material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter || tmpTexture->getStatesCache().MipMapStatus)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
glTexParameteri(tmpTextureType, GL_TEXTURE_MIN_FILTER,
|
||||
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST);
|
||||
|
||||
tmpTexture->getStatesCache().BilinearFilter = material.TextureLayer[i].BilinearFilter;
|
||||
|
@ -2978,7 +2996,7 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
|
|||
if (FeatureAvailable[IRR_EXT_texture_filter_anisotropic] &&
|
||||
(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].AnisotropicFilter != tmpTexture->getStatesCache().AnisotropicFilter))
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
||||
glTexParameteri(tmpTextureType, GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
||||
material.TextureLayer[i].AnisotropicFilter>1 ? core::min_(MaxAnisotropy, material.TextureLayer[i].AnisotropicFilter) : 1);
|
||||
|
||||
tmpTexture->getStatesCache().AnisotropicFilter = material.TextureLayer[i].AnisotropicFilter;
|
||||
|
@ -2987,13 +3005,13 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
|
|||
|
||||
if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].TextureWrapU != tmpTexture->getStatesCache().WrapU)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, getTextureWrapMode(material.TextureLayer[i].TextureWrapU));
|
||||
glTexParameteri(tmpTextureType, GL_TEXTURE_WRAP_S, getTextureWrapMode(material.TextureLayer[i].TextureWrapU));
|
||||
tmpTexture->getStatesCache().WrapU = material.TextureLayer[i].TextureWrapU;
|
||||
}
|
||||
|
||||
if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].TextureWrapV != tmpTexture->getStatesCache().WrapV)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, getTextureWrapMode(material.TextureLayer[i].TextureWrapV));
|
||||
glTexParameteri(tmpTextureType, GL_TEXTURE_WRAP_T, getTextureWrapMode(material.TextureLayer[i].TextureWrapV));
|
||||
tmpTexture->getStatesCache().WrapV = material.TextureLayer[i].TextureWrapV;
|
||||
}
|
||||
|
||||
|
@ -4608,6 +4626,7 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver),
|
|||
for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
|
||||
{
|
||||
Texture[i] = 0;
|
||||
TextureType[i] = GL_TEXTURE_2D;
|
||||
TextureFixedPipeline[i] = true;
|
||||
}
|
||||
|
||||
|
@ -4811,30 +4830,43 @@ void COpenGLCallBridge::setClientActiveTexture(GLenum texture)
|
|||
}
|
||||
}
|
||||
|
||||
void COpenGLCallBridge::setTexture(u32 stage, bool fixedPipeline)
|
||||
void COpenGLCallBridge::getTexture(u32 stage, GLenum& type, bool& fixedPipeline)
|
||||
{
|
||||
if (stage < MATERIAL_MAX_TEXTURES)
|
||||
{
|
||||
if((fixedPipeline && TextureFixedPipeline[stage] != fixedPipeline) || Texture[stage] != Driver->CurrentTexture[stage])
|
||||
type = TextureType[stage];
|
||||
fixedPipeline = TextureFixedPipeline[stage];
|
||||
}
|
||||
}
|
||||
|
||||
void COpenGLCallBridge::setTexture(u32 stage, GLenum type, bool fixedPipeline)
|
||||
{
|
||||
if (stage < MATERIAL_MAX_TEXTURES)
|
||||
{
|
||||
if((fixedPipeline && TextureFixedPipeline[stage] != fixedPipeline) || Texture[stage] != Driver->CurrentTexture[stage] || type != TextureType[stage])
|
||||
{
|
||||
setActiveTexture(GL_TEXTURE0_ARB + stage);
|
||||
|
||||
if(Driver->CurrentTexture[stage])
|
||||
{
|
||||
if(fixedPipeline)
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
{
|
||||
glDisable(TextureType[stage]);
|
||||
glEnable(type);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, static_cast<const COpenGLTexture*>(Driver->CurrentTexture[stage])->getOpenGLTextureName());
|
||||
glBindTexture(type, static_cast<const COpenGLTexture*>(Driver->CurrentTexture[stage])->getOpenGLTextureName());
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindTexture(type, 0);
|
||||
|
||||
if(fixedPipeline)
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(TextureType[stage]);
|
||||
}
|
||||
|
||||
TextureFixedPipeline[stage] = fixedPipeline;
|
||||
TextureType[stage] = type;
|
||||
Texture[stage] = Driver->CurrentTexture[stage];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -441,8 +441,13 @@ namespace video
|
|||
|
||||
//! inits the parts of the open gl driver used on all platforms
|
||||
bool genericDriverInit();
|
||||
|
||||
//! returns a device dependent texture from a software surface (IImage)
|
||||
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData);
|
||||
virtual ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData);
|
||||
|
||||
//! returns a device dependent texture from a software surface (IImage)
|
||||
virtual ITexture* createDeviceDependentTextureCube(const io::path& name, IImage* posXImage, IImage* negXImage,
|
||||
IImage* posYImage, IImage* negYImage, IImage* posZImage, IImage* negZImage);
|
||||
|
||||
//! creates a transposed matrix in supplied GLfloat array to pass to OpenGL
|
||||
inline void getGLMatrix(GLfloat gl_matrix[16], const core::matrix4& m);
|
||||
|
@ -671,7 +676,9 @@ namespace video
|
|||
|
||||
void setClientActiveTexture(GLenum texture);
|
||||
|
||||
void setTexture(u32 stage, bool fixedPipeline);
|
||||
void getTexture(u32 stage, GLenum& type, bool& fixedPipeline);
|
||||
|
||||
void setTexture(u32 stage, GLenum type, bool fixedPipeline);
|
||||
|
||||
private:
|
||||
COpenGLDriver* Driver;
|
||||
|
@ -702,6 +709,7 @@ namespace video
|
|||
GLenum ClientActiveTexture;
|
||||
|
||||
const ITexture* Texture[MATERIAL_MAX_TEXTURES];
|
||||
GLenum TextureType[MATERIAL_MAX_TEXTURES];
|
||||
bool TextureFixedPipeline[MATERIAL_MAX_TEXTURES];
|
||||
};
|
||||
|
||||
|
|
|
@ -797,6 +797,8 @@ bool COpenGLExtensionHandler::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
|
|||
return false;
|
||||
case EVDF_TEXTURE_COMPRESSED_ETC2:
|
||||
return FeatureAvailable[IRR_ARB_ES3_compatibility];
|
||||
case EVDF_TEXTURE_CUBE_MAP:
|
||||
return FeatureAvailable[IRR_ARB_texture_cube_map];
|
||||
default:
|
||||
return false;
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
|
@ -21,11 +21,11 @@ namespace video
|
|||
|
||||
//! constructor for usual textures
|
||||
COpenGLTexture::COpenGLTexture(IImage* origImage, const io::path& name, void* mipmapData, COpenGLDriver* driver)
|
||||
: ITexture(name), ColorFormat(ECF_A8R8G8B8), Driver(driver), Image(0), MipImage(0),
|
||||
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT),
|
||||
: ITexture(name, ETT_2D), ColorFormat(ECF_A8R8G8B8), Driver(driver), Image(0), MipImage(0),
|
||||
TextureName(0), TextureType(GL_TEXTURE_2D), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT),
|
||||
PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), MipmapLegacyMode(true),
|
||||
IsRenderTarget(false), IsCompressed(false), AutomaticMipmapUpdate(false),
|
||||
ReadOnlyLock(false), KeepImage(false)
|
||||
ReadOnlyLock(false), KeepImage(true)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("COpenGLTexture");
|
||||
|
@ -36,39 +36,112 @@ COpenGLTexture::COpenGLTexture(IImage* origImage, const io::path& name, void* mi
|
|||
|
||||
if (IsCompressed)
|
||||
{
|
||||
Image = origImage;
|
||||
Image->grab();
|
||||
Image.push_back(origImage);
|
||||
Image[0]->grab();
|
||||
KeepImage = false;
|
||||
}
|
||||
else if (ImageSize==TextureSize)
|
||||
{
|
||||
Image = Driver->createImage(ColorFormat, ImageSize);
|
||||
origImage->copyTo(Image);
|
||||
Image.push_back(Driver->createImage(ColorFormat, ImageSize));
|
||||
origImage->copyTo(Image[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Image = Driver->createImage(ColorFormat, TextureSize);
|
||||
origImage->copyToScaling(Image);
|
||||
Image.push_back(Driver->createImage(ColorFormat, TextureSize));
|
||||
origImage->copyToScaling(Image[0]);
|
||||
}
|
||||
|
||||
glGenTextures(1, &TextureName);
|
||||
uploadTexture(true, mipmapData);
|
||||
uploadTexture(true, 0, true, mipmapData);
|
||||
|
||||
if (!KeepImage)
|
||||
{
|
||||
Image->drop();
|
||||
Image=0;
|
||||
Image[0]->drop();
|
||||
|
||||
Image.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! constructor for cube textures
|
||||
COpenGLTexture::COpenGLTexture(const io::path& name, IImage* posXImage, IImage* negXImage, IImage* posYImage,
|
||||
IImage* negYImage, IImage* posZImage, IImage* negZImage, COpenGLDriver* driver)
|
||||
: ITexture(name, ETT_CUBE), ColorFormat(ECF_A8R8G8B8), Driver(driver), Image(0), MipImage(0),
|
||||
TextureName(0), TextureType(GL_TEXTURE_CUBE_MAP), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT),
|
||||
PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), MipmapLegacyMode(true),
|
||||
IsRenderTarget(false), IsCompressed(false), AutomaticMipmapUpdate(false),
|
||||
ReadOnlyLock(false), KeepImage(true)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("COpenGLTexture");
|
||||
#endif
|
||||
|
||||
HasMipMaps = Driver->getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
|
||||
getImageValues(posXImage);
|
||||
|
||||
if (IsCompressed)
|
||||
{
|
||||
Image.push_back(posXImage);
|
||||
Image.push_back(negXImage);
|
||||
Image.push_back(posYImage);
|
||||
Image.push_back(negYImage);
|
||||
Image.push_back(posZImage);
|
||||
Image.push_back(negZImage);
|
||||
|
||||
for (u32 i = 0; i < 6; ++i)
|
||||
Image[i]->grab();
|
||||
|
||||
KeepImage = false;
|
||||
}
|
||||
else if (ImageSize==TextureSize)
|
||||
{
|
||||
for (u32 i = 0; i < 6; ++i)
|
||||
Image.push_back(Driver->createImage(ColorFormat, ImageSize));
|
||||
|
||||
posXImage->copyTo(Image[0]);
|
||||
negXImage->copyTo(Image[1]);
|
||||
posYImage->copyTo(Image[2]);
|
||||
negYImage->copyTo(Image[3]);
|
||||
posZImage->copyTo(Image[4]);
|
||||
negZImage->copyTo(Image[5]);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = 0; i < 6; ++i)
|
||||
Image.push_back(Driver->createImage(ColorFormat, ImageSize));
|
||||
|
||||
posXImage->copyToScaling(Image[0]);
|
||||
negXImage->copyToScaling(Image[1]);
|
||||
posYImage->copyToScaling(Image[2]);
|
||||
negYImage->copyToScaling(Image[3]);
|
||||
posZImage->copyToScaling(Image[4]);
|
||||
negZImage->copyToScaling(Image[5]);
|
||||
}
|
||||
|
||||
glGenTextures(1, &TextureName);
|
||||
|
||||
for (u32 i = 0; i < 5; ++i)
|
||||
uploadTexture(true, i, false);
|
||||
|
||||
uploadTexture(true, 5, true);
|
||||
|
||||
if (!KeepImage)
|
||||
{
|
||||
for (u32 i = 0; i < Image.size(); ++i)
|
||||
Image[i]->drop();
|
||||
|
||||
Image.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! constructor for basic setup (only for derived classes)
|
||||
COpenGLTexture::COpenGLTexture(const io::path& name, COpenGLDriver* driver)
|
||||
: ITexture(name), ColorFormat(ECF_A8R8G8B8), Driver(driver), Image(0), MipImage(0),
|
||||
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT),
|
||||
: ITexture(name, ETT_2D), ColorFormat(ECF_A8R8G8B8), Driver(driver), Image(0), MipImage(0),
|
||||
TextureName(0), TextureType(GL_TEXTURE_2D), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT),
|
||||
PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), HasMipMaps(true),
|
||||
MipmapLegacyMode(true), IsRenderTarget(false), IsCompressed(false),
|
||||
AutomaticMipmapUpdate(false), ReadOnlyLock(false), KeepImage(false)
|
||||
AutomaticMipmapUpdate(false), ReadOnlyLock(false), KeepImage(true)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("COpenGLTexture");
|
||||
|
@ -83,7 +156,7 @@ COpenGLTexture::~COpenGLTexture()
|
|||
if (Driver->CurrentTexture[i] == this)
|
||||
{
|
||||
Driver->setActiveTexture(i, 0);
|
||||
Driver->getBridgeCalls()->setTexture(i, true);
|
||||
Driver->getBridgeCalls()->setTexture(i, TextureType, true);
|
||||
}
|
||||
|
||||
// Remove this texture from active materials as well
|
||||
|
@ -99,8 +172,8 @@ COpenGLTexture::~COpenGLTexture()
|
|||
|
||||
if (TextureName)
|
||||
glDeleteTextures(1, &TextureName);
|
||||
if (Image)
|
||||
Image->drop();
|
||||
for (u32 i = 0; i < Image.size(); ++i)
|
||||
Image[i]->drop();
|
||||
}
|
||||
|
||||
|
||||
|
@ -388,10 +461,10 @@ void COpenGLTexture::getImageValues(IImage* image)
|
|||
|
||||
|
||||
//! copies the the texture into an open gl texture.
|
||||
void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
|
||||
void COpenGLTexture::uploadTexture(bool newTexture, u32 imageNumber, bool regMipmap, void* mipmapData, u32 level)
|
||||
{
|
||||
// check which image needs to be uploaded
|
||||
IImage* image = level?MipImage:Image;
|
||||
IImage* image = level?MipImage:Image[imageNumber];
|
||||
if (!image)
|
||||
{
|
||||
os::Printer::log("No image for OpenGL texture to upload", ELL_ERROR);
|
||||
|
@ -408,7 +481,7 @@ void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
|
|||
InternalFormat = oldInternalFormat;
|
||||
|
||||
Driver->setActiveTexture(0, this);
|
||||
Driver->getBridgeCalls()->setTexture(0, true);
|
||||
Driver->getBridgeCalls()->setTexture(0, TextureType, true);
|
||||
|
||||
if (Driver->testGLError())
|
||||
os::Printer::log("Could not bind Texture", ELL_ERROR);
|
||||
|
@ -417,7 +490,7 @@ void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
|
|||
if (!level && newTexture)
|
||||
{
|
||||
// auto generate if possible and no mipmap data is given
|
||||
if (!IsCompressed && HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE))
|
||||
if (!IsCompressed && HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE) && regMipmap)
|
||||
{
|
||||
if (!Driver->queryFeature(EVDF_FRAMEBUFFER_OBJECT))
|
||||
{
|
||||
|
@ -429,7 +502,7 @@ void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
|
|||
else
|
||||
glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_DONT_CARE);
|
||||
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE );
|
||||
glTexParameteri(TextureType, GL_GENERATE_MIPMAP, GL_TRUE );
|
||||
MipmapLegacyMode=true;
|
||||
AutomaticMipmapUpdate=true;
|
||||
#endif
|
||||
|
@ -457,8 +530,39 @@ void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
|
|||
StatesCache.TrilinearFilter = false;
|
||||
StatesCache.MipMapStatus = false;
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
glTexParameteri(TextureType, GL_TEXTURE_MIN_FILTER, filtering);
|
||||
glTexParameteri(TextureType, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
}
|
||||
|
||||
// get texture type
|
||||
|
||||
GLenum tmpTextureType = GL_TEXTURE_2D;
|
||||
|
||||
if (TextureType == GL_TEXTURE_CUBE_MAP)
|
||||
{
|
||||
switch(imageNumber)
|
||||
{
|
||||
case 0:
|
||||
tmpTextureType = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
break;
|
||||
case 1:
|
||||
tmpTextureType = GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
|
||||
break;
|
||||
case 2:
|
||||
tmpTextureType = GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
|
||||
break;
|
||||
case 3:
|
||||
tmpTextureType = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
|
||||
break;
|
||||
case 4:
|
||||
tmpTextureType = GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
|
||||
break;
|
||||
case 5:
|
||||
tmpTextureType = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// now get image data and upload to GPU
|
||||
|
@ -470,27 +574,27 @@ void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
|
|||
{
|
||||
if (IsCompressed)
|
||||
{
|
||||
Driver->extGlCompressedTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, image->getDimension().Width,
|
||||
Driver->extGlCompressedTexImage2D(tmpTextureType, 0, InternalFormat, image->getDimension().Width,
|
||||
image->getDimension().Height, 0, compressedImageSize, source);
|
||||
}
|
||||
else
|
||||
glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width,
|
||||
glTexImage2D(tmpTextureType, level, InternalFormat, image->getDimension().Width,
|
||||
image->getDimension().Height, 0, PixelFormat, PixelType, source);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsCompressed)
|
||||
{
|
||||
Driver->extGlCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width,
|
||||
Driver->extGlCompressedTexSubImage2D(tmpTextureType, 0, 0, 0, image->getDimension().Width,
|
||||
image->getDimension().Height, PixelFormat, compressedImageSize, source);
|
||||
}
|
||||
else
|
||||
glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width,
|
||||
glTexSubImage2D(tmpTextureType, level, 0, 0, image->getDimension().Width,
|
||||
image->getDimension().Height, PixelFormat, PixelType, source);
|
||||
}
|
||||
image->unlock();
|
||||
|
||||
if (!level && newTexture)
|
||||
if (!level && newTexture && regMipmap)
|
||||
{
|
||||
if (IsCompressed && !mipmapData)
|
||||
{
|
||||
|
@ -518,8 +622,8 @@ void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
|
|||
StatesCache.TrilinearFilter = false;
|
||||
StatesCache.MipMapStatus = false;
|
||||
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filteringMipMaps);
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
glTexParameteri(TextureType, GL_TEXTURE_MIN_FILTER, filteringMipMaps);
|
||||
glTexParameteri(TextureType, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -527,18 +631,29 @@ void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
|
|||
os::Printer::log("Could not glTexImage2D", ELL_ERROR);
|
||||
|
||||
Driver->setActiveTexture(0, 0);
|
||||
Driver->getBridgeCalls()->setTexture(0, true);
|
||||
Driver->getBridgeCalls()->setTexture(0, TextureType, true);
|
||||
}
|
||||
|
||||
|
||||
//! lock function
|
||||
void* COpenGLTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
|
||||
{
|
||||
if (IsCompressed) // TO-DO
|
||||
if (IsCompressed || Type != ETT_2D) // TO-DO
|
||||
return 0;
|
||||
|
||||
// store info about which image is locked
|
||||
IImage* image = (mipmapLevel==0)?Image:MipImage;
|
||||
IImage* image = 0;
|
||||
|
||||
if (mipmapLevel==0)
|
||||
{
|
||||
if (Image.size() > 0)
|
||||
image = Image[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
image = MipImage;
|
||||
}
|
||||
|
||||
ReadOnlyLock |= (mode==ETLM_READ_ONLY);
|
||||
MipLevelStored = mipmapLevel;
|
||||
if (!ReadOnlyLock && mipmapLevel)
|
||||
|
@ -547,7 +662,7 @@ void* COpenGLTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
|
|||
if (Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE))
|
||||
{
|
||||
// do not automatically generate and update mipmaps
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
|
||||
glTexParameteri(TextureType, GL_GENERATE_MIPMAP, GL_FALSE);
|
||||
}
|
||||
#endif
|
||||
AutomaticMipmapUpdate=false;
|
||||
|
@ -576,7 +691,14 @@ void* COpenGLTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
|
|||
MipImage = image = Driver->createImage(ECF_A8R8G8B8, core::dimension2du(width,height));
|
||||
}
|
||||
else
|
||||
Image = image = Driver->createImage(ECF_A8R8G8B8, ImageSize);
|
||||
{
|
||||
image = Driver->createImage(ECF_A8R8G8B8, ImageSize);
|
||||
|
||||
if (Image.size() == 0)
|
||||
Image.push_back(image);
|
||||
else
|
||||
Image[0] = image;
|
||||
}
|
||||
ColorFormat = ECF_A8R8G8B8;
|
||||
}
|
||||
if (!image)
|
||||
|
@ -589,9 +711,12 @@ void* COpenGLTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
|
|||
return 0;
|
||||
|
||||
// we need to keep the correct texture bound later on
|
||||
GLint tmpTexture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &tmpTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, TextureName);
|
||||
const COpenGLTexture* tmpTexture = static_cast<const COpenGLTexture*>(Driver->CurrentTexture[0]);
|
||||
GLuint tmpTextureType = GL_TEXTURE_2D;
|
||||
GLint tmpTextureName = (tmpTexture) ? tmpTexture->getOpenGLTextureName() : 0;
|
||||
bool tmpFixedPipeline = false;
|
||||
Driver->getBridgeCalls()->getTexture(0, tmpTextureType, tmpFixedPipeline);
|
||||
glBindTexture(TextureType, TextureName);
|
||||
|
||||
// we need to flip textures vertical
|
||||
// however, it seems that this does not hold for mipmap
|
||||
|
@ -604,7 +729,7 @@ void* COpenGLTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
|
|||
#endif
|
||||
|
||||
// download GPU data as ARGB8 to pixels;
|
||||
glGetTexImage(GL_TEXTURE_2D, mipmapLevel, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
|
||||
glGetTexImage(TextureType, mipmapLevel, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
if (!mipmapLevel)
|
||||
{
|
||||
|
@ -632,7 +757,7 @@ void* COpenGLTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
|
|||
image->unlock();
|
||||
|
||||
//reset old bound texture
|
||||
glBindTexture(GL_TEXTURE_2D, tmpTexture);
|
||||
glBindTexture(tmpTextureType, tmpTextureName);
|
||||
}
|
||||
}
|
||||
return image->lock();
|
||||
|
@ -642,18 +767,29 @@ void* COpenGLTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
|
|||
//! unlock function
|
||||
void COpenGLTexture::unlock()
|
||||
{
|
||||
if (IsCompressed) // TO-DO
|
||||
if (IsCompressed || Type != ETT_2D) // TO-DO
|
||||
return;
|
||||
|
||||
// test if miplevel or main texture was locked
|
||||
IImage* image = MipImage?MipImage:Image;
|
||||
IImage* image = 0;
|
||||
|
||||
if (!MipImage)
|
||||
{
|
||||
if (Image.size() > 0)
|
||||
image = Image[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
image = MipImage;
|
||||
}
|
||||
|
||||
if (!image)
|
||||
return;
|
||||
// unlock image to see changes
|
||||
image->unlock();
|
||||
// copy texture data to GPU
|
||||
if (!ReadOnlyLock)
|
||||
uploadTexture(false, 0, MipLevelStored);
|
||||
uploadTexture(false, 0, true, 0, MipLevelStored);
|
||||
ReadOnlyLock = false;
|
||||
// cleanup local image
|
||||
if (MipImage)
|
||||
|
@ -663,12 +799,12 @@ void COpenGLTexture::unlock()
|
|||
}
|
||||
else if (!KeepImage)
|
||||
{
|
||||
Image->drop();
|
||||
Image=0;
|
||||
Image[0]->drop();
|
||||
Image.clear();
|
||||
}
|
||||
// update information
|
||||
if (Image)
|
||||
ColorFormat=Image->getColorFormat();
|
||||
if (Image.size() > 0)
|
||||
ColorFormat=Image[0]->getColorFormat();
|
||||
else
|
||||
ColorFormat=ECF_A8R8G8B8;
|
||||
}
|
||||
|
@ -705,8 +841,8 @@ ECOLOR_FORMAT COpenGLTexture::getColorFormat() const
|
|||
//! returns pitch of texture (in bytes)
|
||||
u32 COpenGLTexture::getPitch() const
|
||||
{
|
||||
if (Image)
|
||||
return Image->getPitch();
|
||||
if (Image.size() > 0)
|
||||
return Image[0]->getPitch();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -719,6 +855,13 @@ GLuint COpenGLTexture::getOpenGLTextureName() const
|
|||
}
|
||||
|
||||
|
||||
//! return open gl texture type
|
||||
GLenum COpenGLTexture::getOpenGLTextureType() const
|
||||
{
|
||||
return TextureType;
|
||||
}
|
||||
|
||||
|
||||
//! Returns whether this texture has mipmaps
|
||||
bool COpenGLTexture::hasMipMaps() const
|
||||
{
|
||||
|
@ -746,23 +889,42 @@ void COpenGLTexture::regenerateMipMapLevels(void* mipmapData)
|
|||
return;
|
||||
|
||||
// hardware doesn't support generate mipmaps for certain texture but image data doesn't exist or is wrong.
|
||||
if (!AutomaticMipmapUpdate && (!Image || (Image && ((Image->getDimension().Width==1) && (Image->getDimension().Height==1)))))
|
||||
if (!AutomaticMipmapUpdate && (Image.size() == 0 || (Image.size() > 0 && ((Image[0]->getDimension().Width==1) && (Image[0]->getDimension().Height==1)))))
|
||||
return;
|
||||
}
|
||||
|
||||
// hardware moethods for generate mipmaps.
|
||||
if (!mipmapData && AutomaticMipmapUpdate && !MipmapLegacyMode)
|
||||
{
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
Driver->extGlGenerateMipmap(GL_TEXTURE_2D);
|
||||
glEnable(TextureType);
|
||||
|
||||
const COpenGLTexture* tmpTexture = static_cast<const COpenGLTexture*>(Driver->CurrentTexture[0]);
|
||||
GLuint tmpTextureType = GL_TEXTURE_2D;
|
||||
GLint tmpTextureName = (tmpTexture) ? tmpTexture->getOpenGLTextureName() : 0;
|
||||
bool tmpFixedPipeline = false;
|
||||
Driver->getBridgeCalls()->getTexture(0, tmpTextureType, tmpFixedPipeline);
|
||||
glBindTexture(TextureType, TextureName);
|
||||
Driver->extGlGenerateMipmap(TextureType);
|
||||
glBindTexture(tmpTextureType, tmpTextureName);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// only 2D textures are supported in manual creation mipmaps process.
|
||||
if (Type != ETT_2D)
|
||||
return;
|
||||
|
||||
const COpenGLTexture* tmpTexture = static_cast<const COpenGLTexture*>(Driver->CurrentTexture[0]);
|
||||
GLuint tmpTextureType = GL_TEXTURE_2D;
|
||||
GLint tmpTextureName = (tmpTexture) ? tmpTexture->getOpenGLTextureName() : 0;
|
||||
bool tmpFixedPipeline = false;
|
||||
Driver->getBridgeCalls()->getTexture(0, tmpTextureType, tmpFixedPipeline);
|
||||
glBindTexture(TextureType, TextureName);
|
||||
|
||||
// Manually create mipmaps or use prepared version
|
||||
u32 compressedImageSize = 0;
|
||||
u32 width=Image->getDimension().Width;
|
||||
u32 height=Image->getDimension().Height;
|
||||
u32 width=Image[0]->getDimension().Width;
|
||||
u32 height=Image[0]->getDimension().Height;
|
||||
u32 i=0;
|
||||
u8* target = static_cast<u8*>(mipmapData);
|
||||
do
|
||||
|
@ -775,21 +937,21 @@ void COpenGLTexture::regenerateMipMapLevels(void* mipmapData)
|
|||
++i;
|
||||
|
||||
if (!target)
|
||||
target = new u8[width*height*Image->getBytesPerPixel()];
|
||||
target = new u8[width*height*Image[0]->getBytesPerPixel()];
|
||||
|
||||
// create scaled version if no mipdata available
|
||||
if (!mipmapData)
|
||||
Image->copyToScaling(target, width, height, Image->getColorFormat());
|
||||
Image[0]->copyToScaling(target, width, height, Image[0]->getColorFormat());
|
||||
|
||||
if (IsCompressed)
|
||||
{
|
||||
compressedImageSize = IImage::getCompressedImageSize(ColorFormat, width, height);
|
||||
|
||||
Driver->extGlCompressedTexImage2D(GL_TEXTURE_2D, i, InternalFormat, width,
|
||||
Driver->extGlCompressedTexImage2D(TextureType, i, InternalFormat, width,
|
||||
height, 0, compressedImageSize, target);
|
||||
}
|
||||
else
|
||||
glTexImage2D(GL_TEXTURE_2D, i, InternalFormat, width, height,
|
||||
glTexImage2D(TextureType, i, InternalFormat, width, height,
|
||||
0, PixelFormat, PixelType, target);
|
||||
|
||||
// get next prepared mipmap data if available
|
||||
|
@ -798,7 +960,7 @@ void COpenGLTexture::regenerateMipMapLevels(void* mipmapData)
|
|||
if (IsCompressed)
|
||||
mipmapData = static_cast<u8*>(mipmapData)+compressedImageSize;
|
||||
else
|
||||
mipmapData = static_cast<u8*>(mipmapData)+width*height*Image->getBytesPerPixel();
|
||||
mipmapData = static_cast<u8*>(mipmapData)+width*height*Image[0]->getBytesPerPixel();
|
||||
|
||||
target = static_cast<u8*>(mipmapData);
|
||||
}
|
||||
|
@ -807,6 +969,8 @@ void COpenGLTexture::regenerateMipMapLevels(void* mipmapData)
|
|||
// cleanup
|
||||
if (!mipmapData)
|
||||
delete [] target;
|
||||
|
||||
glBindTexture(tmpTextureType, tmpTextureName);
|
||||
}
|
||||
|
||||
|
||||
|
@ -838,13 +1002,13 @@ void COpenGLTexture::bindRTT()
|
|||
void COpenGLTexture::unbindRTT()
|
||||
{
|
||||
Driver->setActiveTexture(0, this);
|
||||
Driver->getBridgeCalls()->setTexture(0, true);
|
||||
Driver->getBridgeCalls()->setTexture(0, TextureType, true);
|
||||
|
||||
// Copy Our ViewPort To The Texture
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, getSize().Width, getSize().Height);
|
||||
glCopyTexSubImage2D(TextureType, 0, 0, 0, 0, 0, getSize().Width, getSize().Height);
|
||||
|
||||
Driver->setActiveTexture(0, 0);
|
||||
Driver->getBridgeCalls()->setTexture(0, true);
|
||||
Driver->getBridgeCalls()->setTexture(0, TextureType, true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -893,7 +1057,7 @@ COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d<u32>& size,
|
|||
glGenTextures(1, &TextureName);
|
||||
|
||||
Driver->setActiveTexture(0, this);
|
||||
Driver->getBridgeCalls()->setTexture(0, true);
|
||||
Driver->getBridgeCalls()->setTexture(0, TextureType, true);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
|
@ -927,7 +1091,7 @@ COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d<u32>& size,
|
|||
unbindRTT();
|
||||
|
||||
Driver->setActiveTexture(0, 0);
|
||||
Driver->getBridgeCalls()->setTexture(0, true);
|
||||
Driver->getBridgeCalls()->setTexture(0, TextureType, true);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "ITexture.h"
|
||||
#include "IImage.h"
|
||||
#include "SMaterialLayer.h"
|
||||
#include "irrArray.h"
|
||||
|
||||
#include "IrrCompileConfig.h"
|
||||
#ifdef _IRR_COMPILE_WITH_OPENGL_
|
||||
|
@ -75,6 +76,10 @@ public:
|
|||
//! constructor
|
||||
COpenGLTexture(IImage* surface, const io::path& name, void* mipmapData=0, COpenGLDriver* driver=0);
|
||||
|
||||
//! constructor
|
||||
COpenGLTexture(const io::path& name, IImage* posXImage, IImage* negXImage, IImage* posYImage,
|
||||
IImage* negYImage, IImage* posZImage, IImage* negZImage, COpenGLDriver* driver=0);
|
||||
|
||||
//! destructor
|
||||
virtual ~COpenGLTexture();
|
||||
|
||||
|
@ -102,6 +107,9 @@ public:
|
|||
//! return open gl texture name
|
||||
GLuint getOpenGLTextureName() const;
|
||||
|
||||
//! return open gl texture type
|
||||
GLenum getOpenGLTextureType() const;
|
||||
|
||||
//! return whether this texture has mipmaps
|
||||
virtual bool hasMipMaps() const;
|
||||
|
||||
|
@ -145,18 +153,21 @@ protected:
|
|||
|
||||
//! copies the texture into an OpenGL texture.
|
||||
/** \param newTexture True if method is called for a newly created texture for the first time. Otherwise call with false to improve memory handling.
|
||||
\param imageNumber Inform which image should be used for upload.
|
||||
\param regMipmap Inform if regenerate mipmap should be call.
|
||||
\param mipmapData Pointer to raw mipmap data, including all necessary mip levels, in the same format as the main texture image.
|
||||
\param mipLevel If set to non-zero, only that specific miplevel is updated, using the MipImage member. */
|
||||
void uploadTexture(bool newTexture=false, void* mipmapData=0, u32 mipLevel=0);
|
||||
void uploadTexture(bool newTexture=false, u32 imageNumber=0, bool regMipmap = false, void* mipmapData=0, u32 mipLevel=0);
|
||||
|
||||
core::dimension2d<u32> ImageSize;
|
||||
core::dimension2d<u32> TextureSize;
|
||||
ECOLOR_FORMAT ColorFormat;
|
||||
COpenGLDriver* Driver;
|
||||
IImage* Image;
|
||||
core::array<IImage*> Image;
|
||||
IImage* MipImage;
|
||||
|
||||
GLuint TextureName;
|
||||
GLenum TextureType;
|
||||
GLint InternalFormat;
|
||||
GLenum PixelFormat;
|
||||
GLenum PixelType;
|
||||
|
|
|
@ -1019,6 +1019,7 @@
|
|||
<ClInclude Include="COGLESTexture.h" />
|
||||
<ClInclude Include="COpenGLCgMaterialRenderer.h" />
|
||||
<ClInclude Include="CSceneManager.h" />
|
||||
<ClInclude Include="CWGLManager.h" />
|
||||
<ClInclude Include="Octree.h" />
|
||||
<ClInclude Include="CSMFMeshFileLoader.h" />
|
||||
<ClInclude Include="C3DSMeshFileLoader.h" />
|
||||
|
@ -1306,6 +1307,7 @@
|
|||
<ClCompile Include="CQ3LevelMesh.cpp" />
|
||||
<ClCompile Include="CSkinnedMesh.cpp" />
|
||||
<ClCompile Include="CSTLMeshFileLoader.cpp" />
|
||||
<ClCompile Include="CWGLManager.cpp" />
|
||||
<ClCompile Include="CXMeshFileLoader.cpp" />
|
||||
<ClCompile Include="CAnimatedMeshSceneNode.cpp" />
|
||||
<ClCompile Include="CBillboardSceneNode.cpp" />
|
||||
|
@ -1589,4 +1591,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -1354,6 +1354,8 @@
|
|||
<ClInclude Include="CImageLoaderPVR.h">
|
||||
<Filter>Irrlicht\video\Null\Loader</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CEGLManager.h" />
|
||||
<ClInclude Include="CWGLManager.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\changes.txt">
|
||||
|
@ -2327,6 +2329,8 @@
|
|||
<ClCompile Include="CImageLoaderPVR.cpp">
|
||||
<Filter>Irrlicht\video\Null\Loader</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CEGLManager.cpp" />
|
||||
<ClCompile Include="CWGLManager.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Irrlicht.rc" />
|
||||
|
|
Loading…
Reference in New Issue