- Added initial version of shared OpenGL texture. In upcoming commits existing issues will be fixed.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@5172 dfc29bdd-3216-0410-991c-e03cc46cb475
master
nadro 2015-11-08 16:49:13 +00:00
parent 016c81a9f3
commit 1553bef11f
23 changed files with 742 additions and 1201 deletions

View File

@ -113,8 +113,8 @@ class ITexture : public virtual IReferenceCounted
public:
//! constructor
ITexture(const io::path& name) : NamedPath(name), DriverType(EDT_NULL), ColorFormat(ECF_UNKNOWN),
Pitch(0), HasMipMaps(false), IsRenderTarget(false), Source(ETS_UNKNOWN)
ITexture(const io::path& name) : NamedPath(name), DriverType(EDT_NULL), OriginalColorFormat(ECF_UNKNOWN),
ColorFormat(ECF_UNKNOWN), Pitch(0), HasMipMaps(false), IsRenderTarget(false), Source(ETS_UNKNOWN)
{
}
@ -252,6 +252,7 @@ protected:
core::dimension2d<u32> OriginalSize;
core::dimension2d<u32> Size;
E_DRIVER_TYPE DriverType;
ECOLOR_FORMAT OriginalColorFormat;
ECOLOR_FORMAT ColorFormat;
u32 Pitch;
bool HasMipMaps;

View File

@ -1309,6 +1309,39 @@ bool CNullDriver::checkPrimitiveCount(u32 prmCount) const
return true;
}
bool CNullDriver::checkColorFormat(ECOLOR_FORMAT format, const core::dimension2d<u32>& size) const
{
bool status = true;
switch (format)
{
case ECF_DXT1:
case ECF_DXT2:
case ECF_DXT3:
case ECF_DXT4:
case ECF_DXT5:
{
core::dimension2d<u32> sizePOT = size.getOptimalSize(true, false);
if (!queryFeature(EVDF_TEXTURE_COMPRESSED_DXT))
{
os::Printer::log("DXT texture compression not available.", ELL_ERROR);
status = false;
}
else if (sizePOT != size)
{
os::Printer::log("Invalid size of image for DXT texture, size of image must be power of two.", ELL_ERROR);
status = false;
}
}
break;
default:
break;
}
return status;
}
//! Enables or disables a texture creation flag.
void CNullDriver::setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled)
{

View File

@ -690,6 +690,8 @@ namespace video
//! checks triangle count and print warning if wrong
bool checkPrimitiveCount(u32 prmcnt) const;
bool checkColorFormat(ECOLOR_FORMAT format, const core::dimension2d<u32>& size) const;
// adds a material renderer and drops it afterwards. To be used for internal creation
s32 addAndDropMaterialRenderer(IMaterialRenderer* m);

View File

@ -0,0 +1,417 @@
// Copyright (C) 2015 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_OGLCORE_TEXTURE_H_INCLUDED__
#define __C_OGLCORE_TEXTURE_H_INCLUDED__
#include "IrrCompileConfig.h"
#if defined(_IRR_COMPILE_WITH_OPENGL_) || defined(_IRR_COMPILE_WITH_OGLES1_) || defined(_IRR_COMPILE_WITH_OGLES2_)
#include "irrArray.h"
#include "SMaterialLayer.h"
#include "ITexture.h"
namespace irr
{
namespace video
{
template <class TOGLDriver>
class COGLCoreTexture : public ITexture
{
public:
struct SStatesCache
{
SStatesCache() : WrapU(ETC_REPEAT), WrapV(ETC_REPEAT),
LODBias(0), AnisotropicFilter(0),
BilinearFilter(false), TrilinearFilter(false),
MipMapStatus(false), IsCached(false)
{
}
u8 WrapU;
u8 WrapV;
s8 LODBias;
u8 AnisotropicFilter;
bool BilinearFilter;
bool TrilinearFilter;
bool MipMapStatus;
bool IsCached;
};
COGLCoreTexture(const io::path& name, const core::array<IImage*>& image, TOGLDriver* driver) : ITexture(name), Driver(driver), TextureType(GL_TEXTURE_2D),
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), LockReadOnly(false), LockImage(0), LockLevel(0), KeepImage(true),
AutoGenerateMipMaps(false)
{
_IRR_DEBUG_BREAK_IF(image.size() == 0)
DriverType = Driver->getDriverType();
HasMipMaps = Driver->getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
AutoGenerateMipMaps = Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE);
getImageValues(image[0]);
const core::array<IImage*>* tmpImage = &image;
if (KeepImage || OriginalSize != Size || OriginalColorFormat != ColorFormat)
{
Image.set_used(image.size());
for (u32 i = 0; i < image.size(); ++i)
{
Image[i] = Driver->createImage(ColorFormat, Size);
if (image[i]->getDimension() == Size)
image[i]->copyTo(Image[i]);
else
image[i]->copyToScaling(Image[i]);
}
tmpImage = &Image;
}
Pitch = (*tmpImage)[0]->getPitch();
glGenTextures(1, &TextureName);
const COGLCoreTexture* prevTexture = Driver->getCacheHandler()->getTextureCache().get(0);
Driver->getCacheHandler()->getTextureCache().set(0, this);
if (HasMipMaps && AutoGenerateMipMaps)
{
if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST);
else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY))
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
else
glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE);
}
#if defined(IRR_OPENGL_VERSION) && IRR_OPENGL_VERSION < 20
if (HasMipMaps)
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, (AutoGenerateMipMaps) ? GL_TRUE : GL_FALSE);
#endif
uploadTexture(true, 0, (*tmpImage)[0]->getData());
Driver->getCacheHandler()->getTextureCache().set(0, prevTexture);
regenerateMipMapLevels((*tmpImage)[0]->getMipMapsData());
if (!KeepImage)
{
for (u32 i = 0; i < Image.size(); ++i)
Image[i]->drop();
Image.clear();
}
}
COGLCoreTexture(const io::path& name, const core::dimension2d<u32>& size, ECOLOR_FORMAT format, TOGLDriver* driver) : ITexture(name), Driver(driver), TextureType(GL_TEXTURE_2D),
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), LockReadOnly(false), LockImage(0), LockLevel(0), KeepImage(false),
AutoGenerateMipMaps(false)
{
DriverType = Driver->getDriverType();
HasMipMaps = false;
IsRenderTarget = true;
OriginalColorFormat = format;
if (ECF_UNKNOWN == OriginalColorFormat)
ColorFormat = getBestColorFormat(Driver->getColorFormat());
else
ColorFormat = OriginalColorFormat;
OriginalSize = size;
Size = OriginalSize;
void(*converter)(const void*, s32, void*) = 0;
Driver->getColorFormatParameters(ColorFormat, InternalFormat, PixelFormat, PixelType, &converter);
glGenTextures(1, &TextureName);
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(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
StatesCache.WrapU = ETC_CLAMP_TO_EDGE;
StatesCache.WrapV = ETC_CLAMP_TO_EDGE;
glTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, Size.Width, Size.Height, 0, PixelFormat, PixelType, 0);
Driver->getCacheHandler()->getTextureCache().set(0, prevTexture);
}
virtual ~COGLCoreTexture()
{
Driver->getCacheHandler()->getTextureCache().remove(this);
if (TextureName)
glDeleteTextures(1, &TextureName);
for (u32 i = 0; i < Image.size(); ++i)
Image[i]->drop();
if (LockImage)
LockImage->drop();
}
virtual void* lock(E_TEXTURE_LOCK_MODE mode = ETLM_READ_WRITE, u32 mipmapLevel = 0) _IRR_OVERRIDE_
{
// TO-DO - this method will be improved.
if (IImage::isCompressedFormat(ColorFormat) || IsRenderTarget || mipmapLevel > 0) // TO-DO
return 0;
LockReadOnly |= (mode == ETLM_READ_ONLY);
LockLevel = mipmapLevel;
LockImage = Image[0];
return LockImage->getData();
}
virtual void unlock() _IRR_OVERRIDE_
{
if (!LockImage)
return;
if (!LockReadOnly)
{
const COGLCoreTexture* prevTexture = Driver->getCacheHandler()->getTextureCache().get(0);
Driver->getCacheHandler()->getTextureCache().set(0, this);
uploadTexture(false, LockLevel, LockImage->getData());
Driver->getCacheHandler()->getTextureCache().set(0, prevTexture);
if (LockLevel == 0)
regenerateMipMapLevels(LockImage->getMipMapsData());
}
if (!KeepImage || LockLevel != 0)
LockImage->drop();
LockReadOnly = false;
LockImage = 0;
LockLevel = 0;
}
virtual void regenerateMipMapLevels(void* mipMapsData = 0) _IRR_OVERRIDE_
{
if (!HasMipMaps || (!mipMapsData && !AutoGenerateMipMaps) || (Size.Width <= 1 && Size.Height <= 1))
return;
const COGLCoreTexture* prevTexture = Driver->getCacheHandler()->getTextureCache().get(0);
Driver->getCacheHandler()->getTextureCache().set(0, this);
if (mipMapsData)
{
u32 width = Size.Width;
u32 height = Size.Height;
u8* data = static_cast<u8*>(mipMapsData);
u32 dataSize = 0;
u32 level = 0;
do
{
if (width > 1)
width >>= 1;
if (height > 1)
height >>= 1;
dataSize = IImage::getDataSizeFromFormat(ColorFormat, width, height);
++level;
if (!IImage::isCompressedFormat(ColorFormat))
glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, width, height, 0, PixelFormat, PixelType, data);
else
Driver->irrGlCompressedTexImage2D(GL_TEXTURE_2D, level, InternalFormat, width, height, 0, dataSize, data);
data += dataSize;
}
while (width != 1 || height != 1);
}
else
{
#if defined(IRR_OPENGL_VERSION) && IRR_OPENGL_VERSION >= 20
Driver->irrGlGenerateMipmap(GL_TEXTURE_2D);
#endif
}
Driver->getCacheHandler()->getTextureCache().set(0, prevTexture);
}
GLenum getOpenGLTextureType() const
{
return TextureType;
}
GLuint getOpenGLTextureName() const
{
return TextureName;
}
SStatesCache& getStatesCache() const
{
return StatesCache;
}
protected:
ECOLOR_FORMAT getBestColorFormat(ECOLOR_FORMAT format)
{
ECOLOR_FORMAT destFormat = (!IImage::isCompressedFormat(format)) ? ECF_A8R8G8B8 : format;
switch (format)
{
case ECF_A1R5G5B5:
if (!Driver->getTextureCreationFlag(ETCF_ALWAYS_32_BIT))
destFormat = ECF_A1R5G5B5;
break;
case ECF_R5G6B5:
if (!Driver->getTextureCreationFlag(ETCF_ALWAYS_32_BIT))
destFormat = ECF_A1R5G5B5;
break;
case ECF_A8R8G8B8:
if (Driver->getTextureCreationFlag(ETCF_ALWAYS_16_BIT) ||
Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
destFormat = ECF_A1R5G5B5;
break;
case ECF_R8G8B8:
if (Driver->getTextureCreationFlag(ETCF_ALWAYS_16_BIT) || Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
destFormat = ECF_A1R5G5B5;
default:
break;
}
if (Driver->getTextureCreationFlag(ETCF_NO_ALPHA_CHANNEL))
{
switch (destFormat)
{
case ECF_A1R5G5B5:
destFormat = ECF_R5G6B5;
break;
case ECF_A8R8G8B8:
destFormat = ECF_R8G8B8;
break;
default:
break;
}
}
return destFormat;
}
void getImageValues(const IImage* image)
{
OriginalColorFormat = image->getColorFormat();
ColorFormat = getBestColorFormat(OriginalColorFormat);
void(*converter)(const void*, s32, void*) = 0;
Driver->getColorFormatParameters(ColorFormat, InternalFormat, PixelFormat, PixelType, &converter);
if (IImage::isCompressedFormat(image->getColorFormat()))
{
KeepImage = false;
AutoGenerateMipMaps = false;
}
OriginalSize = image->getDimension();
Size = OriginalSize;
if (Size.Width == 0 || Size.Height == 0)
{
os::Printer::log("Invalid size of image for texture.", ELL_ERROR);
return;
}
const f32 ratio = (f32)Size.Width / (f32)Size.Height;
if ((Size.Width > Driver->MaxTextureSize) && (ratio >= 1.f))
{
Size.Width = Driver->MaxTextureSize;
Size.Height = (u32)(Driver->MaxTextureSize / ratio);
}
else if (Size.Height > Driver->MaxTextureSize)
{
Size.Height = Driver->MaxTextureSize;
Size.Width = (u32)(Driver->MaxTextureSize * ratio);
}
Size = Size.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT));
}
void uploadTexture(bool initTexture, u32 level, const void* data)
{
if (!data)
return;
if (initTexture)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
u32 width = Size.Width >> level;
u32 height = Size.Height >> level;
if (!IImage::isCompressedFormat(ColorFormat))
{
if (initTexture)
{
glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, width, height, 0, PixelFormat, PixelType, data);
}
else
{
glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, width, height, PixelFormat, PixelType, data);
}
}
else
{
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);
}
}
}
TOGLDriver* Driver;
GLenum TextureType;
GLuint TextureName;
GLint InternalFormat;
GLenum PixelFormat;
GLenum PixelType;
bool LockReadOnly;
IImage* LockImage;
u32 LockLevel;
bool KeepImage;
core::array<IImage*> Image;
bool AutoGenerateMipMaps;
mutable SStatesCache StatesCache;
};
}
}
#endif
#endif

