Merge revision 5277:5282 from trunk to ogl-es.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@5288 dfc29bdd-3216-0410-991c-e03cc46cb475
master
cutealien 2016-03-18 17:24:46 +00:00
parent 5c1deb8550
commit 0fc5d21a40
13 changed files with 221 additions and 234 deletions

View File

@ -141,6 +141,8 @@ Changes in 1.9 (not yet released)
-------------------------- --------------------------
Changes in 1.8.4 Changes in 1.8.4
- Update libpng to 1.6.21
- Update zlib to 1.2.8
- Fix some compile warnings in aes which got handled as errors by some c++11 compilers. - Fix some compile warnings in aes which got handled as errors by some c++11 compilers.
- Get rid of some misleading-indentation warnings in gcc6 - Get rid of some misleading-indentation warnings in gcc6
- Fix serialization of the InputReceiverEnabled flag in CCameraSceneNode - Fix serialization of the InputReceiverEnabled flag in CCameraSceneNode

View File

@ -139,12 +139,11 @@ public:
only mode or read from in write only mode. only mode or read from in write only mode.
Support for this feature depends on the driver, so don't rely on the Support for this feature depends on the driver, so don't rely on the
texture being write-protected when locking with read-only, etc. texture being write-protected when locking with read-only, etc.
\param mipmapLevel Number of the mipmapLevel to lock. 0 is main texture. \param layer It determines which cubemap face or texture array layer should be locked.
Non-existing levels will silently fail and return 0.
\return Returns a pointer to the pixel data. The format of the pixel can \return Returns a pointer to the pixel data. The format of the pixel can
be determined by using getColorFormat(). 0 is returned, if be determined by using getColorFormat(). 0 is returned, if
the texture cannot be locked. */ the texture cannot be locked. */
virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0) = 0; virtual void* lock(E_TEXTURE_LOCK_MODE mode = ETLM_READ_WRITE, u32 layer = 0) = 0;
//! Unlock function. Must be called after a lock() to the texture. //! Unlock function. Must be called after a lock() to the texture.
/** One should avoid to call unlock more than once before another lock. /** One should avoid to call unlock more than once before another lock.

View File

@ -651,7 +651,7 @@ bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
case EVDF_TEXTURE_COMPRESSED_DXT: case EVDF_TEXTURE_COMPRESSED_DXT:
return true; return true;
case EVDF_TEXTURE_CUBEMAP: case EVDF_TEXTURE_CUBEMAP:
return false; return true;
default: default:
return false; return false;
}; };

View File

@ -16,8 +16,8 @@ namespace video
{ {
CD3D9Texture::CD3D9Texture(const io::path& name, const core::array<IImage*>& image, E_TEXTURE_TYPE type, CD3D9Driver* driver) CD3D9Texture::CD3D9Texture(const io::path& name, const core::array<IImage*>& image, E_TEXTURE_TYPE type, CD3D9Driver* driver)
: ITexture(name, type), Driver(driver), InternalFormat(D3DFMT_UNKNOWN), LockData(0), LockLevel(0), AutoGenerateMipMaps(false), : ITexture(name, type), Driver(driver), InternalFormat(D3DFMT_UNKNOWN), LockReadOnly(false), LockData(0), LockLayer(0),
Device(0), Texture(0), CubeTexture(0), RTTSurface(0) AutoGenerateMipMaps(false), Device(0), Texture(0), CubeTexture(0), RTTSurface(0)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CD3D9Texture"); setDebugName("CD3D9Texture");
@ -115,8 +115,8 @@ CD3D9Texture::CD3D9Texture(const io::path& name, const core::array<IImage*>& ima
} }
CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d<u32>& size, const io::path& name, const ECOLOR_FORMAT format) CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d<u32>& size, const io::path& name, const ECOLOR_FORMAT format)
: ITexture(name, ETT_2D), Driver(driver), InternalFormat(D3DFMT_UNKNOWN), LockData(0), LockLevel(0), AutoGenerateMipMaps(false), : ITexture(name, ETT_2D), Driver(driver), InternalFormat(D3DFMT_UNKNOWN), LockReadOnly(false), LockData(0), LockLayer(0),
Device(0), Texture(0), CubeTexture(0), RTTSurface(0) AutoGenerateMipMaps(false), Device(0), Texture(0), CubeTexture(0), RTTSurface(0)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CD3D9Texture"); setDebugName("CD3D9Texture");
@ -164,16 +164,16 @@ CD3D9Texture::~CD3D9Texture()
Device->Release(); Device->Release();
} }
void* CD3D9Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel) void* CD3D9Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 layer)
{ {
if (LockData) if (LockData)
return LockData; return LockData;
if (IImage::isCompressedFormat(ColorFormat) || mipmapLevel > 0) // TO-DO if (IImage::isCompressedFormat(ColorFormat))
return 0; return 0;
bool lockReadOnly = (mode == ETLM_READ_ONLY); LockReadOnly = (mode == ETLM_READ_ONLY);
LockLevel = mipmapLevel; LockLayer = layer;
HRESULT hr; HRESULT hr;
D3DLOCKED_RECT rect; D3DLOCKED_RECT rect;
@ -182,12 +182,13 @@ void* CD3D9Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
{ {
if (Texture) if (Texture)
{ {
hr = Texture->LockRect(mipmapLevel, &rect, 0, lockReadOnly ? D3DLOCK_READONLY : 0); hr = Texture->LockRect(0, &rect, 0, LockReadOnly ? D3DLOCK_READONLY : 0);
} }
else if (CubeTexture) else if (CubeTexture)
{ {
// TO-DO -> hardcoded D3DCUBEMAP_FACE_POSITIVE_X. _IRR_DEBUG_BREAK_IF(layer > 5)
hr = CubeTexture->LockRect(D3DCUBEMAP_FACE_POSITIVE_X, mipmapLevel, &rect, 0, lockReadOnly ? D3DLOCK_READONLY : 0);
hr = CubeTexture->LockRect(static_cast<_D3DCUBEMAP_FACES>(layer), 0, &rect, 0, LockReadOnly ? D3DLOCK_READONLY : 0);
} }
if (FAILED(hr)) if (FAILED(hr))
@ -212,7 +213,7 @@ void* CD3D9Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
} }
IDirect3DSurface9 *surface = 0; IDirect3DSurface9 *surface = 0;
hr = Texture->GetSurfaceLevel(mipmapLevel, &surface); hr = Texture->GetSurfaceLevel(0, &surface);
if (FAILED(hr)) if (FAILED(hr))
{ {
os::Printer::log("Could not lock DIRECT3D9 Texture", "Could not get surface.", ELL_ERROR); os::Printer::log("Could not lock DIRECT3D9 Texture", "Could not get surface.", ELL_ERROR);
@ -225,7 +226,7 @@ void* CD3D9Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
os::Printer::log("Could not lock DIRECT3D9 Texture", "Data copy failed.", ELL_ERROR); os::Printer::log("Could not lock DIRECT3D9 Texture", "Data copy failed.", ELL_ERROR);
return 0; return 0;
} }
hr = RTTSurface->LockRect(&rect, 0, lockReadOnly ? D3DLOCK_READONLY : 0); hr = RTTSurface->LockRect(&rect, 0, LockReadOnly ? D3DLOCK_READONLY : 0);
if(FAILED(hr)) if(FAILED(hr))
{ {
os::Printer::log("Could not lock DIRECT3D9 Texture", "LockRect failed.", ELL_ERROR); os::Printer::log("Could not lock DIRECT3D9 Texture", "LockRect failed.", ELL_ERROR);
@ -247,12 +248,11 @@ void CD3D9Texture::unlock()
{ {
if (Texture) if (Texture)
{ {
Texture->UnlockRect(LockLevel); Texture->UnlockRect(0);
} }
else if (CubeTexture) else if (CubeTexture)
{ {
// TO-DO -> hardcoded D3DCUBEMAP_FACE_POSITIVE_X. CubeTexture->UnlockRect(static_cast<_D3DCUBEMAP_FACES>(LockLayer), 0);
CubeTexture->UnlockRect(D3DCUBEMAP_FACE_POSITIVE_X, LockLevel);
} }
} }
else if (RTTSurface) else if (RTTSurface)
@ -260,11 +260,12 @@ void CD3D9Texture::unlock()
RTTSurface->UnlockRect(); RTTSurface->UnlockRect();
} }
if (LockLevel == 0) if (!LockReadOnly)
regenerateMipMapLevels(0); regenerateMipMapLevels(0, LockLayer);
LockReadOnly = false;
LockData = 0; LockData = 0;
LockLevel = 0; LockLayer = 0;
} }
void CD3D9Texture::regenerateMipMapLevels(void* data, u32 layer) void CD3D9Texture::regenerateMipMapLevels(void* data, u32 layer)
@ -456,13 +457,6 @@ void CD3D9Texture::uploadTexture(u32 layer, u32 level, void* data)
u32 width = Size.Width >> level; u32 width = Size.Width >> level;
u32 height = Size.Height >> level; u32 height = Size.Height >> level;
const D3DCUBEMAP_FACES cubeTextureType[6] =
{
D3DCUBEMAP_FACE_POSITIVE_X, D3DCUBEMAP_FACE_NEGATIVE_X,
D3DCUBEMAP_FACE_POSITIVE_Y, D3DCUBEMAP_FACE_NEGATIVE_Y,
D3DCUBEMAP_FACE_POSITIVE_Z, D3DCUBEMAP_FACE_NEGATIVE_Z
};
u32 dataSize = IImage::getDataSizeFromFormat(ColorFormat, width, height); u32 dataSize = IImage::getDataSizeFromFormat(ColorFormat, width, height);
HRESULT hr = 0; HRESULT hr = 0;
@ -475,8 +469,9 @@ void CD3D9Texture::uploadTexture(u32 layer, u32 level, void* data)
} }
else if (CubeTexture) else if (CubeTexture)
{ {
const D3DCUBEMAP_FACES tmpCubeTextureType = cubeTextureType[(layer < 6) ? layer : 0]; _IRR_DEBUG_BREAK_IF(layer > 5)
hr = CubeTexture->LockRect(tmpCubeTextureType, level, &lockRectangle, 0, 0);
hr = CubeTexture->LockRect(static_cast<_D3DCUBEMAP_FACES>(layer), level, &lockRectangle, 0, 0);
} }
if (FAILED(hr)) if (FAILED(hr))
@ -493,8 +488,7 @@ void CD3D9Texture::uploadTexture(u32 layer, u32 level, void* data)
} }
else if (CubeTexture) else if (CubeTexture)
{ {
const D3DCUBEMAP_FACES tmpCubeTextureType = cubeTextureType[(layer < 6) ? layer : 0]; hr = CubeTexture->UnlockRect(static_cast<_D3DCUBEMAP_FACES>(layer), level);
hr = CubeTexture->UnlockRect(tmpCubeTextureType, level);
} }
if (FAILED(hr)) if (FAILED(hr))

View File

@ -32,7 +32,7 @@ public:
virtual ~CD3D9Texture(); virtual ~CD3D9Texture();
virtual void* lock(E_TEXTURE_LOCK_MODE mode = ETLM_READ_WRITE, u32 mipmapLevel = 0) _IRR_OVERRIDE_; virtual void* lock(E_TEXTURE_LOCK_MODE mode = ETLM_READ_WRITE, u32 layer = 0) _IRR_OVERRIDE_;
virtual void unlock() _IRR_OVERRIDE_; virtual void unlock() _IRR_OVERRIDE_;
@ -59,8 +59,9 @@ private:
D3DFORMAT InternalFormat; D3DFORMAT InternalFormat;
bool LockReadOnly;
void* LockData; void* LockData;
u32 LockLevel; u32 LockLayer;
bool AutoGenerateMipMaps; bool AutoGenerateMipMaps;

View File

@ -771,7 +771,7 @@ namespace video
{ {
SDummyTexture(const io::path& name, E_TEXTURE_TYPE type) : ITexture(name, type) {}; SDummyTexture(const io::path& name, E_TEXTURE_TYPE type) : ITexture(name, type) {};
virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0) _IRR_OVERRIDE_ { return 0; } virtual void* lock(E_TEXTURE_LOCK_MODE mode = ETLM_READ_WRITE, u32 layer = 0) _IRR_OVERRIDE_ { return 0; }
virtual void unlock()_IRR_OVERRIDE_ {} virtual void unlock()_IRR_OVERRIDE_ {}
virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_ {} virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_ {}
}; };

View File

@ -46,7 +46,7 @@ public:
}; };
COpenGLCoreTexture(const io::path& name, const core::array<IImage*>& image, E_TEXTURE_TYPE type, TOpenGLDriver* driver) : ITexture(name, type), Driver(driver), TextureType(GL_TEXTURE_2D), COpenGLCoreTexture(const io::path& name, const core::array<IImage*>& image, E_TEXTURE_TYPE type, TOpenGLDriver* driver) : ITexture(name, type), Driver(driver), TextureType(GL_TEXTURE_2D),
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), Converter(0), LockReadOnly(false), LockImage(0), LockLevel(0), TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), Converter(0), LockReadOnly(false), LockImage(0), LockLayer(0),
KeepImage(false), AutoGenerateMipMaps(false) KeepImage(false), AutoGenerateMipMaps(false)
{ {
_IRR_DEBUG_BREAK_IF(image.size() == 0) _IRR_DEBUG_BREAK_IF(image.size() == 0)
@ -134,7 +134,7 @@ public:
} }
COpenGLCoreTexture(const io::path& name, const core::dimension2d<u32>& size, ECOLOR_FORMAT format, TOpenGLDriver* driver) : ITexture(name, ETT_2D), Driver(driver), TextureType(GL_TEXTURE_2D), COpenGLCoreTexture(const io::path& name, const core::dimension2d<u32>& size, ECOLOR_FORMAT format, TOpenGLDriver* driver) : ITexture(name, ETT_2D), Driver(driver), TextureType(GL_TEXTURE_2D),
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), Converter(0), LockReadOnly(false), LockImage(0), LockLevel(0), KeepImage(false), TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), Converter(0), LockReadOnly(false), LockImage(0), LockLayer(0), KeepImage(false),
AutoGenerateMipMaps(false) AutoGenerateMipMaps(false)
{ {
DriverType = Driver->getDriverType(); DriverType = Driver->getDriverType();
@ -192,7 +192,7 @@ public:
Image[i]->drop(); Image[i]->drop();
} }
virtual void* lock(E_TEXTURE_LOCK_MODE mode = ETLM_READ_WRITE, u32 mipmapLevel = 0) _IRR_OVERRIDE_ virtual void* lock(E_TEXTURE_LOCK_MODE mode = ETLM_READ_WRITE, u32 layer = 0) _IRR_OVERRIDE_
{ {
if (LockImage) if (LockImage)
return LockImage->getData(); return LockImage->getData();
@ -201,24 +201,34 @@ public:
return 0; return 0;
LockReadOnly |= (mode == ETLM_READ_ONLY); LockReadOnly |= (mode == ETLM_READ_ONLY);
LockLevel = mipmapLevel; LockLayer = layer;
if (KeepImage && mipmapLevel == 0) if (KeepImage)
{ {
LockImage = Image[0]; _IRR_DEBUG_BREAK_IF(LockLayer > Image.size())
LockImage = Image[LockLayer];
LockImage->grab(); LockImage->grab();
} }
else else
{ {
const core::dimension2d<u32> lockImageSize(Size.Width >> mipmapLevel, Size.Height >> mipmapLevel); LockImage = Driver->createImage(ColorFormat, Size);
LockImage = Driver->createImage(ColorFormat, lockImageSize);
if (LockImage && mode != ETLM_WRITE_ONLY) if (LockImage && mode != ETLM_WRITE_ONLY)
{ {
IImage* tmpImage = Driver->createImage(ECF_A8R8G8B8, lockImageSize); IImage* tmpImage = Driver->createImage(ECF_A8R8G8B8, Size);
#if 0 // This method doesn't work properly in some cases #if 0 // This method doesn't work properly in some cases
glGetTexImage(GL_TEXTURE_2D, mipmapLevel, GL_RGBA, GL_UNSIGNED_BYTE, tmpImage->getData()); GLenum tmpTextureType = TextureType;
if (tmpTextureType == GL_TEXTURE_CUBE_MAP)
{
_IRR_DEBUG_BREAK_IF(layer > 5)
tmpTextureType = GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
}
glGetTexImage(tmpTextureType, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmpImage->getData());
if (IsRenderTarget) if (IsRenderTarget)
{ {
@ -241,7 +251,7 @@ public:
delete[] tmpBuffer; delete[] tmpBuffer;
} }
#else #else
COpenGLCoreTexture* tmpTexture = new COpenGLCoreTexture("OGL_CORE_LOCK_TEXTURE", lockImageSize, ColorFormat, Driver); COpenGLCoreTexture* tmpTexture = new COpenGLCoreTexture("OGL_CORE_LOCK_TEXTURE", Size, ColorFormat, Driver);
GLuint tmpFBO = 0; GLuint tmpFBO = 0;
Driver->irrGlGenFramebuffers(1, &tmpFBO); Driver->irrGlGenFramebuffers(1, &tmpFBO);
@ -251,7 +261,7 @@ public:
GLsizei prevViewportWidth = 0; GLsizei prevViewportWidth = 0;
GLsizei prevViewportHeight = 0; GLsizei prevViewportHeight = 0;
Driver->getCacheHandler()->getViewport(prevViewportX, prevViewportY, prevViewportWidth, prevViewportHeight); Driver->getCacheHandler()->getViewport(prevViewportX, prevViewportY, prevViewportWidth, prevViewportHeight);
Driver->getCacheHandler()->setViewport(0, 0, lockImageSize.Width, lockImageSize.Height); Driver->getCacheHandler()->setViewport(0, 0, Size.Width, Size.Height);
GLuint prevFBO = 0; GLuint prevFBO = 0;
Driver->getCacheHandler()->getFBO(prevFBO); Driver->getCacheHandler()->getFBO(prevFBO);
@ -259,9 +269,11 @@ public:
Driver->irrGlFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmpTexture->getOpenGLTextureName(), 0); Driver->irrGlFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmpTexture->getOpenGLTextureName(), 0);
Driver->draw2DImage(this, true); glClear(GL_COLOR_BUFFER_BIT);
glReadPixels(0, 0, lockImageSize.Width, lockImageSize.Height, GL_RGBA, GL_UNSIGNED_BYTE, tmpImage->getData()); Driver->draw2DImage(this, layer, true);
glReadPixels(0, 0, Size.Width, Size.Height, GL_RGBA, GL_UNSIGNED_BYTE, tmpImage->getData());
Driver->getCacheHandler()->setFBO(prevFBO); Driver->getCacheHandler()->setFBO(prevFBO);
Driver->getCacheHandler()->setViewport(prevViewportX, prevViewportY, prevViewportWidth, prevViewportHeight); Driver->getCacheHandler()->setViewport(prevViewportX, prevViewportY, prevViewportWidth, prevViewportHeight);
@ -316,19 +328,18 @@ public:
const COpenGLCoreTexture* prevTexture = Driver->getCacheHandler()->getTextureCache().get(0); const COpenGLCoreTexture* prevTexture = Driver->getCacheHandler()->getTextureCache().get(0);
Driver->getCacheHandler()->getTextureCache().set(0, this); Driver->getCacheHandler()->getTextureCache().set(0, this);
uploadTexture(false, 0, LockLevel, LockImage->getData()); uploadTexture(false, LockLayer, 0, LockImage->getData());
Driver->getCacheHandler()->getTextureCache().set(0, prevTexture); Driver->getCacheHandler()->getTextureCache().set(0, prevTexture);
if (LockLevel == 0) regenerateMipMapLevels(0, LockLayer);
regenerateMipMapLevels(0);
} }
LockImage->drop(); LockImage->drop();
LockReadOnly = false; LockReadOnly = false;
LockImage = 0; LockImage = 0;
LockLevel = 0; LockLayer = 0;
} }
virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_ virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_
@ -484,14 +495,14 @@ protected:
u32 width = Size.Width >> level; u32 width = Size.Width >> level;
u32 height = Size.Height >> level; u32 height = Size.Height >> level;
const GLenum cubeTextureType[6] = GLenum tmpTextureType = TextureType;
{
GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
};
GLenum tmpTextureType = (TextureType == GL_TEXTURE_CUBE_MAP) ? cubeTextureType[(layer < 6) ? layer : 0] : TextureType; if (tmpTextureType == GL_TEXTURE_CUBE_MAP)
{
_IRR_DEBUG_BREAK_IF(layer > 5)
tmpTextureType = GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
}
if (!IImage::isCompressedFormat(ColorFormat)) if (!IImage::isCompressedFormat(ColorFormat))
{ {
@ -555,7 +566,7 @@ protected:
bool LockReadOnly; bool LockReadOnly;
IImage* LockImage; IImage* LockImage;
u32 LockLevel; u32 LockLayer;
bool KeepImage; bool KeepImage;
core::array<IImage*> Image; core::array<IImage*> Image;

View File

@ -1511,7 +1511,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect
} }
void COpenGLDriver::draw2DImage(const video::ITexture* texture, bool flip) void COpenGLDriver::draw2DImage(const video::ITexture* texture, u32 layer, bool flip)
{ {
if (!texture || !CacheHandler->getTextureCache().set(0, texture)) if (!texture || !CacheHandler->getTextureCache().set(0, texture))
return; return;
@ -1527,22 +1527,92 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, bool flip)
Transformation3DChanged = true; Transformation3DChanged = true;
Quad2DVertices[0].Pos = core::vector3df(-1.f, 1.f, 0.f);
Quad2DVertices[1].Pos = core::vector3df(1.f, 1.f, 0.f);
Quad2DVertices[2].Pos = core::vector3df(1.f, -1.f, 0.f);
Quad2DVertices[3].Pos = core::vector3df(-1.f, -1.f, 0.f);
f32 modificator = (flip) ? 1.f : 0.f;
Quad2DVertices[0].TCoords = core::vector2df(0.f, 0.f + modificator);
Quad2DVertices[1].TCoords = core::vector2df(1.f, 0.f + modificator);
Quad2DVertices[2].TCoords = core::vector2df(1.f, 1.f - modificator);
Quad2DVertices[3].TCoords = core::vector2df(0.f, 1.f - modificator);
CacheHandler->setClientState(true, false, false, true); CacheHandler->setClientState(true, false, false, true);
glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].TCoords); const core::vector3df positionData[4] = {
glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(Quad2DVertices))[0].Pos); core::vector3df(-1.f, 1.f, 0.f),
core::vector3df(1.f, 1.f, 0.f),
core::vector3df(1.f, -1.f, 0.f),
core::vector3df(-1.f, -1.f, 0.f)
};
glVertexPointer(2, GL_FLOAT, sizeof(core::vector3df), positionData);
if (texture && texture->getType() == ETT_CUBEMAP)
{
const core::vector3df texcoordCubeData[6][4] = {
// GL_TEXTURE_CUBE_MAP_POSITIVE_X
{
core::vector3df(1.f, 1.f, 1.f),
core::vector3df(1.f, 1.f, -1.f),
core::vector3df(1.f, -1.f, -1.f),
core::vector3df(1.f, -1.f, 1.f)
},
// GL_TEXTURE_CUBE_MAP_NEGATIVE_X
{
core::vector3df(-1.f, 1.f, -1.f),
core::vector3df(-1.f, 1.f, 1.f),
core::vector3df(-1.f, -1.f, 1.f),
core::vector3df(-1.f, -1.f, -1.f)
},
// GL_TEXTURE_CUBE_MAP_POSITIVE_Y
{
core::vector3df(-1.f, 1.f, -1.f),
core::vector3df(1.f, 1.f, -1.f),
core::vector3df(1.f, 1.f, 1.f),
core::vector3df(-1.f, 1.f, 1.f)
},
// GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
{
core::vector3df(-1.f, -1.f, 1.f),
core::vector3df(-1.f, -1.f, -1.f),
core::vector3df(1.f, -1.f, -1.f),
core::vector3df(1.f, -1.f, 1.f)
},
// GL_TEXTURE_CUBE_MAP_POSITIVE_Z
{
core::vector3df(-1.f, 1.f, 1.f),
core::vector3df(-1.f, -1.f, 1.f),
core::vector3df(1.f, -1.f, 1.f),
core::vector3df(1.f, 1.f, 1.f)
},
// GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
{
core::vector3df(1.f, 1.f, -1.f),
core::vector3df(-1.f, 1.f, -1.f),
core::vector3df(-1.f, -1.f, -1.f),
core::vector3df(1.f, -1.f, -1.f)
}
};
const core::vector3df texcoordData[4] = {
texcoordCubeData[layer][(flip) ? 3 : 0],
texcoordCubeData[layer][(flip) ? 2 : 1],
texcoordCubeData[layer][(flip) ? 1 : 2],
texcoordCubeData[layer][(flip) ? 0 : 3]
};
glTexCoordPointer(3, GL_FLOAT, sizeof(core::vector3df), texcoordData);
}
else
{
f32 modificator = (flip) ? 1.f : 0.f;
core::vector2df texcoordData[4] = {
core::vector2df(0.f, 0.f + modificator),
core::vector2df(1.f, 0.f + modificator),
core::vector2df(1.f, 1.f - modificator),
core::vector2df(0.f, 1.f - modificator)
};
glTexCoordPointer(2, GL_FLOAT, sizeof(core::vector2df), texcoordData);
}
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, Quad2DIndices); glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, Quad2DIndices);
} }
@ -2871,6 +2941,8 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
CacheHandler->setMatrixMode(GL_MODELVIEW); CacheHandler->setMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
glTranslatef(0.375f, 0.375f, 0.0f);
// Make sure we set first texture matrix // Make sure we set first texture matrix
CacheHandler->setActiveTexture(GL_TEXTURE0); CacheHandler->setActiveTexture(GL_TEXTURE0);

View File

@ -145,7 +145,7 @@ namespace video
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
const video::SColor* const colors = 0, bool useAlphaChannelOfTexture = false) _IRR_OVERRIDE_; const video::SColor* const colors = 0, bool useAlphaChannelOfTexture = false) _IRR_OVERRIDE_;
virtual void draw2DImage(const video::ITexture* texture, bool flip); virtual void draw2DImage(const video::ITexture* texture, u32 layer, bool flip);
//! draws a set of 2d images, using a color and the alpha channel of the //! draws a set of 2d images, using a color and the alpha channel of the
//! texture if desired. //! texture if desired.

View File

@ -76,7 +76,7 @@ CSoftwareTexture::~CSoftwareTexture()
//! lock function //! lock function
void* CSoftwareTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel) void* CSoftwareTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 layer)
{ {
return Image->getData(); return Image->getData();
} }

View File

@ -30,7 +30,7 @@ public:
virtual ~CSoftwareTexture(); virtual ~CSoftwareTexture();
//! lock function //! lock function
virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0) _IRR_OVERRIDE_; virtual void* lock(E_TEXTURE_LOCK_MODE mode = ETLM_READ_WRITE, u32 layer = 0) _IRR_OVERRIDE_;
//! unlock function //! unlock function
virtual void unlock() _IRR_OVERRIDE_; virtual void unlock() _IRR_OVERRIDE_;

View File

@ -38,11 +38,11 @@ public:
virtual ~CSoftwareTexture2(); virtual ~CSoftwareTexture2();
//! lock function //! lock function
virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0) _IRR_OVERRIDE_ virtual void* lock(E_TEXTURE_LOCK_MODE mode = ETLM_READ_WRITE, u32 layer = 0) _IRR_OVERRIDE_
{ {
if (Flags & GEN_MIPMAP) if (Flags & GEN_MIPMAP)
{ {
MipMapLOD = mipmapLevel; MipMapLOD = 0;
Size = MipMap[MipMapLOD]->getDimension(); Size = MipMap[MipMapLOD]->getDimension();
Pitch = MipMap[MipMapLOD]->getPitch(); Pitch = MipMap[MipMapLOD]->getPitch();
} }

View File

@ -8,6 +8,7 @@ using namespace core;
namespace namespace
{ {
//! check miplevels by visual test //! check miplevels by visual test
bool renderMipLevels(video::E_DRIVER_TYPE driverType) bool renderMipLevels(video::E_DRIVER_TYPE driverType)
{ {
@ -30,7 +31,7 @@ bool renderMipLevels(video::E_DRIVER_TYPE driverType)
logTestString("Testing driver %ls\n", driver->getName()); logTestString("Testing driver %ls\n", driver->getName());
scene::ISceneNode* n = smgr->addCubeSceneNode(); scene::ISceneNode* n = smgr->addCubeSceneNode();
scene::ISceneNode* n2 = smgr->addCubeSceneNode(10, 0, -1, core::vector3df(20,0,30), core::vector3df(0,45,0)); scene::ISceneNode* n2 = smgr->addCubeSceneNode(10, 0, -1, vector3df(20,0,30), vector3df(0,45,0));
// we use a main texture with blue on top and red below // we use a main texture with blue on top and red below
// and mipmap with pink on top and cyan below // and mipmap with pink on top and cyan below
@ -40,7 +41,7 @@ bool renderMipLevels(video::E_DRIVER_TYPE driverType)
u32 texData[16*16]; u32 texData[16*16];
for (u32 i=0; i<16*16; ++i) for (u32 i=0; i<16*16; ++i)
texData[i]=(i<8*16?0xff0000ff:0xffff0000); texData[i]=(i<8*16?0xff0000ff:0xffff0000);
video::IImage* image = driver->createImageFromData(video::ECF_A8R8G8B8, core::dimension2du(16,16), texData, false); video::IImage* image = driver->createImageFromData(video::ECF_A8R8G8B8, dimension2du(16,16), texData, false);
u32 mipdata[8*16]; u32 mipdata[8*16];
u32 index=0; u32 index=0;
for (u32 j=8; j>0; j/=2) for (u32 j=8; j>0; j/=2)
@ -68,7 +69,7 @@ bool renderMipLevels(video::E_DRIVER_TYPE driverType)
image->drop(); image->drop();
} }
(void)smgr->addCameraSceneNode(0, core::vector3df(10,0,-30)); (void)smgr->addCameraSceneNode(0, vector3df(10,0,-30));
driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,100,101,140)); driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,100,101,140));
smgr->drawAll(); smgr->drawAll();
@ -88,9 +89,8 @@ bool renderMipLevels(video::E_DRIVER_TYPE driverType)
return result; return result;
} }
//! Tests locking
//! Tests locking miplevels bool lockTexture(video::E_DRIVER_TYPE driverType)
bool lockAllMipLevels(video::E_DRIVER_TYPE driverType)
{ {
IrrlichtDevice *device = createDevice( driverType, dimension2d<u32>(160, 120), 32); IrrlichtDevice *device = createDevice( driverType, dimension2d<u32>(160, 120), 32);
if (!device) if (!device)
@ -107,188 +107,97 @@ bool lockAllMipLevels(video::E_DRIVER_TYPE driverType)
return true; return true;
} }
bool testCubemap = driver->queryFeature(video::EVDF_TEXTURE_CUBEMAP);
stabilizeScreenBackground(driver); stabilizeScreenBackground(driver);
logTestString("Testing driver %ls\n", driver->getName()); logTestString("Testing driver %ls\n", driver->getName());
scene::ISceneNode* n = smgr->addCubeSceneNode(); scene::ISceneNode* n = smgr->addCubeSceneNode();
scene::ISceneNode* n2 = smgr->addCubeSceneNode(10, 0, -1, vector3df(20, 0, 30), vector3df(0, 45, 0));
if (n) if (n && n2)
{ {
// create the texture and miplevels with distinct colors
u32 texData[16*16]; u32 texData[16*16];
for (u32 i=0; i<16*16; ++i) for (u32 i=0; i<16*16; ++i)
texData[i]=0xff0000ff-i; texData[i]=0xff0000ff-i;
video::IImage* image = driver->createImageFromData(video::ECF_A8R8G8B8, core::dimension2du(16,16), texData, false);
u32 mipdata[8*16]; // texture 2d
u32 index=0;
for (u32 j=8; j>0; j/=2) video::IImage* image = driver->createImageFromData(video::ECF_A8R8G8B8, dimension2du(16,16), texData, false);
video::ITexture* tex = driver->addTexture("tex2d", image);
if (!tex)
return false;
else
n->setMaterialTexture(0, tex);
// cubemap
if (testCubemap)
{ {
u32 val=(j==8?0x00ff00ff:(j==4?0x0000ffff:(j==2?0xc2c200ff:0x001212ff))); video::ITexture* texCube = driver->addTextureCubemap("texcube", image, image, image, image, image, image);
for (u32 i=0; i<j; ++i)
{ if (!texCube)
for (u32 k=0; k<j; ++k) testCubemap = false;
mipdata[index++]=val-i; else
} n2->setMaterialTexture(0, texCube);
} }
image->setMipMapsData(mipdata, false, true);
video::ITexture* tex = driver->addTexture("miptest", image);
if (!tex)
// is probably an error in the mipdata handling
return false;
else
n->setMaterialTexture(0, tex);
image->drop(); image->drop();
} }
(void)smgr->addCameraSceneNode(); smgr->addCameraSceneNode(0, vector3df(10, 0, -30));
driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,100,101,140)); driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,100,101,140));
smgr->drawAll(); smgr->drawAll();
driver->endScene(); driver->endScene();
video::ITexture* tex = driver->findTexture("miptest"); video::ITexture* tex = driver->findTexture("tex2d");
video::SColor* bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 0);
bool result = (bits[0].color==0xff0000ff);
tex->unlock();
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 1);
result &= (bits[0].color==0x00ff00ff);
tex->unlock();
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 2);
result &= (bits[0].color==0x0000ffff);
tex->unlock();
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 3);
result &= (bits[0].color==0xc2c200ff);
tex->unlock();
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 4);
result &= (bits[0].color==0x001212ff);
tex->unlock();
if (!result) video::SColor* bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE);
logTestString("mipmap lock after init with driver %ls failed.\n", driver->getName());
// test with updating a lower level, and reading upper and lower
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 3);
bits[0]=0xff00ff00; bits[0]=0xff00ff00;
bits[1]=0xff00ff00; bits[1]=0xff00ff00;
tex->unlock(); tex->unlock();
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 4);
result &= (bits[0].color==0x001212ff);
tex->unlock();
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 3);
result &= ((bits[0].color==0xff00ff00)&&(bits[2].color==0xc2c200fe));
tex->unlock();
if (!result)
logTestString("mipmap lock after mipmap write with driver %ls failed.\n", driver->getName());
// now test locking level 0
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 0);
bits[0]=0xff00ff00;
bits[1]=0xff00ff00;
tex->unlock();
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 4);
result &= (bits[0].color==0x001212ff);
tex->unlock();
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 0); bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 0);
result &= ((bits[0].color==0xff00ff00)&&(bits[2].color==0xff0000fd)); bool result = ((bits[0].color==0xff00ff00)&&(bits[2].color==0xff0000fd));
tex->unlock(); tex->unlock();
if (!result) if (!result)
logTestString("mipmap lock at level 0 after mipmap write with driver %ls failed.\n", driver->getName()); logTestString("texture 2d lock with driver %ls failed.\n", driver->getName());
else else
logTestString("Passed\n"); logTestString("Passed\n");
device->closeDevice(); if (testCubemap)
device->run();
device->drop();
return result;
}
//! Tests locking miplevels after texture was created with auto mipmap update
bool lockWithAutoMipmap(video::E_DRIVER_TYPE driverType)
{
IrrlichtDevice *device = createDevice( driverType, dimension2d<u32>(160, 120), 32);
if (!device)
return true; // Treat a failure to create a driver as benign; this saves a lot of #ifdefs
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager * smgr = device->getSceneManager();
if (!driver->queryFeature(video::EVDF_MIP_MAP))
{ {
device->closeDevice(); tex = driver->findTexture("texcube");
device->run();
device->drop();
return true;
}
stabilizeScreenBackground(driver); for (u32 i = 0; i < 6; ++i)
{
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, i);
bits[0] = 0xff00ff00;
bits[1] = 0xff00ff00;
tex->unlock();
}
logTestString("Testing driver %ls\n", driver->getName()); for (u32 i = 0; i < 6; ++i)
{
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, i);
u32 b0 = bits[0].color;
u32 b2 = bits[2].color;
scene::ISceneNode* n = smgr->addCubeSceneNode(); result &= ((bits[0].color == 0xff00ff00) && (bits[2].color == 0xff0000fd));
tex->unlock();
}
if (n) if (!result)
{ logTestString("texture cubemap lock with driver %ls failed.\n", driver->getName());
// create the texture
u32 texData[16*16];
for (u32 i=0; i<16*16; ++i)
texData[i]=0xff0000ff-i;
video::IImage* image = driver->createImageFromData(video::ECF_A8R8G8B8, core::dimension2du(16,16), texData, false);
video::ITexture* tex = driver->addTexture("miptest", image);
if (!tex)
return false;
else else
n->setMaterialTexture(0, tex); logTestString("Passed\n");
image->drop();
} }
(void)smgr->addCameraSceneNode();
driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,100,101,140));
smgr->drawAll();
driver->endScene();
video::ITexture* tex = driver->findTexture("miptest");
video::SColor* bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 0);
bool result = (bits[0].color==0xff0000ff);
tex->unlock();
if (!result)
logTestString("mipmap lock after init with driver %ls failed.\n", driver->getName());
// test with updating a lower level, and reading upper and lower
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 3);
bits[0]=0xff00ff00;
bits[1]=0xff00ff00;
tex->unlock();
// lock another texture just to invalidate caches in the driver
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 4);
tex->unlock();
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 3);
result &= ((bits[0].color==0xff00ff00)&&(bits[2].color!=0xff00ff00));
tex->unlock();
if (!result)
logTestString("mipmap lock after mipmap write with driver %ls failed.\n", driver->getName());
// now test locking level 0
bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 0);
bits[0]=0x00ff00ff;
bits[1]=0x00ff00ff;
tex->unlock();
bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 3);
result &= ((bits[0].color==0xff00ff00)&&(bits[2].color!=0xff00ff00));
tex->unlock();
if (!result)
logTestString("mipmap lock at level 0 after mipmap write with driver %ls failed.\n", driver->getName());
else
logTestString("Passed\n");
device->closeDevice(); device->closeDevice();
device->run(); device->run();
@ -296,16 +205,15 @@ bool lockWithAutoMipmap(video::E_DRIVER_TYPE driverType)
return result; return result;
} }
}
}
bool textureFeatures(void) bool textureFeatures(void)
{ {
bool result = true; bool result = true;
TestWithAllDrivers(renderMipLevels); TestWithAllDrivers(renderMipLevels);
TestWithAllDrivers(lockAllMipLevels); TestWithAllDrivers(lockTexture);
TestWithAllDrivers(lockWithAutoMipmap);
return result; return result;
} }