Fixed the d3d9 mipmapping for new formats. Still not a nice solution, though. Also enabled hardware mipmap update for d3d9 with an extra check for format support.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@837 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2007-08-14 15:10:28 +00:00
parent 0aa958f441
commit 8f34efc3f4
5 changed files with 56 additions and 52 deletions

View File

@ -569,12 +569,6 @@ namespace video
/** \param light: Data specifying the dynamic light. */ /** \param light: Data specifying the dynamic light. */
virtual void addDynamicLight(const SLight& light) = 0; virtual void addDynamicLight(const SLight& light) = 0;
//! Sets the dynamic ambient light color.
/** The default color is
(0,0,0,0) which means it is dark.
\param color: New color of the ambient light. */
virtual void setAmbientLight(const SColorf& color) = 0;
//! Returns the maximal amount of dynamic lights the device can handle //! Returns the maximal amount of dynamic lights the device can handle
/** \return Maximal amount of dynamic lights. */ /** \return Maximal amount of dynamic lights. */
virtual u32 getMaximalDynamicLightAmount() = 0; virtual u32 getMaximalDynamicLightAmount() = 0;
@ -785,6 +779,11 @@ namespace video
//! \param enable: If true, enable the clipping plane else disable it. //! \param enable: If true, enable the clipping plane else disable it.
virtual void enableClipPlane(u32 index, bool enable) = 0; virtual void enableClipPlane(u32 index, bool enable) = 0;
//! Sets the driver's ambient light color.
/** This color is set in the scene manager, see ISceneManager.h.
\param color: New color of the ambient light. */
virtual void setAmbientLight(const SColorf& color) = 0;
}; };
} // end namespace video } // end namespace video

View File