View File

@ -7,7 +7,6 @@
#ifdef _IRR_COMPILE_WITH_OPENGL_
#include "COpenGLDriver.h"
#include "COpenGLTexture.h"
namespace irr
{

View File

@ -9,15 +9,14 @@
#ifdef _IRR_COMPILE_WITH_OPENGL_
#include "COpenGLExtensionHandler.h"
#include "COpenGLCommon.h"
#include "COGLCoreTexture.h"
#include "COGLCoreCacheHandler.h"
namespace irr
{
namespace video
{
class COpenGLTexture;
class COpenGLDriver;
class COpenGLCacheHandler : public COGLCoreCacheHandler<COpenGLDriver, COpenGLTexture>
{

View File

@ -8,10 +8,10 @@
#ifdef _IRR_COMPILE_WITH_OPENGL_
#include "COGLCoreTexture.h"
#include "COGLCoreRenderTarget.h"
#include "COpenGLCacheHandler.h"
#include "COpenGLTexture.h"
#include "COpenGLMaterialRenderer.h"
#include "COpenGLShaderMaterialRenderer.h"
#include "COpenGLSLMaterialRenderer.h"
@ -2523,7 +2523,17 @@ 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)
{
return new COpenGLTexture(surface, name, this);
COpenGLTexture* texture = 0;
if (surface && checkColorFormat(surface->getColorFormat(), surface->getDimension()))
{
core::array<IImage*> imageArray(1);
imageArray.push_back(surface);
texture = new COpenGLTexture(name, imageArray, this);
}
return texture;
}
@ -3192,7 +3202,7 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
if (FixedPipelineState == EOFPS_ENABLE || FixedPipelineState == EOFPS_DISABLE_TO_ENABLE)
fixedPipeline = true;
const COpenGLTexture* tmpTexture = CacheHandler->getTextureCache()[i];
const COpenGLTexture* tmpTexture = CacheHandler->getTextureCache().get(i);
if (!tmpTexture)
continue;
@ -3218,13 +3228,15 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
}
}
if(resetAllRenderstates)
tmpTexture->getStatesCache().IsCached = false;
COpenGLTexture::SStatesCache& statesCache = tmpTexture->getStatesCache();
if (resetAllRenderstates)
statesCache.IsCached = false;
#ifdef GL_VERSION_2_1
if (Version>=210)
{
if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].LODBias != tmpTexture->getStatesCache().LODBias)
if(!statesCache.IsCached || material.TextureLayer[i].LODBias != statesCache.LODBias)
{
if (material.TextureLayer[i].LODBias)
{
@ -3234,7 +3246,7 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
else
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, 0.f);
tmpTexture->getStatesCache().LODBias = material.TextureLayer[i].LODBias;
statesCache.LODBias = material.TextureLayer[i].LODBias;
}
}
else if (FeatureAvailable[IRR_EXT_texture_lod_bias])
@ -3260,69 +3272,69 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
}
#endif
if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter ||
material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter)
if(!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter ||
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST);
tmpTexture->getStatesCache().BilinearFilter = material.TextureLayer[i].BilinearFilter;
tmpTexture->getStatesCache().TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
statesCache.BilinearFilter = material.TextureLayer[i].BilinearFilter;
statesCache.TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
}
if (material.UseMipMaps && tmpTexture->hasMipMaps())
{
if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter ||
material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter || !tmpTexture->getStatesCache().MipMapStatus)
if(!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter ||
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter || !statesCache.MipMapStatus)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
material.TextureLayer[i].TrilinearFilter ? GL_LINEAR_MIPMAP_LINEAR :
material.TextureLayer[i].BilinearFilter ? GL_LINEAR_MIPMAP_NEAREST :
GL_NEAREST_MIPMAP_NEAREST);
tmpTexture->getStatesCache().BilinearFilter = material.TextureLayer[i].BilinearFilter;
tmpTexture->getStatesCache().TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
tmpTexture->getStatesCache().MipMapStatus = true;
statesCache.BilinearFilter = material.TextureLayer[i].BilinearFilter;
statesCache.TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
statesCache.MipMapStatus = true;
}
}
else
{
if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter ||
material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter || tmpTexture->getStatesCache().MipMapStatus)
if(!statesCache.IsCached || material.TextureLayer[i].BilinearFilter != statesCache.BilinearFilter ||
material.TextureLayer[i].TrilinearFilter != statesCache.TrilinearFilter || statesCache.MipMapStatus)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
(material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST);
tmpTexture->getStatesCache().BilinearFilter = material.TextureLayer[i].BilinearFilter;
tmpTexture->getStatesCache().TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
tmpTexture->getStatesCache().MipMapStatus = false;
statesCache.BilinearFilter = material.TextureLayer[i].BilinearFilter;
statesCache.TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
statesCache.MipMapStatus = false;
}
}
#ifdef GL_EXT_texture_filter_anisotropic
if (FeatureAvailable[IRR_EXT_texture_filter_anisotropic] &&
(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].AnisotropicFilter != tmpTexture->getStatesCache().AnisotropicFilter))
(!statesCache.IsCached || material.TextureLayer[i].AnisotropicFilter != statesCache.AnisotropicFilter))
{
glTexParameteri(GL_TEXTURE_2D, 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;
statesCache.AnisotropicFilter = material.TextureLayer[i].AnisotropicFilter;
}
#endif
if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].TextureWrapU != tmpTexture->getStatesCache().WrapU)
if(!statesCache.IsCached || material.TextureLayer[i].TextureWrapU != statesCache.WrapU)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, getTextureWrapMode(material.TextureLayer[i].TextureWrapU));
tmpTexture->getStatesCache().WrapU = material.TextureLayer[i].TextureWrapU;
statesCache.WrapU = material.TextureLayer[i].TextureWrapU;
}
if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].TextureWrapV != tmpTexture->getStatesCache().WrapV)
if(!statesCache.IsCached || material.TextureLayer[i].TextureWrapV != statesCache.WrapV)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, getTextureWrapMode(material.TextureLayer[i].TextureWrapV));
tmpTexture->getStatesCache().WrapV = material.TextureLayer[i].TextureWrapV;
statesCache.WrapV = material.TextureLayer[i].TextureWrapV;
}
tmpTexture->getStatesCache().IsCached = true;
statesCache.IsCached = true;
}
// be sure to leave in texture stage 0
@ -3368,7 +3380,6 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
CacheHandler->setMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.375f, 0.375f, 0.0f);
// Make sure we set first texture matrix
CacheHandler->setActiveTexture(GL_TEXTURE0);
@ -4589,6 +4600,206 @@ GLenum COpenGLDriver::getZBufferBits() const
return bits;
}
void COpenGLDriver::getColorFormatParameters(ECOLOR_FORMAT format, GLint& internalFormat, GLenum& pixelFormat,
GLenum& pixelType, void(**converter)(const void*, s32, void*))
{
internalFormat = GL_RGBA;
pixelFormat = GL_RGBA;
pixelType = GL_UNSIGNED_BYTE;
switch (format)
{
case ECF_A1R5G5B5:
internalFormat = GL_RGBA;
pixelFormat = GL_BGRA_EXT;
pixelType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
break;
case ECF_R5G6B5:
internalFormat = GL_RGB;
pixelFormat = GL_RGB;
pixelType = GL_UNSIGNED_SHORT_5_6_5;
break;
case ECF_R8G8B8:
internalFormat = GL_RGB;
pixelFormat = GL_BGR;
pixelType = GL_UNSIGNED_BYTE;
break;
case ECF_A8R8G8B8:
internalFormat = GL_RGBA;
pixelFormat = GL_BGRA_EXT;
if (Version > 101)
pixelType = GL_UNSIGNED_INT_8_8_8_8_REV;
break;
case ECF_DXT1:
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
pixelFormat = GL_BGRA_EXT;
pixelType = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
break;
case ECF_DXT2:
case ECF_DXT3:
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
pixelFormat = GL_BGRA_EXT;
pixelType = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
break;
case ECF_DXT4:
case ECF_DXT5:
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
pixelFormat = GL_BGRA_EXT;
pixelType = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
break;
case ECF_D16:
internalFormat = GL_DEPTH_COMPONENT16;
pixelFormat = GL_DEPTH_COMPONENT;
pixelType = GL_UNSIGNED_BYTE;
break;
case ECF_D32:
internalFormat = GL_DEPTH_COMPONENT32;
pixelFormat = GL_DEPTH_COMPONENT;
pixelType = GL_UNSIGNED_BYTE;
break;
case ECF_D24S8:
#ifdef GL_EXT_packed_depth_stencil
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_EXT_packed_depth_stencil))
{
internalFormat = GL_DEPTH_STENCIL_EXT;
pixelFormat = GL_DEPTH_STENCIL_EXT;
pixelType = GL_UNSIGNED_INT_24_8_EXT;
}
else
#endif
os::Printer::log("ECF_D24S8 color format is not supported", ELL_ERROR);
break;
case ECF_R8:
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
internalFormat = GL_R8;
pixelFormat = GL_RED;
pixelType = GL_UNSIGNED_BYTE;
}
else
os::Printer::log("ECF_R8 color format is not supported", ELL_ERROR);
break;
case ECF_R8G8:
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
internalFormat = GL_RG8;
pixelFormat = GL_RG;
pixelType = GL_UNSIGNED_BYTE;
}
else
os::Printer::log("ECF_R8G8 color format is not supported", ELL_ERROR);
break;
case ECF_R16:
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
internalFormat = GL_R16;
pixelFormat = GL_RED;
pixelType = GL_UNSIGNED_SHORT;
}
else
os::Printer::log("ECF_R16 color format is not supported", ELL_ERROR);
break;
case ECF_R16G16:
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
internalFormat = GL_RG16;
pixelFormat = GL_RG;
pixelType = GL_UNSIGNED_SHORT;
}
else
os::Printer::log("ECF_R16G16 color format is not supported", ELL_ERROR);
break;
case ECF_R16F:
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
internalFormat = GL_R16F;
pixelFormat = GL_RED;
#ifdef GL_ARB_half_float_pixel
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_half_float_pixel))
pixelType = GL_HALF_FLOAT_ARB;
else
#endif
pixelType = GL_FLOAT;
}
else
os::Printer::log("ECF_R16F color format is not supported", ELL_ERROR);
break;
case ECF_G16R16F:
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
internalFormat = GL_RG16F;
pixelFormat = GL_RG;
#ifdef GL_ARB_half_float_pixel
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_half_float_pixel))
pixelType = GL_HALF_FLOAT_ARB;
else
#endif
pixelType = GL_FLOAT;
}
else
os::Printer::log("ECF_G16R16F color format is not supported", ELL_ERROR);
break;
case ECF_A16B16G16R16F:
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_float))
{
internalFormat = GL_RGBA16F_ARB;
pixelFormat = GL_RGBA;
#ifdef GL_ARB_half_float_pixel
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_half_float_pixel))
pixelType = GL_HALF_FLOAT_ARB;
else
#endif
pixelType = GL_FLOAT;
}
else
os::Printer::log("ECF_A16B16G16R16F color format is not supported", ELL_ERROR);
break;
case ECF_R32F:
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
internalFormat = GL_R32F;
pixelFormat = GL_RED;
pixelType = GL_FLOAT;
}
else
os::Printer::log("ECF_R32F color format is not supported", ELL_ERROR);
break;
case ECF_G32R32F:
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
internalFormat = GL_RG32F;
pixelFormat = GL_RG;
pixelType = GL_FLOAT;
}
else
os::Printer::log("ECF_G32R32F color format is not supported", ELL_ERROR);
break;
case ECF_A32B32G32R32F:
if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_float))
{
internalFormat = GL_RGBA32F_ARB;
pixelFormat = GL_RGBA;
pixelType = GL_FLOAT;
}
else
os::Printer::log("ECF_A32B32G32R32F color format is not supported", ELL_ERROR);
break;
default:
os::Printer::log("Unsupported texture format", ELL_ERROR);
break;
}
#if defined(GL_ARB_framebuffer_sRGB) || defined(GL_EXT_framebuffer_sRGB)
if (Params.HandleSRGB)
{
if (internalFormat == GL_RGBA)
internalFormat = GL_SRGB_ALPHA_EXT;
else if (internalFormat == GL_RGB)
internalFormat = GL_SRGB_EXT;
}
#endif
}
COpenGLDriver::E_OPENGL_FIXED_PIPELINE_STATE COpenGLDriver::getFixedPipelineState() const
{
return FixedPipelineState;

View File

@ -21,7 +21,7 @@ namespace irr
#include "CNullDriver.h"
#include "IMaterialRendererServices.h"
// also includes the OpenGL stuff
#include "COpenGLCommon.h"
#include "COpenGLExtensionHandler.h"
namespace irr
@ -29,19 +29,10 @@ namespace irr
namespace video
{
template <class TOGLDriver, class TOGLTexture>
class COGLCoreRenderTarget;
class COpenGLCacheHandler;
class COpenGLTexture;
class COpenGLDriver;
typedef COGLCoreRenderTarget<COpenGLDriver, COpenGLTexture> COpenGLRenderTarget;
class COpenGLDriver : public CNullDriver, public IMaterialRendererServices, public COpenGLExtensionHandler
{
friend class COpenGLCacheHandler;
friend class COpenGLTexture;
friend COpenGLCacheHandler;
friend COpenGLTexture;
public:
// Information about state of fixed pipeline activity.
enum E_OPENGL_FIXED_PIPELINE_STATE
@ -406,6 +397,9 @@ namespace video
//! Get ZBuffer bits.
GLenum getZBufferBits() const;
void getColorFormatParameters(ECOLOR_FORMAT format, GLint& internalFormat, GLenum& pixelFormat,
GLenum& pixelType, void(**converter)(const void*, s32, void*));
//! Return info about fixed pipeline state.
E_OPENGL_FIXED_PIPELINE_STATE getFixedPipelineState() const;

View File

@ -6,139 +6,13 @@
#define __C_OPEN_GL_FEATURE_MAP_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OPENGL_
#include "EDriverFeatures.h"
#include "irrTypes.h"
#include "os.h"
#if defined(_IRR_WINDOWS_API_)
// include windows headers for HWND
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
#endif
#include <GL/gl.h>
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#include "glext.h"
#endif
#include "wglext.h"
#ifdef _MSC_VER
#pragma comment(lib, "OpenGL32.lib")
#endif
#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
#endif
#include <OpenGL/gl.h>
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#include "glext.h"
#endif
#elif defined(_IRR_COMPILE_WITH_SDL_DEVICE_) && !defined(_IRR_COMPILE_WITH_X11_DEVICE_)
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
#define GLX_GLXEXT_LEGACY 1
#else
#define GL_GLEXT_PROTOTYPES 1
#define GLX_GLXEXT_PROTOTYPES 1
#endif
#define NO_SDL_GLEXT
#include <SDL/SDL_video.h>
#include <SDL/SDL_opengl.h>
#include "glext.h"
#else
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
#define GLX_GLXEXT_LEGACY 1
#else
#define GL_GLEXT_PROTOTYPES 1
#define GLX_GLXEXT_PROTOTYPES 1
#endif
#include <GL/gl.h>
#include <GL/glx.h>
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#include "glext.h"
#undef GLX_ARB_get_proc_address // avoid problems with local glxext.h
#include "glxext.h"
#endif
#endif
#ifndef GL_ARB_shader_objects
/* GL types for program/shader text and shader object handles */
typedef char GLcharARB;
typedef unsigned int GLhandleARB;
#endif
#ifndef GL_VERSION_2_0
/* GL type for program/shader text */
typedef char GLchar;
#endif
// Blending definitions.
#if !defined(GL_VERSION_1_4)
#if defined(GL_EXT_blend_subtract) || defined(GL_EXT_blend_minmax) || defined(GL_EXT_blend_logic_op)
#define GL_FUNC_ADD GL_FUNC_ADD_EXT
#else
#define GL_FUNC_ADD 0
#endif
#endif
// FBO definitions.
#if !defined(GL_VERSION_3_0) && !defined(GL_ARB_framebuffer_object)
#ifdef GL_EXT_framebuffer_object
#define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
#define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT
#define GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_EXT
#define GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_EXT
#define GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_EXT
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT
#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT
#define GL_FRAMEBUFFER_UNSUPPORTED GL_FRAMEBUFFER_UNSUPPORTED_EXT
#else
#define GL_FRAMEBUFFER 0
#define GL_COLOR_ATTACHMENT0 0
#define GL_DEPTH_ATTACHMENT 0
#define GL_STENCIL_ATTACHMENT 0
#define GL_FRAMEBUFFER_COMPLETE 0
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 1
#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 2
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 3
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 4
#define GL_FRAMEBUFFER_UNSUPPORTED 5
#endif
#endif
#ifdef GL_EXT_framebuffer_object
#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
#else
#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS 6
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 7
#endif
// Texture definitions.
#if !defined(GL_VERSION_1_3)
#ifdef GL_ARB_multitexture
#define GL_TEXTURE0 GL_TEXTURE0_ARB
#else
#define GL_TEXTURE0 0
#endif
#endif
// Irrlicht's OpenGL version.
#define IRR_OPENGL_VERSION 14
#include "COpenGLCommon.h"
#include "COGLCoreFeature.h"
namespace irr
@ -1182,10 +1056,10 @@ class COpenGLExtensionHandler
void extGlPointParameterfv(GLint loc, const GLfloat *v);
void extGlStencilFuncSeparate (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
void extGlStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
void extGlCompressedTexImage2D(GLenum target, GLint level,
void irrGlCompressedTexImage2D(GLenum target, GLint level,
GLenum internalformat, GLsizei width, GLsizei height,
GLint border, GLsizei imageSize, const void* data);
void extGlCompressedTexSubImage2D(GLenum target, GLint level,
void irrGlCompressedTexSubImage2D(GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
GLenum format, GLsizei imageSize, const void* data);
@ -2133,7 +2007,7 @@ inline void COpenGLExtensionHandler::extGlStencilOpSeparate (GLenum face, GLenum
#endif
}
inline void COpenGLExtensionHandler::extGlCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width,
inline void COpenGLExtensionHandler::irrGlCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width,
GLsizei height, GLint border, GLsizei imageSize, const void* data)
{
#ifdef _IRR_OPENGL_USE_EXTPOINTER_
@ -2146,7 +2020,7 @@ inline void COpenGLExtensionHandler::extGlCompressedTexImage2D (GLenum target, G
#endif
}
inline void COpenGLExtensionHandler::extGlCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
inline void COpenGLExtensionHandler::irrGlCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
{
#ifdef _IRR_OPENGL_USE_EXTPOINTER_

View File

@ -20,7 +20,6 @@
#include "IVideoDriver.h"
#include "os.h"
#include "COpenGLDriver.h"
#include "COpenGLTexture.h"
#include "COpenGLCacheHandler.h"
#include "COpenGLMaterialRenderer.h"

View File

@ -11,7 +11,6 @@
#include "IVideoDriver.h"
#include "os.h"
#include "COpenGLDriver.h"
#include "COpenGLTexture.h"
#include "COpenGLCacheHandler.h"
#include "COpenGLMaterialRenderer.h"

View File

@ -1,838 +0,0 @@
// 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
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OPENGL_
#include "irrTypes.h"
#include "COpenGLTexture.h"
#include "COpenGLDriver.h"
#include "COpenGLCacheHandler.h"
#include "os.h"
#include "CColorConverter.h"
#include "irrString.h"
namespace irr
{
namespace video
{
//! constructor for a standard textures
COpenGLTexture::COpenGLTexture(IImage* origImage, const io::path& name, COpenGLDriver* driver)
: ITexture(name), Driver(driver), Image(0), MipImage(0), TextureName(0), InternalFormat(GL_RGBA),
PixelFormat(GL_BGRA_EXT), PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), MipmapLegacyMode(true),
IsCompressed(false), AutomaticMipmapUpdate(false), ReadOnlyLock(false), KeepImage(true)
{
#ifdef _DEBUG
setDebugName("COpenGLTexture");
#endif
DriverType = EDT_OPENGL;
ColorFormat = ECF_A8R8G8B8;
HasMipMaps = Driver->getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
IsRenderTarget = false;
getImageValues(origImage);
if (IImage::isCompressedFormat(ColorFormat))
{
if (!Driver->queryFeature(EVDF_TEXTURE_COMPRESSED_DXT))
{
os::Printer::log("DXT texture compression not available.", ELL_ERROR);
return;
}
if (OriginalSize != Size)
{
os::Printer::log("Invalid size of image for compressed texture, size of image must be POT.", ELL_ERROR);
return;
}
else
{
IsCompressed = true;
Image = origImage;
Image->grab();
KeepImage = false;
}
}
else if (OriginalSize == Size)
{
Image = Driver->createImage(ColorFormat, OriginalSize);
origImage->copyTo(Image);
}
else
{
Image = Driver->createImage(ColorFormat, Size);
// scale texture
origImage->copyToScaling(Image);
}
Pitch = Image->getPitch();
glGenTextures(1, &TextureName);
uploadTexture(true, origImage->getMipMapsData());
if (!KeepImage)
{
Image->drop();
Image=0;
}
}
//! constructor for a render target textures
COpenGLTexture::COpenGLTexture(const io::path& name, const core::dimension2d<u32>& size, ECOLOR_FORMAT format, COpenGLDriver* driver)
: ITexture(name), Driver(driver), Image(0), MipImage(0), TextureName(0), InternalFormat(GL_RGBA),
PixelFormat(GL_BGRA_EXT), PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), MipmapLegacyMode(false),
IsCompressed(false), AutomaticMipmapUpdate(false), ReadOnlyLock(false), KeepImage(false)
{
#ifdef _DEBUG
setDebugName("COpenGLTexture");
#endif
COpenGLCacheHandler* cacheHandler = Driver->getCacheHandler();
const COpenGLTexture* prevTexture = cacheHandler->getTextureCache()[0];
DriverType = EDT_OPENGL;
if (ECF_UNKNOWN == format)
format = getBestColorFormat(driver->getColorFormat());
OriginalSize = size;
Size = size;
ColorFormat = format;
GLint FilteringType = 0;
InternalFormat = getOpenGLFormatAndParametersFromColorFormat(format, FilteringType, PixelFormat, PixelType);
HasMipMaps = false;
IsRenderTarget = true;
glGenTextures(1, &TextureName);
cacheHandler->getTextureCache().set(0, this);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, FilteringType);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (FilteringType == GL_NEAREST)
StatesCache.BilinearFilter = false;
else
StatesCache.BilinearFilter = true;
StatesCache.WrapU = ETC_CLAMP_TO_EDGE;
StatesCache.WrapV = ETC_CLAMP_TO_EDGE;
glTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, OriginalSize.Width, OriginalSize.Height, 0, PixelFormat, PixelType, 0);
cacheHandler->getTextureCache().set(0, prevTexture);
}
//! destructor
COpenGLTexture::~COpenGLTexture()
{
Driver->getCacheHandler()->getTextureCache().remove(this);
if (TextureName)
glDeleteTextures(1, &TextureName);
if (Image)
Image->drop();
}
//! Choose best matching color format, based on texture creation flags
ECOLOR_FORMAT COpenGLTexture::getBestColorFormat(ECOLOR_FORMAT format)
{
ECOLOR_FORMAT destFormat = ECF_A8R8G8B8;
switch (format)
{
case ECF_A1R5G5B5:
if (!Driver->getTextureCreationFlag(ETCF_ALWAYS_32_BIT))
destFormat = ECF_A1R5G5B5;
break;
case ECF_R5G6B5:
if (!Driver->getTextureCreationFlag(ETCF_ALWAYS_32_BIT))
destFormat = ECF_A1R5G5B5;
break;
case ECF_A8R8G8B8:
if (Driver->getTextureCreationFlag(ETCF_ALWAYS_16_BIT) ||
Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
destFormat = ECF_A1R5G5B5;
break;
case ECF_R8G8B8:
if (Driver->getTextureCreationFlag(ETCF_ALWAYS_16_BIT) ||
Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
destFormat = ECF_A1R5G5B5;
default:
break;
}
if (Driver->getTextureCreationFlag(ETCF_NO_ALPHA_CHANNEL))
{
switch (destFormat)
{
case ECF_A1R5G5B5:
destFormat = ECF_R5G6B5;
break;
case ECF_A8R8G8B8:
destFormat = ECF_R8G8B8;
break;
default:
break;
}
}
return destFormat;
}
//! Get opengl values for the GPU texture storage
GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT format,
GLint& filtering,
GLenum& colorformat,
GLenum& type)
{
// default
filtering = GL_LINEAR;
colorformat = GL_RGBA;
type = GL_UNSIGNED_BYTE;
GLenum internalformat = GL_RGBA;
switch(format)
{
case ECF_A1R5G5B5:
colorformat=GL_BGRA_EXT;
type=GL_UNSIGNED_SHORT_1_5_5_5_REV;
internalformat = GL_RGBA;
break;
case ECF_R5G6B5:
colorformat=GL_RGB;
type=GL_UNSIGNED_SHORT_5_6_5;
internalformat = GL_RGB;
break;
case ECF_R8G8B8:
colorformat=GL_BGR;
type=GL_UNSIGNED_BYTE;
internalformat = GL_RGB;
break;
case ECF_A8R8G8B8:
colorformat=GL_BGRA_EXT;
if (Driver->Version > 101)
type=GL_UNSIGNED_INT_8_8_8_8_REV;
internalformat = GL_RGBA;
break;
case ECF_DXT1:
colorformat = GL_BGRA_EXT;
type = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
internalformat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
break;
case ECF_DXT2:
case ECF_DXT3:
colorformat = GL_BGRA_EXT;
type = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
internalformat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
break;
case ECF_DXT4:
case ECF_DXT5:
colorformat = GL_BGRA_EXT;
type = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
internalformat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
break;
case ECF_D16:
colorformat = GL_DEPTH_COMPONENT;
type = GL_UNSIGNED_BYTE;
internalformat = GL_DEPTH_COMPONENT16;
break;
case ECF_D32:
colorformat = GL_DEPTH_COMPONENT;
type = GL_UNSIGNED_BYTE;
internalformat = GL_DEPTH_COMPONENT32;
break;
case ECF_D24S8:
#ifdef GL_EXT_packed_depth_stencil
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_EXT_packed_depth_stencil))
{
colorformat = GL_DEPTH_STENCIL_EXT;
type = GL_UNSIGNED_INT_24_8_EXT;
internalformat = GL_DEPTH_STENCIL_EXT;
}
else
#endif
os::Printer::log("ECF_D24S8 color format is not supported", ELL_ERROR);
break;
case ECF_R8:
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
colorformat = GL_RED;
type = GL_UNSIGNED_BYTE;
internalformat = GL_R8;
}
else
os::Printer::log("ECF_R8 color format is not supported", ELL_ERROR);
break;
case ECF_R8G8:
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
colorformat = GL_RG;
type = GL_UNSIGNED_BYTE;
internalformat = GL_RG8;
}
else
os::Printer::log("ECF_R8G8 color format is not supported", ELL_ERROR);
break;
case ECF_R16:
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
colorformat = GL_RED;
type = GL_UNSIGNED_SHORT;
internalformat = GL_R16;
}
else
os::Printer::log("ECF_R16 color format is not supported", ELL_ERROR);
break;
case ECF_R16G16:
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
colorformat = GL_RG;
type = GL_UNSIGNED_SHORT;
internalformat = GL_RG16;
}
else
os::Printer::log("ECF_R16G16 color format is not supported", ELL_ERROR);
break;
case ECF_R16F:
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
filtering = GL_NEAREST;
colorformat = GL_RED;
internalformat = GL_R16F;
#ifdef GL_ARB_half_float_pixel
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_half_float_pixel))
type = GL_HALF_FLOAT_ARB;
else
#endif
type = GL_FLOAT;
}
else
os::Printer::log("ECF_R16F color format is not supported", ELL_ERROR);
break;
case ECF_G16R16F:
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
filtering = GL_NEAREST;
colorformat = GL_RG;
internalformat = GL_RG16F;
#ifdef GL_ARB_half_float_pixel
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_half_float_pixel))
type = GL_HALF_FLOAT_ARB;
else
#endif
type = GL_FLOAT;
}
else
os::Printer::log("ECF_G16R16F color format is not supported", ELL_ERROR);
break;
case ECF_A16B16G16R16F:
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_float))
{
filtering = GL_NEAREST;
colorformat = GL_RGBA;
internalformat = GL_RGBA16F_ARB;
#ifdef GL_ARB_half_float_pixel
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_half_float_pixel))
type = GL_HALF_FLOAT_ARB;
else
#endif
type = GL_FLOAT;
}
else
os::Printer::log("ECF_A16B16G16R16F color format is not supported", ELL_ERROR);
break;
case ECF_R32F:
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
filtering = GL_NEAREST;
colorformat = GL_RED;
internalformat = GL_R32F;
type = GL_FLOAT;
}
else
os::Printer::log("ECF_R32F color format is not supported", ELL_ERROR);
break;
case ECF_G32R32F:
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
{
filtering = GL_NEAREST;
colorformat = GL_RG;
internalformat = GL_RG32F;
type = GL_FLOAT;
}
else
os::Printer::log("ECF_G32R32F color format is not supported", ELL_ERROR);
break;
case ECF_A32B32G32R32F:
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_float))
{
filtering = GL_NEAREST;
colorformat = GL_RGBA;
internalformat = GL_RGBA32F_ARB;
type = GL_FLOAT;
}
else
os::Printer::log("ECF_A32B32G32R32F color format is not supported", ELL_ERROR);
break;
default:
os::Printer::log("Unsupported texture format", ELL_ERROR);
break;
}
#if defined(GL_ARB_framebuffer_sRGB) || defined(GL_EXT_framebuffer_sRGB)
if (Driver->Params.HandleSRGB)
{
if (internalformat==GL_RGBA)
internalformat=GL_SRGB_ALPHA_EXT;
else if (internalformat==GL_RGB)
internalformat=GL_SRGB_EXT;
}
#endif
return internalformat;
}
// prepare values ImageSize, TextureSize, and ColorFormat based on image
void COpenGLTexture::getImageValues(IImage* image)
{
if (!image)
{
os::Printer::log("No image for OpenGL texture.", ELL_ERROR);
return;
}
OriginalSize = image->getDimension();
if (!OriginalSize.Width || !OriginalSize.Height)
{
os::Printer::log("Invalid size of image for OpenGL Texture.", ELL_ERROR);
return;
}
const f32 ratio = (f32)OriginalSize.Width / (f32)OriginalSize.Height;
if ((OriginalSize.Width>Driver->MaxTextureSize) && (ratio >= 1.0f))
{
OriginalSize.Width = Driver->MaxTextureSize;
OriginalSize.Height = (u32)(Driver->MaxTextureSize / ratio);
}
else if (OriginalSize.Height>Driver->MaxTextureSize)
{
OriginalSize.Height = Driver->MaxTextureSize;
OriginalSize.Width = (u32)(Driver->MaxTextureSize*ratio);
}
Size = OriginalSize.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT));
if (IImage::isCompressedFormat(image->getColorFormat()))
ColorFormat = image->getColorFormat();
else
ColorFormat = getBestColorFormat(image->getColorFormat());
}
//! copies the the texture into an open gl texture.
void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
{
// check which image needs to be uploaded
IImage* image = level?MipImage:Image;
if (!image)
{
os::Printer::log("No image for OpenGL texture to upload", ELL_ERROR);
return;
}
COpenGLCacheHandler* cacheHandler = Driver->getCacheHandler();
const COpenGLTexture* prevTexture = cacheHandler->getTextureCache()[0];
// get correct opengl color data values
GLenum oldInternalFormat = InternalFormat;
GLint filtering;
InternalFormat = getOpenGLFormatAndParametersFromColorFormat(ColorFormat, filtering, PixelFormat, PixelType);
// make sure we don't change the internal format of existing images
if (!newTexture)
InternalFormat=oldInternalFormat;
cacheHandler->getTextureCache().set(0, this);
if (Driver->testGLError())
os::Printer::log("Could not bind Texture", ELL_ERROR);
// mipmap handling for main texture
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 (!Driver->queryFeature(EVDF_FRAMEBUFFER_OBJECT))
{
#ifdef GL_SGIS_generate_mipmap
if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_FASTEST);
else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY))
glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
else
glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_DONT_CARE);
glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE );
MipmapLegacyMode=true;
AutomaticMipmapUpdate=true;
#endif
}
else
{
if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST);
else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY))
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
else
glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE);
MipmapLegacyMode=false;
AutomaticMipmapUpdate=true;
}
}
// enable bilinear filter without mipmaps
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
StatesCache.BilinearFilter = true;
StatesCache.TrilinearFilter = false;
StatesCache.MipMapStatus = false;
}
// now get image data and upload to GPU
u32 compressedDataSize = 0;
void* source = image->lock();
if (newTexture)
{
if (IsCompressed)
{
if(ColorFormat == ECF_DXT1)
compressedDataSize = ((image->getDimension().Width + 3) / 4) * ((image->getDimension().Height + 3) / 4) * 8;
else if (ColorFormat == ECF_DXT2 || ColorFormat == ECF_DXT3 || ColorFormat == ECF_DXT4 || ColorFormat == ECF_DXT5)
compressedDataSize = ((image->getDimension().Width + 3) / 4) * ((image->getDimension().Height + 3) / 4) * 16;
Driver->extGlCompressedTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, image->getDimension().Width,
image->getDimension().Height, 0, compressedDataSize, source);
}
else
glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width,
image->getDimension().Height, 0, PixelFormat, PixelType, source);
}
else
{
if (IsCompressed)
{
if(ColorFormat == ECF_DXT1)
compressedDataSize = ((image->getDimension().Width + 3) / 4) * ((image->getDimension().Height + 3) / 4) * 8;
else if (ColorFormat == ECF_DXT2 || ColorFormat == ECF_DXT3 || ColorFormat == ECF_DXT4 || ColorFormat == ECF_DXT5)
compressedDataSize = ((image->getDimension().Width + 3) / 4) * ((image->getDimension().Height + 3) / 4) * 16;
Driver->extGlCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width,
image->getDimension().Height, PixelFormat, compressedDataSize, source);
}
else
glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width,
image->getDimension().Height, PixelFormat, PixelType, source);
}
image->unlock();
if (!level && newTexture)
{
if (IsCompressed && !mipmapData)
HasMipMaps = false;
regenerateMipMapLevels(mipmapData);
if (HasMipMaps) // might have changed in regenerateMipMapLevels
{
// enable bilinear mipmap filter
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
StatesCache.BilinearFilter = true;
StatesCache.TrilinearFilter = false;
StatesCache.MipMapStatus = true;
}
}
if (Driver->testGLError())
os::Printer::log("Could not glTexImage2D", ELL_ERROR);
cacheHandler->getTextureCache().set(0, prevTexture);
}
//! lock function
void* COpenGLTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
{
if (IsCompressed) // TO-DO
return 0;
COpenGLCacheHandler* cacheHandler = Driver->getCacheHandler();
const COpenGLTexture* prevTexture = cacheHandler->getTextureCache()[0];
cacheHandler->getTextureCache().set(0, this);
// store info about which image is locked
IImage* image = (mipmapLevel==0)?Image:MipImage;
ReadOnlyLock |= (mode==ETLM_READ_ONLY);
MipLevelStored = mipmapLevel;
if (!ReadOnlyLock && mipmapLevel)
{
#ifdef GL_SGIS_generate_mipmap
if (Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE))
{
// do not automatically generate and update mipmaps
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
}
#endif
AutomaticMipmapUpdate=false;
}
// if data not available or might have changed on GPU download it
if (!image || IsRenderTarget)
{
// prepare the data storage if necessary
if (!image)
{
if (mipmapLevel)
{
u32 i=0;
u32 width = Size.Width;
u32 height = Size.Height;
do
{
if (width>1)
width>>=1;
if (height>1)
height>>=1;
++i;
}
while (i != mipmapLevel);
MipImage = image = Driver->createImage(ECF_A8R8G8B8, core::dimension2du(width,height));
}
else
Image = image = Driver->createImage(ECF_A8R8G8B8, OriginalSize);
ColorFormat = ECF_A8R8G8B8;
}
if (!image)
{
cacheHandler->getTextureCache().set(0, prevTexture);
return 0;
}
if (mode != ETLM_WRITE_ONLY)
{
u8* pixels = static_cast<u8*>(image->lock());
if (!pixels)
{
cacheHandler->getTextureCache().set(0, prevTexture);
return 0;
}
// we need to flip textures vertical
// however, it seems that this does not hold for mipmap
// textures, for unknown reasons.
// allows to read pixels in top-to-bottom order
#ifdef GL_MESA_pack_invert
if (!mipmapLevel && Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_MESA_pack_invert))
glPixelStorei(GL_PACK_INVERT_MESA, GL_TRUE);
#endif
// download GPU data as ARGB8 to pixels;
glGetTexImage(GL_TEXTURE_2D, mipmapLevel, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
if (!mipmapLevel)
{
#ifdef GL_MESA_pack_invert
if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_MESA_pack_invert))
glPixelStorei(GL_PACK_INVERT_MESA, GL_FALSE);
else
#endif
{
// opengl images are horizontally flipped, so we have to fix that here.
const s32 pitch=image->getPitch();
u8* p2 = pixels + (image->getDimension().Height - 1) * pitch;
u8* tmpBuffer = new u8[pitch];
for (u32 i=0; i < image->getDimension().Height; i += 2)
{
memcpy(tmpBuffer, pixels, pitch);
memcpy(pixels, p2, pitch);
memcpy(p2, tmpBuffer, pitch);
pixels += pitch;
p2 -= pitch;
}
delete [] tmpBuffer;
}
}
image->unlock();
}
}
cacheHandler->getTextureCache().set(0, prevTexture);
return image->lock();
}
//! unlock function
void COpenGLTexture::unlock()
{
if (IsCompressed) // TO-DO
return;
// test if miplevel or main texture was locked
IImage* image = MipImage?MipImage:Image;
if (!image)
return;
// unlock image to see changes
image->unlock();
// copy texture data to GPU
if (!ReadOnlyLock)
uploadTexture(false, 0, MipLevelStored);
ReadOnlyLock = false;
// cleanup local image
if (MipImage)
{
MipImage->drop();
MipImage=0;
}
else if (!KeepImage)
{
Image->drop();
Image=0;
}
// update information
if (Image)
ColorFormat=Image->getColorFormat();
else
ColorFormat=ECF_A8R8G8B8;
}
//! return open gl texture name
GLuint COpenGLTexture::getOpenGLTextureName() const
{
return TextureName;
}
//! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture
void COpenGLTexture::regenerateMipMapLevels(void* mipmapData)
{
// texture require mipmaps?
if (!HasMipMaps)
return;
// we don't use custom data for mipmaps.
if (!mipmapData)
{
// compressed textures require custom data for prepare mipmaps.
if (IsCompressed)
return;
// texture use legacy method for generate mipmaps?
if (AutomaticMipmapUpdate && MipmapLegacyMode)
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)))))
return;
}
COpenGLCacheHandler* cacheHandler = Driver->getCacheHandler();
const COpenGLTexture* prevTexture = cacheHandler->getTextureCache()[0];
cacheHandler->getTextureCache().set(0, this);
// hardware moethods for generate mipmaps.
if (!mipmapData && AutomaticMipmapUpdate && !MipmapLegacyMode)
{
Driver->irrGlGenerateMipmap(GL_TEXTURE_2D);
cacheHandler->getTextureCache().set(0, prevTexture);
return;
}
// Manually create mipmaps or use prepared version
u32 compressedDataSize = 0;
u32 width=Image->getDimension().Width;
u32 height=Image->getDimension().Height;
u32 i=0;
u8* target = static_cast<u8*>(mipmapData);
do
{
if (width>1)
width>>=1;
if (height>1)
height>>=1;
++i;
if (!target)
target = new u8[width*height*Image->getBytesPerPixel()];
// create scaled version if no mipdata available
if (!mipmapData)
Image->copyToScaling(target, width, height, Image->getColorFormat());
if (IsCompressed)
{
if(ColorFormat == ECF_DXT1)
compressedDataSize = ((width + 3) / 4) * ((height + 3) / 4) * 8;
else if (ColorFormat == ECF_DXT2 || ColorFormat == ECF_DXT3 || ColorFormat == ECF_DXT4 || ColorFormat == ECF_DXT5)
compressedDataSize = ((width + 3) / 4) * ((height + 3) / 4) * 16;
Driver->extGlCompressedTexImage2D(GL_TEXTURE_2D, i, InternalFormat, width,
height, 0, compressedDataSize, target);
}
else
glTexImage2D(GL_TEXTURE_2D, i, InternalFormat, width, height,
0, PixelFormat, PixelType, target);
// get next prepared mipmap data if available
if (mipmapData)
{
if (IsCompressed)
mipmapData = static_cast<u8*>(mipmapData)+compressedDataSize;
else
mipmapData = static_cast<u8*>(mipmapData)+width*height*Image->getBytesPerPixel();
target = static_cast<u8*>(mipmapData);
}
}
while (width!=1 || height!=1);
// cleanup
if (!mipmapData)
delete [] target;
cacheHandler->getTextureCache().set(0, prevTexture);
}
COpenGLTexture::SStatesCache& COpenGLTexture::getStatesCache() const
{
return StatesCache;
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_OPENGL_

View File

@ -1,147 +0,0 @@
// 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
#ifndef __C_OPEN_GL_TEXTURE_H_INCLUDED__
#define __C_OPEN_GL_TEXTURE_H_INCLUDED__
#include "ITexture.h"
#include "IImage.h"
#include "SMaterialLayer.h"
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OPENGL_
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
#else
#define GL_GLEXT_PROTOTYPES 1
#endif
#ifdef _IRR_WINDOWS_API_
// include windows headers for HWND
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <GL/gl.h>
#ifdef _MSC_VER
#pragma comment(lib, "OpenGL32.lib")
#endif
#elif defined(_IRR_OSX_PLATFORM_)
#include <OpenGL/gl.h>
#elif defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
#define NO_SDL_GLEXT
#include <SDL/SDL_video.h>
#include <SDL/SDL_opengl.h>
#else
#if defined(_IRR_OSX_PLATFORM_)
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif
#endif
namespace irr
{
namespace video
{
class COpenGLDriver;
//! OpenGL texture.
class COpenGLTexture : public ITexture
{
public:
//! Cache structure.
struct SStatesCache
{
SStatesCache() : WrapU(ETC_REPEAT), WrapV(ETC_REPEAT),
LODBias(0), AnisotropicFilter(0),
BilinearFilter(false), TrilinearFilter(false),
MipMapStatus(false), IsCached(false)
{
}
u8 WrapU;
u8 WrapV;
s8 LODBias;
u8 AnisotropicFilter;
bool BilinearFilter;
bool TrilinearFilter;
bool MipMapStatus;
bool IsCached;
};
//! constructor for a standard textures
COpenGLTexture(IImage* surface, const io::path& name, COpenGLDriver* driver);
//! constructor for a render target textures
COpenGLTexture(const io::path& name, const core::dimension2d<u32>& size, ECOLOR_FORMAT format, COpenGLDriver* driver);
//! destructor
virtual ~COpenGLTexture();
//! lock function
virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0) _IRR_OVERRIDE_;
//! unlock function
virtual void unlock() _IRR_OVERRIDE_;
//! Regenerates the mip map levels of the texture.
/** Useful after locking and modifying the texture
\param mipmapData Pointer to raw mipmap data, including all necessary mip levels, in the same format as the main texture image. If not set the mipmaps are derived from the main image. */
virtual void regenerateMipMapLevels(void* mipmapData = 0) _IRR_OVERRIDE_;
//! return open gl texture name
GLuint getOpenGLTextureName() const;
//! Get an access to texture states cache.
SStatesCache& getStatesCache() const;
protected:
//! protected constructor with basic setup, no GL texture name created, for derived classes
COpenGLTexture(const io::path& name, COpenGLDriver* driver);
//! get the desired color format based on texture creation flags and the input format.
ECOLOR_FORMAT getBestColorFormat(ECOLOR_FORMAT format);
//! Get the OpenGL color format parameters based on the given Irrlicht color format
GLint getOpenGLFormatAndParametersFromColorFormat(
ECOLOR_FORMAT format, GLint& filtering, GLenum& colorformat, GLenum& type);
//! get important numbers of the image and hw texture
void getImageValues(IImage* image);
//! 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 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);
COpenGLDriver* Driver;
IImage* Image;
IImage* MipImage;
GLuint TextureName;
GLint InternalFormat;
GLenum PixelFormat;
GLenum PixelType;
u8 MipLevelStored;
bool MipmapLegacyMode;
bool IsCompressed;
bool AutomaticMipmapUpdate;
bool ReadOnlyLock;
bool KeepImage;
mutable SStatesCache StatesCache;
};
} // end namespace video
} // end namespace irr
#endif
#endif // _IRR_COMPILE_WITH_OPENGL_

