Commit b9f96332 authored by hybrid's avatar hybrid

Added a new texture creation flag for specifying the desired texture format....

Added a new texture creation flag for specifying the desired texture format. The new flag chooses a non-alpha channel texture format. This will save some texture memory (one fourth for 32bit textures).
Fixed another COpenGL render state bug.
Fixed several color conversion methods.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@801 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 1d6a992e
...@@ -59,6 +59,9 @@ enum E_TEXTURE_CREATION_FLAG ...@@ -59,6 +59,9 @@ enum E_TEXTURE_CREATION_FLAG
//! Automatically creates mip map levels for the textures. //! Automatically creates mip map levels for the textures.
ETCF_CREATE_MIP_MAPS = 0x00000010, ETCF_CREATE_MIP_MAPS = 0x00000010,
//! Discard any alpha layer and use non-alpha color format.
ETCF_NO_ALPHA_CHANNEL = 0x00000020,
//! This flag is never used, it only forces the compiler to //! This flag is never used, it only forces the compiler to
//! compile these enumeration values to 32 bit. //! compile these enumeration values to 32 bit.
ETCF_FORCE_32_BIT_DO_NOT_USE = 0x7fffffff ETCF_FORCE_32_BIT_DO_NOT_USE = 0x7fffffff
......
...@@ -246,8 +246,8 @@ void CColorConverter::convert_A1R5G5B5toR8G8B8(const void* sP, s32 sN, void* dP) ...@@ -246,8 +246,8 @@ void CColorConverter::convert_A1R5G5B5toR8G8B8(const void* sP, s32 sN, void* dP)
for (s32 x = 0; x < sN; ++x) for (s32 x = 0; x < sN; ++x)
{ {
dB[2] = (*sB & 0x7c) << 9; dB[2] = (*sB & 0x7c00) >> 7;
dB[1] = (*sB & 0x3e) << 6; dB[1] = (*sB & 0x03e0) >> 2;
dB[0] = (*sB & 0x1f) << 3; dB[0] = (*sB & 0x1f) << 3;
sB += 1; sB += 1;
...@@ -262,8 +262,8 @@ void CColorConverter::convert_A1R5G5B5toB8G8R8(const void* sP, s32 sN, void* dP) ...@@ -262,8 +262,8 @@ void CColorConverter::convert_A1R5G5B5toB8G8R8(const void* sP, s32 sN, void* dP)
for (s32 x = 0; x < sN; ++x) for (s32 x = 0; x < sN; ++x)
{ {
dB[0] = (*sB & 0x7c) << 9; dB[0] = (*sB & 0x7c00) >> 7;
dB[1] = (*sB & 0x3e) << 6; dB[1] = (*sB & 0x03e0) >> 2;
dB[2] = (*sB & 0x1f) << 3; dB[2] = (*sB & 0x1f) << 3;
sB += 1; sB += 1;
...@@ -302,9 +302,9 @@ void CColorConverter::convert_A8R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP) ...@@ -302,9 +302,9 @@ void CColorConverter::convert_A8R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP)
for (s32 x = 0; x < sN; ++x) for (s32 x = 0; x < sN; ++x)
{ {
// sB[3] is alpha // sB[3] is alpha
dB[0] = sB[0]; dB[0] = sB[2];
dB[1] = sB[1]; dB[1] = sB[1];
dB[2] = sB[2]; dB[2] = sB[0];
sB += 4; sB += 4;
dB += 3; dB += 3;
...@@ -319,9 +319,9 @@ void CColorConverter::convert_A8R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP) ...@@ -319,9 +319,9 @@ void CColorConverter::convert_A8R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP)
for (s32 x = 0; x < sN; ++x) for (s32 x = 0; x < sN; ++x)
{ {
// sB[3] is alpha // sB[3] is alpha
dB[0] = sB[2]; dB[0] = sB[0];
dB[1] = sB[1]; dB[1] = sB[1];
dB[2] = sB[0]; dB[2] = sB[2];
sB += 4; sB += 4;
dB += 3; dB += 3;
......
...@@ -59,7 +59,7 @@ HasMipMaps(false), IsRenderTarget(false) ...@@ -59,7 +59,7 @@ HasMipMaps(false), IsRenderTarget(false)
setDebugName("CD3D8Texture"); setDebugName("CD3D8Texture");
#endif #endif
bool generateMipLevels = (flags & video::ETCF_CREATE_MIP_MAPS) != 0; const bool generateMipLevels = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
Device=driver->getExposedVideoData().D3D8.D3DDev8; Device=driver->getExposedVideoData().D3D8.D3DDev8;
if (Device) if (Device)
...@@ -97,6 +97,22 @@ HasMipMaps(false), IsRenderTarget(false) ...@@ -97,6 +97,22 @@ HasMipMaps(false), IsRenderTarget(false)
} }
//! destructor
CD3D8Texture::~CD3D8Texture()
{
if (Device)
Device->Release();
if (Image)
Image->drop();
if (Texture)
Texture->Release();
if (RTTSurface)
RTTSurface->Release();
}
//! creates the hardware texture //! creates the hardware texture
bool CD3D8Texture::createTexture(u32 flags) bool CD3D8Texture::createTexture(u32 flags)
...@@ -137,21 +153,32 @@ bool CD3D8Texture::createTexture(u32 flags) ...@@ -137,21 +153,32 @@ bool CD3D8Texture::createTexture(u32 flags)
case ETCF_OPTIMIZED_FOR_SPEED: case ETCF_OPTIMIZED_FOR_SPEED:
format = D3DFMT_A1R5G5B5; break; format = D3DFMT_A1R5G5B5; break;
} }
if (Driver->getTextureCreationFlag(video::ETCF_NO_ALPHA_CHANNEL))
{
if (format == D3DFMT_A8R8G8B8)
format = D3DFMT_R8G8B8;
else if (format == D3DFMT_A1R5G5B5)
format = D3DFMT_R5G6B5;
}
bool mipmaps = (flags & video::ETCF_CREATE_MIP_MAPS) != 0; const bool mipmaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
hr = Device->CreateTexture(optSize.Width, optSize.Height, hr = Device->CreateTexture(optSize.Width, optSize.Height,
mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all) mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all)
0, format, D3DPOOL_MANAGED, &Texture); 0, format, D3DPOOL_MANAGED, &Texture);
if (FAILED(hr) && format == D3DFMT_A8R8G8B8) if (FAILED(hr))
{ {
// try brute force 16 bit // try brute force 16 bit
if (format == D3DFMT_A8R8G8B8)
format = D3DFMT_A1R5G5B5; format = D3DFMT_A1R5G5B5;
else if (format == D3DFMT_R8G8B8)
format = D3DFMT_R5G6B5;
else
return false;
hr = Device->CreateTexture(optSize.Width, optSize.Height, hr = Device->CreateTexture(optSize.Width, optSize.Height,
(flags & ETCF_CREATE_MIP_MAPS) ? 0 : 1, // number of mipmaplevels (0 = automatic all) mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all)
0, D3DFMT_A1R5G5B5, D3DPOOL_MANAGED, &Texture); 0, D3DFMT_A1R5G5B5, D3DPOOL_MANAGED, &Texture);
} }
...@@ -172,88 +199,36 @@ bool CD3D8Texture::copyTexture() ...@@ -172,88 +199,36 @@ bool CD3D8Texture::copyTexture()
TextureSize.Width = desc.Width; TextureSize.Width = desc.Width;
TextureSize.Height = desc.Height; TextureSize.Height = desc.Height;
if (desc.Format == D3DFMT_A1R5G5B5) if ((desc.Format == D3DFMT_A1R5G5B5) || (desc.Format == D3DFMT_A8R8G8B8))
return copyTo16BitTexture(); {
else D3DLOCKED_RECT rect;
if (desc.Format == D3DFMT_A8R8G8B8) HRESULT hr = Texture->LockRect(0, &rect, 0, 0);
return copyTo32BitTexture(); if (FAILED(hr))
else {
os::Printer::log("CD3D8Texture: Unsupported D3D8 hardware texture format", ELL_ERROR); os::Printer::log("Could not lock D3D8 Texture.", ELL_ERROR);
} return false;
}
return true;
}
//! copies texture to 32 bit hardware texture
bool CD3D8Texture::copyTo32BitTexture()
{
D3DLOCKED_RECT rect;
HRESULT hr = Texture->LockRect(0, &rect, 0, 0);
if (FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D8 32 bit Texture.", ELL_ERROR);
return false;
}
Pitch = rect.Pitch;
Image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ECF_A8R8G8B8, Pitch);
hr = Texture->UnlockRect(0);
if (FAILED(hr))
{
os::Printer::log("Could not unlock DIRECT3D8 Texture.", ELL_ERROR);
return false;
}
return true;
}
Pitch = rect.Pitch;
Image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ColorFormat, Pitch);
//! optimized for 16 bit to 16 copy. hr = Texture->UnlockRect(0);
bool CD3D8Texture::copyTo16BitTexture() if (FAILED(hr))
{ {
D3DLOCKED_RECT rect; os::Printer::log("Could not unlock D3D8 Texture.", ELL_ERROR);
HRESULT hr = Texture->LockRect(0, &rect, 0, 0); return false;
if (FAILED(hr)) }
{
os::Printer::log("Could not lock DIRECT3D8 16 bit Texture.", ELL_ERROR);
return false;
}
Pitch = rect.Pitch;
Image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ECF_A1R5G5B5, Pitch);
hr = Texture->UnlockRect(0); return true;
if (FAILED(hr)) }
{ else
os::Printer::log("Could not unlock DIRECT3D8 16 bit Texture.", ELL_ERROR); os::Printer::log("CD3D8Texture: Unsupported D3D8 hardware texture format", ELL_ERROR);
return false;
} }
return true; return true;
} }
//! destructor
CD3D8Texture::~CD3D8Texture()
{
if (Device)
Device->Release();
if (Image)
Image->drop();
if (Texture)
Texture->Release();
if (RTTSurface)
RTTSurface->Release();
}
//! lock function //! lock function
void* CD3D8Texture::lock() void* CD3D8Texture::lock()
{ {
......
...@@ -89,12 +89,6 @@ private: ...@@ -89,12 +89,6 @@ private:
//! convert color formats //! convert color formats
ECOLOR_FORMAT getColorFormatFromD3DFormat(D3DFORMAT format); ECOLOR_FORMAT getColorFormatFromD3DFormat(D3DFORMAT format);
//! optimized for 16 bit to 16 copy.
bool copyTo16BitTexture();
//! copies texture to 32 bit hardware texture
bool copyTo32BitTexture();
bool createMipMaps(u32 level=1); bool createMipMaps(u32 level=1);
void copy16BitMipMap(char* src, char* tgt, void copy16BitMipMap(char* src, char* tgt,
......
...@@ -58,7 +58,7 @@ HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(false) ...@@ -58,7 +58,7 @@ HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(false)
setDebugName("CD3D9Texture"); setDebugName("CD3D9Texture");
#endif #endif
bool generateMipLevels = (flags & video::ETCF_CREATE_MIP_MAPS) != 0; const bool generateMipLevels = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
Device=driver->getExposedVideoData().D3D9.D3DDev9; Device=driver->getExposedVideoData().D3D9.D3DDev9;
if (Device) if (Device)
...@@ -95,6 +95,23 @@ HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(false) ...@@ -95,6 +95,23 @@ HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(false)
} }
//! destructor
CD3D9Texture::~CD3D9Texture()
{
if (Device)
Device->Release();
if (Image)
Image->drop();
if (Texture)
Texture->Release();
if (RTTSurface)
RTTSurface->Release();
}
void CD3D9Texture::createRenderTarget() void CD3D9Texture::createRenderTarget()
{ {
TextureSize.Width = getTextureSizeFromImageSize(TextureSize.Width); TextureSize.Width = getTextureSizeFromImageSize(TextureSize.Width);
...@@ -284,8 +301,15 @@ bool CD3D9Texture::createTexture(u32 flags) ...@@ -284,8 +301,15 @@ bool CD3D9Texture::createTexture(u32 flags)
default: default:
break; break;
} }
if (Driver->getTextureCreationFlag(video::ETCF_NO_ALPHA_CHANNEL))
{
if (format == D3DFMT_A8R8G8B8)
format = D3DFMT_R8G8B8;
else if (format == D3DFMT_A1R5G5B5)
format = D3DFMT_R5G6B5;
}
bool mipmaps = (flags & video::ETCF_CREATE_MIP_MAPS) != 0; const bool mipmaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
DWORD usage = 0; DWORD usage = 0;
...@@ -304,14 +328,18 @@ bool CD3D9Texture::createTexture(u32 flags) ...@@ -304,14 +328,18 @@ bool CD3D9Texture::createTexture(u32 flags)
usage, // usage usage, // usage
format, D3DPOOL_MANAGED , &Texture, NULL); format, D3DPOOL_MANAGED , &Texture, NULL);
if (FAILED(hr) && format == D3DFMT_A8R8G8B8) if (FAILED(hr))
{ {
// try brute force 16 bit // try brute force 16 bit
if (format == D3DFMT_A8R8G8B8)
format = D3DFMT_A1R5G5B5; format = D3DFMT_A1R5G5B5;
else if (format == D3DFMT_R8G8B8)
format = D3DFMT_R5G6B5;
else
return false;
hr = Device->CreateTexture(optSize.Width, optSize.Height, hr = Device->CreateTexture(optSize.Width, optSize.Height,
(flags & ETCF_CREATE_MIP_MAPS) ? 0 : 1, // number of mipmaplevels (0 = automatic all) mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all)
0, D3DFMT_A1R5G5B5, D3DPOOL_MANAGED, &Texture, NULL); 0, D3DFMT_A1R5G5B5, D3DPOOL_MANAGED, &Texture, NULL);
} }
...@@ -373,87 +401,36 @@ bool CD3D9Texture::copyTexture() ...@@ -373,87 +401,36 @@ bool CD3D9Texture::copyTexture()
TextureSize.Width = desc.Width; TextureSize.Width = desc.Width;
TextureSize.Height = desc.Height; TextureSize.Height = desc.Height;
if (desc.Format == D3DFMT_A1R5G5B5) if ((desc.Format == D3DFMT_A1R5G5B5) || (desc.Format == D3DFMT_A8R8G8B8))
return copyTo16BitTexture(); {
else D3DLOCKED_RECT rect;
if (desc.Format == D3DFMT_A8R8G8B8) HRESULT hr = Texture->LockRect(0, &rect, 0, 0);
return copyTo32BitTexture(); if (FAILED(hr))
else {
os::Printer::log("CD3D9Texture: Unsupported D3D9 hardware texture format", ELL_ERROR); os::Printer::log("Could not lock D3D9 Texture.", ELL_ERROR);
} return false;
}
return true;
}
//! copies texture to 32 bit hardware texture
bool CD3D9Texture::copyTo32BitTexture()
{
D3DLOCKED_RECT rect;
HRESULT hr = Texture->LockRect(0, &rect, 0, 0);
if (FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D9 32 bit Texture.", ELL_ERROR);
return false;
}
Pitch = rect.Pitch;
Image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ECF_A8R8G8B8, Pitch);
hr = Texture->UnlockRect(0);
if (FAILED(hr))
{
os::Printer::log("Could not unlock DIRECT3D9 Texture.", ELL_ERROR);
return false;
}
return true;
}
Pitch = rect.Pitch;
Image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ColorFormat, Pitch);
//! optimized for 16 bit to 16 copy. hr = Texture->UnlockRect(0);
bool CD3D9Texture::copyTo16BitTexture() if (FAILED(hr))
{ {
D3DLOCKED_RECT rect; os::Printer::log("Could not unlock D3D9 Texture.", ELL_ERROR);
HRESULT hr = Texture->LockRect(0, &rect, 0, 0); return false;
if (FAILED(hr)) }
{
os::Printer::log("Could not lock DIRECT3D9 16 bit Texture.", ELL_ERROR);
return false;
}
Pitch = rect.Pitch;
Image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ECF_A1R5G5B5, Pitch);
hr = Texture->UnlockRect(0); return true;
if (FAILED(hr)) }
{ else
os::Printer::log("Could not unlock DIRECT3D9 16 bit Texture.", ELL_ERROR); os::Printer::log("CD3D9Texture: Unsupported D3D9 hardware texture format", ELL_ERROR);
return false;
} }
return true; return true;
} }
//! destructor
CD3D9Texture::~CD3D9Texture()
{
if (Device)
Device->Release();
if (Image)
Image->drop();
if (Texture)
Texture->Release();
if (RTTSurface)
RTTSurface->Release();
}
//! lock function //! lock function
void* CD3D9Texture::lock() void* CD3D9Texture::lock()
{ {
......
...@@ -85,12 +85,6 @@ private: ...@@ -85,12 +85,6 @@ private:
//! copies the image to the texture //! copies the image to the texture
bool copyTexture(); bool copyTexture();
//! optimized for 16 bit to 16 copy.
bool copyTo16BitTexture();
//! copies texture to 32 bit hardware texture
bool copyTo32BitTexture();
//! Get D3D color format from Irrlicht color format. //! Get D3D color format from Irrlicht color format.
D3DFORMAT getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const; D3DFORMAT getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const;
......
...@@ -1164,7 +1164,7 @@ void COpenGLDriver::setMaterial(const SMaterial& material) ...@@ -1164,7 +1164,7 @@ void COpenGLDriver::setMaterial(const SMaterial& material)
{ {
Material = material; Material = material;
for (s32 i = 0; i < MaxTextureUnits; ++i) for (s32 i = MaxTextureUnits-1; i>= 0; --i)
{ {
setTransform ((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ), setTransform ((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ),
material.getTextureMatrix(i)); material.getTextureMatrix(i));
......
...@@ -189,6 +189,20 @@ ECOLOR_FORMAT COpenGLTexture::getBestColorFormat(ECOLOR_FORMAT format) ...@@ -189,6 +189,20 @@ ECOLOR_FORMAT COpenGLTexture::getBestColorFormat(ECOLOR_FORMAT format)
destFormat = ECF_A1R5G5B5; destFormat = ECF_A1R5G5B5;
break; break;
} }
if (Driver->getTextureCreationFlag(ETCF_NO_ALPHA_CHANNEL))
{
switch (format)
{
case ECF_A1R5G5B5:
destFormat = ECF_R5G6B5;
break;
case ECF_A8R8G8B8:
destFormat = ECF_R8G8B8;
break;
default:
break;
}
}
return destFormat; return destFormat;
} }
...@@ -247,12 +261,12 @@ void COpenGLTexture::copyTexture(bool newTexture) ...@@ -247,12 +261,12 @@ void COpenGLTexture::copyTexture(bool newTexture)
break; break;
case ECF_R5G6B5: case ECF_R5G6B5:
InternalFormat=GL_RGB; InternalFormat=GL_RGB;
PixelFormat=GL_RGB; PixelFormat=GL_BGR;
PixelType=GL_UNSIGNED_SHORT_5_6_5; PixelType=GL_UNSIGNED_SHORT_5_6_5_REV;
break; break;
case ECF_R8G8B8: case ECF_R8G8B8:
InternalFormat=GL_RGB8; InternalFormat=GL_RGB;
PixelFormat=GL_RGB; PixelFormat=GL_BGR;
PixelType=GL_UNSIGNED_BYTE; PixelType=GL_UNSIGNED_BYTE;
break; break;
case ECF_A8R8G8B8: case ECF_A8R8G8B8:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment