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
//! Automatically creates mip map levels for the textures.
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
//! compile these enumeration values to 32 bit.
ETCF_FORCE_32_BIT_DO_NOT_USE = 0x7fffffff
......
......@@ -246,8 +246,8 @@ void CColorConverter::convert_A1R5G5B5toR8G8B8(const void* sP, s32 sN, void* dP)
for (s32 x = 0; x < sN; ++x)
{
dB[2] = (*sB & 0x7c) << 9;
dB[1] = (*sB & 0x3e) << 6;
dB[2] = (*sB & 0x7c00) >> 7;
dB[1] = (*sB & 0x03e0) >> 2;
dB[0] = (*sB & 0x1f) << 3;
sB += 1;
......@@ -262,8 +262,8 @@ void CColorConverter::convert_A1R5G5B5toB8G8R8(const void* sP, s32 sN, void* dP)
for (s32 x = 0; x < sN; ++x)
{
dB[0] = (*sB & 0x7c) << 9;
dB[1] = (*sB & 0x3e) << 6;
dB[0] = (*sB & 0x7c00) >> 7;
dB[1] = (*sB & 0x03e0) >> 2;
dB[2] = (*sB & 0x1f) << 3;
sB += 1;
......@@ -302,9 +302,9 @@ void CColorConverter::convert_A8R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP)
for (s32 x = 0; x < sN; ++x)
{
// sB[3] is alpha
dB[0] = sB[0];
dB[0] = sB[2];
dB[1] = sB[1];
dB[2] = sB[2];
dB[2] = sB[0];
sB += 4;
dB += 3;
......@@ -319,9 +319,9 @@ void CColorConverter::convert_A8R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP)
for (s32 x = 0; x < sN; ++x)
{
// sB[3] is alpha
dB[0] = sB[2];
dB[0] = sB[0];
dB[1] = sB[1];
dB[2] = sB[0];
dB[2] = sB[2];
sB += 4;
dB += 3;
......
......@@ -59,7 +59,7 @@ HasMipMaps(false), IsRenderTarget(false)
setDebugName("CD3D8Texture");
#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;
if (Device)
......@@ -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
bool CD3D8Texture::createTexture(u32 flags)
......@@ -137,21 +153,32 @@ bool CD3D8Texture::createTexture(u32 flags)
case ETCF_OPTIMIZED_FOR_SPEED:
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,
mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all)
0, format, D3DPOOL_MANAGED, &Texture);
if (FAILED(hr) && format == D3DFMT_A8R8G8B8)
if (FAILED(hr))
{
// try brute force 16 bit
format = D3DFMT_A1R5G5B5;
if (format == D3DFMT_A8R8G8B8)
format = D3DFMT_A1R5G5B5;
else if (format == D3DFMT_R8G8B8)
format = D3DFMT_R5G6B5;
else
return false;
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);
}
......@@ -172,88 +199,36 @@ bool CD3D8Texture::copyTexture()
TextureSize.Width = desc.Width;
TextureSize.Height = desc.Height;
if (desc.Format == D3DFMT_A1R5G5B5)
return copyTo16BitTexture();
else
if (desc.Format == D3DFMT_A8R8G8B8)
return copyTo32BitTexture();
else
os::Printer::log("CD3D8Texture: Unsupported D3D8 hardware texture format", ELL_ERROR);
}
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;
}
if ((desc.Format == D3DFMT_A1R5G5B5) || (desc.Format == D3DFMT_A8R8G8B8))
{
D3DLOCKED_RECT rect;
HRESULT hr = Texture->LockRect(0, &rect, 0, 0);
if (FAILED(hr))
{
os::Printer::log("Could not lock D3D8 Texture.", ELL_ERROR);
return false;
}
Pitch = rect.Pitch;
Image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ColorFormat, Pitch);
//! optimized for 16 bit to 16 copy.
bool CD3D8Texture::copyTo16BitTexture()
{
D3DLOCKED_RECT rect;
HRESULT hr = Texture->LockRect(0, &rect, 0, 0);
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);
if (FAILED(hr))
{
os::Printer::log("Could not unlock D3D8 Texture.", ELL_ERROR);
return false;
}
hr = Texture->UnlockRect(0);
if (FAILED(hr))
{
os::Printer::log("Could not unlock DIRECT3D8 16 bit Texture.", ELL_ERROR);
return false;
return true;
}
else
os::Printer::log("CD3D8Texture: Unsupported D3D8 hardware texture format", ELL_ERROR);
}
return true;
}
//! destructor
CD3D8Texture::~CD3D8Texture()
{
if (Device)
Device->Release();
if (Image)
Image->drop();
if (Texture)
Texture->Release();
if (RTTSurface)
RTTSurface->Release();
}
//! lock function
void* CD3D8Texture::lock()
{
......
......@@ -89,12 +89,6 @@ private:
//! convert color formats
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);
void copy16BitMipMap(char* src, char* tgt,
......
......@@ -58,7 +58,7 @@ HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(false)
setDebugName("CD3D9Texture");
#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;
if (Device)
......@@ -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()
{
TextureSize.Width = getTextureSizeFromImageSize(TextureSize.Width);
......@@ -284,8 +301,15 @@ bool CD3D9Texture::createTexture(u32 flags)
default:
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;
......@@ -304,14 +328,18 @@ bool CD3D9Texture::createTexture(u32 flags)
usage, // usage
format, D3DPOOL_MANAGED , &Texture, NULL);
if (FAILED(hr) && format == D3DFMT_A8R8G8B8)
if (FAILED(hr))
{
// try brute force 16 bit
format = D3DFMT_A1R5G5B5;
if (format == D3DFMT_A8R8G8B8)
format = D3DFMT_A1R5G5B5;
else if (format == D3DFMT_R8G8B8)
format = D3DFMT_R5G6B5;
else
return false;
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);
}
......@@ -373,87 +401,36 @@ bool CD3D9Texture::copyTexture()
TextureSize.Width = desc.Width;
TextureSize.Height = desc.Height;
if (desc.Format == D3DFMT_A1R5G5B5)
return copyTo16BitTexture();
else
if (desc.Format == D3DFMT_A8R8G8B8)
return copyTo32BitTexture();
else
os::Printer::log("CD3D9Texture: Unsupported D3D9 hardware texture format", ELL_ERROR);
}
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;
}
if ((desc.Format == D3DFMT_A1R5G5B5) || (desc.Format == D3DFMT_A8R8G8B8))
{
D3DLOCKED_RECT rect;
HRESULT hr = Texture->LockRect(0, &rect, 0, 0);
if (FAILED(hr))
{
os::Printer::log("Could not lock D3D9 Texture.", ELL_ERROR);
return false;
}
Pitch = rect.Pitch;
Image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ColorFormat, Pitch);
//! optimized for 16 bit to 16 copy.
bool CD3D9Texture::copyTo16BitTexture()
{
D3DLOCKED_RECT rect;
HRESULT hr = Texture->LockRect(0, &rect, 0, 0);
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);
if (FAILED(hr))
{
os::Printer::log("Could not unlock D3D9 Texture.", ELL_ERROR);
return false;
}
hr = Texture->UnlockRect(0);
if (FAILED(hr))
{
os::Printer::log("Could not unlock DIRECT3D9 16 bit Texture.", ELL_ERROR);
return false;
return true;
}
else
os::Printer::log("CD3D9Texture: Unsupported D3D9 hardware texture format", ELL_ERROR);
}
return true;
}
//! destructor
CD3D9Texture::~CD3D9Texture()
{
if (Device)
Device->Release();
if (Image)
Image->drop();
if (Texture)
Texture->Release();
if (RTTSurface)
RTTSurface->Release();
}
//! lock function
void* CD3D9Texture::lock()
{
......
......@@ -85,12 +85,6 @@ private:
//! copies the image to the texture
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.
D3DFORMAT getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const;
......
......@@ -1164,7 +1164,7 @@ void COpenGLDriver::setMaterial(const SMaterial& 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 ),
material.getTextureMatrix(i));
......
......@@ -189,6 +189,20 @@ ECOLOR_FORMAT COpenGLTexture::getBestColorFormat(ECOLOR_FORMAT format)
destFormat = ECF_A1R5G5B5;
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;
}
......@@ -247,12 +261,12 @@ void COpenGLTexture::copyTexture(bool newTexture)
break;
case ECF_R5G6B5:
InternalFormat=GL_RGB;
PixelFormat=GL_RGB;
PixelType=GL_UNSIGNED_SHORT_5_6_5;
PixelFormat=GL_BGR;
PixelType=GL_UNSIGNED_SHORT_5_6_5_REV;
break;
case ECF_R8G8B8:
InternalFormat=GL_RGB8;
PixelFormat=GL_RGB;
InternalFormat=GL_RGB;
PixelFormat=GL_BGR;
PixelType=GL_UNSIGNED_BYTE;
break;
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