View File

@ -845,8 +845,6 @@
<Unit filename="COpenGLSLMaterialRenderer.h" />
<Unit filename="COpenGLShaderMaterialRenderer.cpp" />
<Unit filename="COpenGLShaderMaterialRenderer.h" />
<Unit filename="COpenGLTexture.cpp" />
<Unit filename="COpenGLTexture.h" />
<Unit filename="CPLYMeshFileLoader.cpp" />
<Unit filename="CPLYMeshFileLoader.h" />
<Unit filename="CPLYMeshWriter.cpp" />

View File

@ -1011,7 +1011,9 @@
<ClInclude Include="COGLCoreCacheHandler.h" />
<ClInclude Include="COGLCoreFeature.h" />
<ClInclude Include="COGLCoreRenderTarget.h" />
<ClInclude Include="COGLCoreTexture.h" />
<ClInclude Include="COpenGLCacheHandler.h" />
<ClInclude Include="COpenGLCommon.h" />
<ClInclude Include="COpenGLDriver.h" />
<ClInclude Include="COpenGLExtensionHandler.h" />
<ClInclude Include="COpenGLMaterialRenderer.h" />
@ -1019,7 +1021,6 @@
<ClInclude Include="COpenGLParallaxMapRenderer.h" />
<ClInclude Include="COpenGLShaderMaterialRenderer.h" />
<ClInclude Include="COpenGLSLMaterialRenderer.h" />
<ClInclude Include="COpenGLTexture.h" />
<ClInclude Include="CProfiler.h" />
<ClInclude Include="CSceneManager.h" />
<ClInclude Include="Octree.h" />
@ -1264,7 +1265,6 @@
<ClCompile Include="COpenGLParallaxMapRenderer.cpp" />
<ClCompile Include="COpenGLShaderMaterialRenderer.cpp" />
<ClCompile Include="COpenGLSLMaterialRenderer.cpp" />
<ClCompile Include="COpenGLTexture.cpp" />
<ClCompile Include="CSceneManager.cpp" />
<ClCompile Include="C3DSMeshFileLoader.cpp" />
<ClCompile Include="CSMFMeshFileLoader.cpp" />