@ -69,7 +69,7 @@ namespace video
//! Returns A8R8G8B8 Color from A1R5G5B5 color //! Returns A8R8G8B8 Color from A1R5G5B5 color
//! build a nicer 32 Bit Color by extending dest lower bits with source high bits //! build a nicer 32 Bit Color by extending dest lower bits with source high bits
inline u32 A1R5G5B5toA8R8G8B8(u32 color) inline u32 A1R5G5B5toA8R8G8B8(u16 color)
{ {
return ( (( -( (s32) color & 0x00008000 ) >> (s32) 31 ) & 0xFF000000 ) | return ( (( -( (s32) color & 0x00008000 ) >> (s32) 31 ) & 0xFF000000 ) |
(( color & 0x00007C00 ) << 9) | (( color & 0x00007000 ) << 4) | (( color & 0x00007C00 ) << 9) | (( color & 0x00007000 ) << 4) |
@ -134,7 +134,7 @@ namespace video
return (color & 0x1F); return (color & 0x1F);
} }
//! Returns the red component from A1R5G5B5 color. //! Returns the red component from A1R5G5B5 color.
//! Shift left by 3 to get 8 bit value. //! Shift left by 3 to get 8 bit value.
inline s32 getRedSigned(u16 color) inline s32 getRedSigned(u16 color)
{ {
@ -285,7 +285,7 @@ namespace video
//! \return Returns true if the colors are different, and false if they are the same. //! \return Returns true if the colors are different, and false if they are the same.
inline bool operator!=(const SColor& other) const { return other.color != color; } inline bool operator!=(const SColor& other) const { return other.color != color; }
//! Adds two lights //! Adds two colors
inline SColor operator+(const SColor& other) const inline SColor operator+(const SColor& other) const
{ {
s32 a = getAlpha() + other.getAlpha(); s32 a = getAlpha() + other.getAlpha();

View File

@ -540,6 +540,8 @@ bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature)
return (Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0; return (Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0;
case EVDF_MIP_MAP: case EVDF_MIP_MAP:
return (Caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) != 0; return (Caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) != 0;
case EVDF_MIP_MAP_AUTO_UPDATE:
return (Caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0;
case EVDF_STENCIL_BUFFER: case EVDF_STENCIL_BUFFER:
return StencilBuffer && Caps.StencilCaps; return StencilBuffer && Caps.StencilCaps;
case EVDF_VERTEX_SHADER_1_1: case EVDF_VERTEX_SHADER_1_1:

View File

@ -76,8 +76,7 @@ HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(false)
#ifdef _IRR_USE_D3DXFilterTexture_ #ifdef _IRR_USE_D3DXFilterTexture_
// The D3DXFilterTexture function seems to get linked wrong when // The D3DXFilterTexture function seems to get linked wrong when
// compiling with both D3D8 and 9, causing it not to work in the D3D9 device. // compiling with both D3D8 and 9, causing it not to work in the D3D9 device.
// So mipmapgeneration is replaced with my own bad generation in d3d 8 when // So mipmapgeneration is replaced with my own bad generation
// compiling with both D3D 8 and 9.
HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT, D3DX_DEFAULT); HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT, D3DX_DEFAULT);
if (FAILED(hr)) if (FAILED(hr))
os::Printer::log("Could not create direct3d mip map levels.", ELL_WARNING); os::Printer::log("Could not create direct3d mip map levels.", ELL_WARNING);
@ -173,12 +172,7 @@ bool CD3D9Texture::createMipMaps(u32 level)
Texture->GenerateMipSubLevels(); Texture->GenerateMipSubLevels();
return true; return true;
} }
//os::Printer::log("manual mipmap"); // os::Printer::log("manual mipmap");
// The D3DXFilterTexture function seems to get linked wrong when
// compiling with both D3D8 and 9, causing it not to work in the D3D9 device.
// So mipmapgeneration is replaced with my own bad generation here when
// compiling with both D3D 8 and 9.
IDirect3DSurface9* upperSurface = 0; IDirect3DSurface9* upperSurface = 0;
IDirect3DSurface9* lowerSurface = 0; IDirect3DSurface9* lowerSurface = 0;
@ -256,7 +250,7 @@ bool CD3D9Texture::createMipMaps(u32 level)
upperSurface->Release(); upperSurface->Release();
lowerSurface->Release(); lowerSurface->Release();
if (!result || upperDesc.Width < 3 || upperDesc.Height < 3) if (!result || (upperDesc.Width < 3 && upperDesc.Height < 3))
return result; // stop generating levels return result; // stop generating levels
// generate next level // generate next level
@ -306,7 +300,7 @@ bool CD3D9Texture::createTexture(u32 flags)
default: default:
break; break;
} }
if (false && Driver->getTextureCreationFlag(video::ETCF_NO_ALPHA_CHANNEL)) if (Driver->getTextureCreationFlag(video::ETCF_NO_ALPHA_CHANNEL))
{ {
if (format == D3DFMT_A8R8G8B8) if (format == D3DFMT_A8R8G8B8)
format = D3DFMT_R8G8B8; format = D3DFMT_R8G8B8;
@ -318,15 +312,19 @@ bool CD3D9Texture::createTexture(u32 flags)
DWORD usage = 0; DWORD usage = 0;
// This enables hardware mip map generation. Disabled because // This enables hardware mip map generation.
// some cards or drivers seem to have problems with this. if (mipmaps && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE))
// D3DCAPS9 caps; {
// Device->GetDeviceCaps(&caps); LPDIRECT3D9 intf = Driver->getExposedVideoData().D3D9.D3D9;
// if (caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) D3DDISPLAYMODE d3ddm;
// { intf->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
// usage = D3DUSAGE_AUTOGENMIPMAP;
// HardwareMipMaps = true; if (D3D_OK==intf->CheckDeviceFormat(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,d3ddm.Format,D3DUSAGE_AUTOGENMIPMAP,D3DRTYPE_TEXTURE,format))
//} {
usage = D3DUSAGE_AUTOGENMIPMAP;
HardwareMipMaps = true;
}
}
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)
@ -336,6 +334,7 @@ bool CD3D9Texture::createTexture(u32 flags)
if (FAILED(hr)) if (FAILED(hr))
{ {
// try brute force 16 bit // try brute force 16 bit
HardwareMipMaps = false;
if (format == D3DFMT_A8R8G8B8) if (format == D3DFMT_A8R8G8B8)
format = D3DFMT_A1R5G5B5; format = D3DFMT_A1R5G5B5;
else if (format == D3DFMT_R8G8B8) else if (format == D3DFMT_R8G8B8)
@ -570,26 +569,29 @@ void CD3D9Texture::copy16BitMipMap(char* src, char* tgt,
s32 width, s32 height, s32 width, s32 height,
s32 pitchsrc, s32 pitchtgt) s32 pitchsrc, s32 pitchtgt)
{ {
u16 c; for (s32 y=0; y<height; ++y)
{
for (int x=0; x<width; ++x) for (s32 x=0; x<width; ++x)
for (int y=0; y<height; ++y)
{ {
s32 a=0, r=0, g=0, b=0; u32 a=0, r=0, g=0, b=0;
for (int dx=0; dx<2; ++dx) for (s32 dy=0; dy<2; ++dy)
{ {
for (int dy=0; dy<2; ++dy) const s32 tgy = (y*2)+dy;
for (s32 dx=0; dx<2; ++dx)
{ {
int tgx = (x*2)+dx; const s32 tgx = (x*2)+dx;
int tgy = (y*2)+dy;
c = *(u16*)(&src[(tgx*2)+(tgy*pitchsrc)]); SColor c;
if (ColorFormat == ECF_A1R5G5B5)
c = A1R5G5B5toA8R8G8B8(*(u16*)(&src[(tgx*2)+(tgy*pitchsrc)]));
else
c = R5G6B5toA8R8G8B8(*(u16*)(&src[(tgx*2)+(tgy*pitchsrc)]));
a += getAlpha(c); a += c.getAlpha();
r += getRed(c); r += c.getRed();
g += getGreen(c); g += c.getGreen();
b += getBlue(c); b += c.getBlue();
} }
} }
@ -598,12 +600,14 @@ void CD3D9Texture::copy16BitMipMap(char* src, char* tgt,
g /= 4; g /= 4;
b /= 4; b /= 4;
u16 c;
if (ColorFormat == ECF_A1R5G5B5) if (ColorFormat == ECF_A1R5G5B5)
c = RGBA16(r,g,b,a); c = RGBA16(r,g,b,a);
else else
c = A8R8G8B8toR5G6B5(SColor(a,r,g,b).color); c = A8R8G8B8toR5G6B5(SColor(a,r,g,b).color);
*(u16*)(&tgt[(x*2)+(y*pitchtgt)]) = c; *(u16*)(&tgt[(x*2)+(y*pitchtgt)]) = c;
} }
}
} }
@ -611,20 +615,19 @@ void CD3D9Texture::copy32BitMipMap(char* src, char* tgt,
s32 width, s32 height, s32 width, s32 height,
s32 pitchsrc, s32 pitchtgt) s32 pitchsrc, s32 pitchtgt)
{ {
SColor c; for (s32 y=0; y<height; ++y)
for (int x=0; x<width; ++x)
{ {
for (int y=0; y<height; ++y) for (s32 x=0; x<width; ++x)
{ {
s32 a=0, r=0, g=0, b=0; u32 a=0, r=0, g=0, b=0;
SColor c;
for (int dx=0; dx<2; ++dx) for (s32 dy=0; dy<2; ++dy)
{ {
for (int dy=0; dy<2; ++dy) const s32 tgy = (y*2)+dy;
for (s32 dx=0; dx<2; ++dx)
{ {
int tgx = (x*2)+dx; const s32 tgx = (x*2)+dx;
int tgy = (y*2)+dy;
c = *(u32*)(&src[(tgx*4)+(tgy*pitchsrc)]); c = *(u32*)(&src[(tgx*4)+(tgy*pitchsrc)]);

View File

@ -100,7 +100,7 @@ IImage* CImageLoaderPCX::loadImage(irr::io::IReadFile* file)
u8 *tempPalette = new u8[768]; u8 *tempPalette = new u8[768];
PaletteData = new s32[256]; PaletteData = new s32[256];
memset(PaletteData, 0, 256*sizeof(s32)); memset(PaletteData, 0xFF, 256*sizeof(s32));
file->read( tempPalette, 768 ); file->read( tempPalette, 768 );
for( s32 i=0; i<256; i++ ) for( s32 i=0; i<256; i++ )