View File

@ -1288,6 +1288,9 @@
<ClInclude Include="COpenGLCacheHandler.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COpenGLCommon.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COpenGLDriver.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
@ -1309,9 +1312,6 @@
<ClInclude Include="COpenGLSLMaterialRenderer.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COpenGLTexture.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COGLCoreCacheHandler.h">
<Filter>Irrlicht\video\OpenGL Core</Filter>
</ClInclude>
@ -1321,6 +1321,9 @@
<ClInclude Include="COGLCoreRenderTarget.h">
<Filter>Irrlicht\video\OpenGL Core</Filter>
</ClInclude>
<ClInclude Include="COGLCoreTexture.h">
<Filter>Irrlicht\video\OpenGL Core</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\changes.txt">
@ -2249,9 +2252,6 @@
<ClCompile Include="COpenGLSLMaterialRenderer.cpp">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClCompile>
<ClCompile Include="COpenGLTexture.cpp">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />

View File

@ -1011,7 +1011,9 @@
<ClInclude Include="COGLCoreCacheHandler.h" />
<ClInclude Include="COGLCoreFeature.h" />
<ClInclude Include="COGLCoreRenderTarget.h" />
<ClInclude Include="COGLCoreTexture.h" />
<ClInclude Include="COpenGLCacheHandler.h" />
<ClInclude Include="COpenGLCommon.h" />
<ClInclude Include="COpenGLDriver.h" />
<ClInclude Include="COpenGLExtensionHandler.h" />
<ClInclude Include="COpenGLMaterialRenderer.h" />
@ -1019,7 +1021,6 @@
<ClInclude Include="COpenGLParallaxMapRenderer.h" />
<ClInclude Include="COpenGLShaderMaterialRenderer.h" />
<ClInclude Include="COpenGLSLMaterialRenderer.h" />
<ClInclude Include="COpenGLTexture.h" />
<ClInclude Include="CSceneManager.h" />
<ClInclude Include="Octree.h" />
<ClInclude Include="CSMFMeshFileLoader.h" />
@ -1264,7 +1265,6 @@
<ClCompile Include="COpenGLParallaxMapRenderer.cpp" />
<ClCompile Include="COpenGLShaderMaterialRenderer.cpp" />
<ClCompile Include="COpenGLSLMaterialRenderer.cpp" />
<ClCompile Include="COpenGLTexture.cpp" />
<ClCompile Include="CSceneManager.cpp" />
<ClCompile Include="C3DSMeshFileLoader.cpp" />
<ClCompile Include="CSMFMeshFileLoader.cpp" />

View File

@ -1288,6 +1288,9 @@
<ClInclude Include="COpenGLCacheHandler.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COpenGLCommon.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COpenGLDriver.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
@ -1309,9 +1312,6 @@
<ClInclude Include="COpenGLSLMaterialRenderer.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COpenGLTexture.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COGLCoreCacheHandler.h">
<Filter>Irrlicht\video\OpenGL Core</Filter>
</ClInclude>
@ -1321,6 +1321,9 @@
<ClInclude Include="COGLCoreRenderTarget.h">
<Filter>Irrlicht\video\OpenGL Core</Filter>
</ClInclude>
<ClInclude Include="COGLCoreTexture.h">
<Filter>Irrlicht\video\OpenGL Core</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\changes.txt">
@ -2249,9 +2252,6 @@
<ClCompile Include="COpenGLSLMaterialRenderer.cpp">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClCompile>
<ClCompile Include="COpenGLTexture.cpp">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />

View File

@ -1011,7 +1011,9 @@
<ClInclude Include="COGLCoreCacheHandler.h" />
<ClInclude Include="COGLCoreFeature.h" />
<ClInclude Include="COGLCoreRenderTarget.h" />
<ClInclude Include="COGLCoreTexture.h" />
<ClInclude Include="COpenGLCacheHandler.h" />
<ClInclude Include="COpenGLCommon.h" />
<ClInclude Include="COpenGLDriver.h" />
<ClInclude Include="COpenGLExtensionHandler.h" />
<ClInclude Include="COpenGLMaterialRenderer.h" />
@ -1019,7 +1021,6 @@
<ClInclude Include="COpenGLParallaxMapRenderer.h" />
<ClInclude Include="COpenGLShaderMaterialRenderer.h" />
<ClInclude Include="COpenGLSLMaterialRenderer.h" />
<ClInclude Include="COpenGLTexture.h" />
<ClInclude Include="CSceneManager.h" />
<ClInclude Include="Octree.h" />
<ClInclude Include="CSMFMeshFileLoader.h" />
@ -1264,7 +1265,6 @@
<ClCompile Include="COpenGLParallaxMapRenderer.cpp" />
<ClCompile Include="COpenGLShaderMaterialRenderer.cpp" />
<ClCompile Include="COpenGLSLMaterialRenderer.cpp" />
<ClCompile Include="COpenGLTexture.cpp" />
<ClCompile Include="CSceneManager.cpp" />
<ClCompile Include="C3DSMeshFileLoader.cpp" />
<ClCompile Include="CSMFMeshFileLoader.cpp" />

View File

@ -1288,6 +1288,9 @@
<ClInclude Include="COpenGLCacheHandler.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COpenGLCommon.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COpenGLDriver.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
@ -1309,9 +1312,6 @@
<ClInclude Include="COpenGLSLMaterialRenderer.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COpenGLTexture.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COGLCoreCacheHandler.h">
<Filter>Irrlicht\video\OpenGL Core</Filter>
</ClInclude>
@ -1321,6 +1321,9 @@
<ClInclude Include="COGLCoreRenderTarget.h">
<Filter>Irrlicht\video\OpenGL Core</Filter>
</ClInclude>
<ClInclude Include="COGLCoreTexture.h">
<Filter>Irrlicht\video\OpenGL Core</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\changes.txt">
@ -2249,9 +2252,6 @@
<ClCompile Include="COpenGLSLMaterialRenderer.cpp">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClCompile>
<ClCompile Include="COpenGLTexture.cpp">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />

View File

@ -1021,7 +1021,9 @@
<ClInclude Include="COGLCoreCacheHandler.h" />
<ClInclude Include="COGLCoreFeature.h" />
<ClInclude Include="COGLCoreRenderTarget.h" />
<ClInclude Include="COGLCoreTexture.h" />
<ClInclude Include="COpenGLCacheHandler.h" />
<ClInclude Include="COpenGLCommon.h" />
<ClInclude Include="COpenGLDriver.h" />
<ClInclude Include="COpenGLExtensionHandler.h" />
<ClInclude Include="COpenGLMaterialRenderer.h" />
@ -1029,7 +1031,6 @@
<ClInclude Include="COpenGLParallaxMapRenderer.h" />
<ClInclude Include="COpenGLShaderMaterialRenderer.h" />
<ClInclude Include="COpenGLSLMaterialRenderer.h" />
<ClInclude Include="COpenGLTexture.h" />
<ClInclude Include="CSceneManager.h" />
<ClInclude Include="Octree.h" />
<ClInclude Include="CSMFMeshFileLoader.h" />
@ -1274,7 +1275,6 @@
<ClCompile Include="COpenGLParallaxMapRenderer.cpp" />
<ClCompile Include="COpenGLShaderMaterialRenderer.cpp" />
<ClCompile Include="COpenGLSLMaterialRenderer.cpp" />
<ClCompile Include="COpenGLTexture.cpp" />
<ClCompile Include="CSceneManager.cpp" />
<ClCompile Include="C3DSMeshFileLoader.cpp" />
<ClCompile Include="CSMFMeshFileLoader.cpp" />

View File

@ -1288,6 +1288,9 @@
<ClInclude Include="COpenGLCacheHandler.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COpenGLCommon.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COpenGLDriver.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
@ -1309,9 +1312,6 @@
<ClInclude Include="COpenGLSLMaterialRenderer.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COpenGLTexture.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
<ClInclude Include="COGLCoreCacheHandler.h">
<Filter>Irrlicht\video\OpenGL Core</Filter>
</ClInclude>
@ -1321,6 +1321,9 @@
<ClInclude Include="COGLCoreRenderTarget.h">
<Filter>Irrlicht\video\OpenGL Core</Filter>
</ClInclude>
<ClInclude Include="COGLCoreTexture.h">
<Filter>Irrlicht\video\OpenGL Core</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\changes.txt">
@ -2249,9 +2252,6 @@
<ClCompile Include="COpenGLSLMaterialRenderer.cpp">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClCompile>
<ClCompile Include="COpenGLTexture.cpp">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />

View File

@ -38,7 +38,7 @@ IRRMESHOBJ = $(IRRMESHLOADER) $(IRRMESHWRITER) \
IRROBJ = CBillboardSceneNode.o CCameraSceneNode.o CDummyTransformationSceneNode.o CEmptySceneNode.o CGeometryCreator.o CLightSceneNode.o CMeshManipulator.o CMetaTriangleSelector.o COctreeSceneNode.o COctreeTriangleSelector.o CSceneCollisionManager.o CSceneManager.o CShadowVolumeSceneNode.o CSkyBoxSceneNode.o CSkyDomeSceneNode.o CTerrainSceneNode.o CTerrainTriangleSelector.o CVolumeLightSceneNode.o CCubeSceneNode.o CSphereSceneNode.o CTextSceneNode.o CTriangleBBSelector.o CTriangleSelector.o CWaterSurfaceSceneNode.o CMeshCache.o CDefaultSceneNodeAnimatorFactory.o CDefaultSceneNodeFactory.o CSceneLoaderIrr.o
IRRPARTICLEOBJ = CParticleAnimatedMeshSceneNodeEmitter.o CParticleBoxEmitter.o CParticleCylinderEmitter.o CParticleMeshEmitter.o CParticlePointEmitter.o CParticleRingEmitter.o CParticleSphereEmitter.o CParticleAttractionAffector.o CParticleFadeOutAffector.o CParticleGravityAffector.o CParticleRotationAffector.o CParticleSystemSceneNode.o CParticleScaleAffector.o
IRRANIMOBJ = CSceneNodeAnimatorCameraFPS.o CSceneNodeAnimatorCameraMaya.o CSceneNodeAnimatorCollisionResponse.o CSceneNodeAnimatorDelete.o CSceneNodeAnimatorFlyCircle.o CSceneNodeAnimatorFlyStraight.o CSceneNodeAnimatorFollowSpline.o CSceneNodeAnimatorRotation.o CSceneNodeAnimatorTexture.o
IRRDRVROBJ = CNullDriver.o COpenGLCacheHandler.o COpenGLDriver.o COpenGLNormalMapRenderer.o COpenGLParallaxMapRenderer.o COpenGLShaderMaterialRenderer.o COpenGLTexture.o COpenGLSLMaterialRenderer.o COpenGLExtensionHandler.o CD3D9Driver.o CD3D9HLSLMaterialRenderer.o CD3D9NormalMapRenderer.o CD3D9ParallaxMapRenderer.o CD3D9ShaderMaterialRenderer.o CD3D9Texture.o
IRRDRVROBJ = CNullDriver.o COpenGLCacheHandler.o COpenGLDriver.o COpenGLNormalMapRenderer.o COpenGLParallaxMapRenderer.o COpenGLShaderMaterialRenderer.o COpenGLSLMaterialRenderer.o COpenGLExtensionHandler.o CD3D9Driver.o CD3D9HLSLMaterialRenderer.o CD3D9NormalMapRenderer.o CD3D9ParallaxMapRenderer.o CD3D9ShaderMaterialRenderer.o CD3D9Texture.o
IRRIMAGEOBJ = CColorConverter.o CImage.o CImageLoaderBMP.o CImageLoaderDDS.o CImageLoaderJPG.o CImageLoaderPCX.o CImageLoaderPNG.o CImageLoaderPSD.o CImageLoaderTGA.o CImageLoaderPPM.o CImageLoaderWAL.o CImageLoaderRGB.o \
CImageWriterBMP.o CImageWriterJPG.o CImageWriterPCX.o CImageWriterPNG.o CImageWriterPPM.o CImageWriterPSD.o CImageWriterTGA.o
IRRVIDEOOBJ = CVideoModeList.o CFPSCounter.o $(IRRDRVROBJ) $(IRRIMAGEOBJ)