- Burningvideo: repaired MipMap Selection

- renamed private Driver function name getTextureSizeFromImageSize to
  getTextureSizeFromSurfaceSize ( now equal in all drivers )


git-svn-id: http://svn.code.sf.net/p/irrlicht/code/trunk@1143 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
engineer_apple 2007-12-30 16:51:28 +00:00
parent 18d495851f
commit 18960d44f6
13 changed files with 151 additions and 60 deletions

View File

@ -1,3 +1,7 @@
30.12.2006 TA
Minor:
- Burningvideo: MipMap Selection
- renamed private Driver function getTextureSizeFromImageSize to getTextureSizeFromSurfaceSize
-------------------------------------------
Changes in version 1.5 (... 2008)

View File

@ -124,8 +124,8 @@ bool CD3D8Texture::createTexture(u32 flags)
optSize=ImageSize;
else
{
optSize.Width = getTextureSizeFromImageSize(ImageSize.Width);
optSize.Height = getTextureSizeFromImageSize(ImageSize.Height);
optSize.Width = getTextureSizeFromSurfaceSize(ImageSize.Width);
optSize.Height = getTextureSizeFromSurfaceSize(ImageSize.Height);
}
HRESULT hr;
@ -309,7 +309,7 @@ const core::dimension2d<s32>& CD3D8Texture::getSize() const
//! returns the size of a texture which would be the optimize size for rendering it
inline s32 CD3D8Texture::getTextureSizeFromImageSize(s32 size) const
inline s32 CD3D8Texture::getTextureSizeFromSurfaceSize(s32 size) const
{
s32 ts = 0x01;
@ -559,8 +559,8 @@ void CD3D8Texture::copy32BitMipMap(char* src, char* tgt,
void CD3D8Texture::createRenderTarget()
{
TextureSize.Width = getTextureSizeFromImageSize(TextureSize.Width);
TextureSize.Height = getTextureSizeFromImageSize(TextureSize.Height);
TextureSize.Width = getTextureSizeFromSurfaceSize(TextureSize.Width);
TextureSize.Height = getTextureSizeFromSurfaceSize(TextureSize.Height);
// get backbuffer format to create the render target in the
// same format

View File

@ -78,7 +78,7 @@ private:
void createRenderTarget();
//! returns the size of a texture which would be the optimize size for rendering it
inline s32 getTextureSizeFromImageSize(s32 size) const;
inline s32 getTextureSizeFromSurfaceSize(s32 size) const;
//! creates the hardware texture
bool createTexture(u32 flags);

View File

@ -108,8 +108,8 @@ CD3D9Texture::~CD3D9Texture()
void CD3D9Texture::createRenderTarget()
{
TextureSize.Width = getTextureSizeFromImageSize(TextureSize.Width);
TextureSize.Height = getTextureSizeFromImageSize(TextureSize.Height);
TextureSize.Width = getTextureSizeFromSurfaceSize(TextureSize.Width);
TextureSize.Height = getTextureSizeFromSurfaceSize(TextureSize.Height);
// get backbuffer format to create the render target in the
// same format
@ -263,8 +263,8 @@ bool CD3D9Texture::createTexture(u32 flags, IImage * image)
optSize=ImageSize;
else
{
optSize.Width = getTextureSizeFromImageSize(ImageSize.Width);
optSize.Height = getTextureSizeFromImageSize(ImageSize.Height);
optSize.Width = getTextureSizeFromSurfaceSize(ImageSize.Width);
optSize.Height = getTextureSizeFromSurfaceSize(ImageSize.Height);
}
HRESULT hr;
@ -510,7 +510,7 @@ const core::dimension2d<s32>& CD3D9Texture::getSize() const
//! returns the size of a texture which would be the optimize size for rendering it
inline s32 CD3D9Texture::getTextureSizeFromImageSize(s32 size) const
inline s32 CD3D9Texture::getTextureSizeFromSurfaceSize(s32 size) const
{
s32 ts = 0x01;

View File

@ -77,7 +77,7 @@ private:
void createRenderTarget();
//! returns the size of a texture which would be the optimize size for rendering it
inline s32 getTextureSizeFromImageSize(s32 size) const;
inline s32 getTextureSizeFromSurfaceSize(s32 size) const;
//! creates the hardware texture
bool createTexture(u32 flags, IImage * image);

View File

@ -762,19 +762,12 @@ inline f32 CBurningVideoDriver::screenarea ( const s4DVertex *v ) const
*/
inline f32 CBurningVideoDriver::texelarea ( const s4DVertex *v, int tex ) const
{
f32 x0,y0, x1,y1, z;
f32 z;
x0 = v[2].Tex[tex].x - v[0].Tex[tex].x;
y0 = v[2].Tex[tex].y - v[0].Tex[tex].y;
x1 = v[4].Tex[tex].x - v[0].Tex[tex].x;
y1 = v[4].Tex[tex].y - v[0].Tex[tex].y;
z = ( (v[2].Tex[tex].x - v[0].Tex[tex].x ) * (v[4].Tex[tex].y - v[0].Tex[tex].y ) )
- ( (v[4].Tex[tex].x - v[0].Tex[tex].x ) * (v[2].Tex[tex].y - v[0].Tex[tex].y ) );
z = x0*y1 - x1*y0;
const core::dimension2d<s32> &d = MAT_TEXTURE ( tex )->getMaxMipMapSize ();
z *= d.Height;
z *= d.Width;
return z;
return MAT_TEXTURE ( tex )->getLODFactor ( z );
}
/*!
@ -791,22 +784,13 @@ inline f32 CBurningVideoDriver::screenarea2 ( const s4DVertex **v ) const
inline f32 CBurningVideoDriver::texelarea2 ( const s4DVertex **v, s32 tex ) const
{
f32 z;
z = ( (v[1]->Tex[tex].x - v[0]->Tex[tex].x ) * (v[2]->Tex[tex].y - v[0]->Tex[tex].y ) )
- ( (v[2]->Tex[tex].x - v[0]->Tex[tex].x ) * (v[1]->Tex[tex].y - v[0]->Tex[tex].y ) );
z = (v[1]->Tex[tex].x - v[0]->Tex[tex].x ) *
(v[2]->Tex[tex].y - v[0]->Tex[tex].y )
- (v[2]->Tex[tex].x - v[0]->Tex[tex].x ) *
(v[1]->Tex[tex].y - v[0]->Tex[tex].y )
;
const core::dimension2d<s32> &d = MAT_TEXTURE ( tex )->getMaxMipMapSize ();
z *= d.Height;
z *= d.Width;
return z;
return MAT_TEXTURE ( tex )->getLODFactor ( z );
}
/*!
*/
inline void CBurningVideoDriver::select_polygon_mipmap ( s4DVertex *v, u32 vIn, s32 tex )
@ -1167,8 +1151,11 @@ void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vert
}
dc_area = core::reciprocal ( dc_area );
// select mipmap
for ( g = 0; g != MATERIAL_MAX_TEXTURES; ++g )
for ( g = 0; g != vSize[VertexCache.vType].TexSize; ++g )
//for ( g = 0; g != MATERIAL_MAX_TEXTURES; ++g )
{
if ( 0 == MAT_TEXTURE ( g ) )
{
@ -1177,7 +1164,6 @@ void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vert
}
lodLevel = s32_log2_f32 ( texelarea2 ( face, g ) * dc_area );
CurrentShader->setTextureParam(g, MAT_TEXTURE ( g ), lodLevel);
select_polygon_mipmap2 ( (s4DVertex**) face, g );
@ -1282,7 +1268,8 @@ void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vert
continue;
// select mipmap
for ( g = 0; g != MATERIAL_MAX_TEXTURES; ++g )
//for ( g = 0; g != MATERIAL_MAX_TEXTURES; ++g )
for ( g = 0; g != vSize[VertexCache.vType].TexSize; ++g )
{
if ( 0 == MAT_TEXTURE ( g ) )
{
@ -1863,6 +1850,87 @@ u32 CBurningVideoDriver::getMaximalPrimitiveCount() const
return 0x00800000;
}
//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do
//! this: Frist, draw all geometry. Then use this method, to draw the shadow
//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow.
void CBurningVideoDriver::drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail)
{
/*
if (!StencilBuffer || !count)
return;
setRenderStatesStencilShadowMode(zfail);
if (!zfail)
{
// ZPASS Method
// Draw front-side of shadow volume in stencil/z only
pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW );
pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCRSAT);
pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df));
// Now reverse cull order so front sides of shadow volume are written.
pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
pID3DDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_DECRSAT);
pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df));
}
else
{
// ZFAIL Method
// Draw front-side of shadow volume in stencil/z only
pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW );
pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCRSAT );
pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df));
// Now reverse cull order so front sides of shadow volume are written.
pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECRSAT );
pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles, sizeof(core::vector3df));
}
*/
}
//! Fills the stencil shadow with color. After the shadow volume has been drawn
//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this
//! to draw the color of the shadow.
void CBurningVideoDriver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge,
video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge)
{
/*
if (!StencilBuffer)
return;
S3DVertex vtx[4];
vtx[0] = S3DVertex(1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftUpEdge, 0.0f, 0.0f);
vtx[1] = S3DVertex(1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightUpEdge, 0.0f, 1.0f);
vtx[2] = S3DVertex(-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftDownEdge, 1.0f, 0.0f);
vtx[3] = S3DVertex(-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightDownEdge, 1.0f, 1.0f);
s16 indices[6] = {0,1,2,1,3,2};
setRenderStatesStencilFillMode(
leftUpEdge.getAlpha() < 255 ||
rightUpEdge.getAlpha() < 255 ||
leftDownEdge.getAlpha() < 255 ||
rightDownEdge.getAlpha() < 255);
setTexture(0,0);
setVertexShader(EVT_STANDARD);
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0],
D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex));
if (clearStencilBuffer)
pID3DDevice->Clear( 0, NULL, D3DCLEAR_STENCIL,0, 1.0, 0);
*/
}
} // end namespace video
} // end namespace irr

View File

@ -118,6 +118,21 @@ namespace video
//! call.
virtual u32 getMaximalPrimitiveCount() const;
//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do
//! this: First, draw all geometry. Then use this method, to draw the shadow
//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow.
virtual void drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail);
//! Fills the stencil shadow with color. After the shadow volume has been drawn
//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this
//! to draw the color of the shadow.
virtual void drawStencilShadow(bool clearStencilBuffer=false,
video::SColor leftUpEdge = video::SColor(0,0,0,0),
video::SColor rightUpEdge = video::SColor(0,0,0,0),
video::SColor leftDownEdge = video::SColor(0,0,0,0),
video::SColor rightDownEdge = video::SColor(0,0,0,0));
protected:
//! sets a render target

View File

@ -9,12 +9,15 @@
#include "SoftwareDriver2_helper.h"
#include "CSoftwareTexture2.h"
#include "os.h"
#include "CImageWriterBMP.h"
namespace irr
{
namespace video
{
IImageWriter* createImageWriterBMP();
//! constructor
CSoftwareTexture2::CSoftwareTexture2(IImage* image, const char* name, bool generateMipLevels, bool isRenderTarget)
: ITexture(name), MipMapLOD(0), HasMipMaps(generateMipLevels), IsRenderTarget(isRenderTarget)
@ -41,11 +44,13 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const char* name, bool gener
}
else
{
os::Printer::log ( "Burningvideo: Warning Texture reformat", ELL_WARNING );
MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, optSize);
// temporary CImage needed
CImage * temp = new CImage ( BURNINGSHADER_COLOR_FORMAT, image );
temp->copyToScaling(MipMap[0]);
temp->copyToScalingBoxFilter ( MipMap[0], 0 );
//temp->copyToScaling(MipMap[0]);
temp->drop ();
}
}
@ -67,16 +72,17 @@ CSoftwareTexture2::~CSoftwareTexture2()
//! returns the size of a texture which would be the optimize size for rendering it
inline s32 CSoftwareTexture2::getTextureSizeFromSurfaceSize(s32 size) const
s32 CSoftwareTexture2::getTextureSizeFromSurfaceSize(s32 size) const
{
s32 ts = 0x01;
while(ts < size)
ts <<= 1;
/*
if (ts > size && ts > 256 )
if ( ts > size )
ts >>= 1;
*/
//ts = core::s32_min ( ts, 256 );
return ts;
}
@ -105,8 +111,8 @@ void CSoftwareTexture2::regenerateMipMapLevels()
while ( i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX )
{
currentSize = c->getDimension();
newSize.Width = core::s32_max ( 1, currentSize.Width >> 1 );
newSize.Height = core::s32_max ( 1, currentSize.Height >> 1 );
newSize.Width = core::s32_max ( 1, currentSize.Width >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE );
newSize.Height = core::s32_max ( 1, currentSize.Height >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE );
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
MipMap[0]->copyToScalingBoxFilter ( MipMap[i], 0 );

View File

@ -48,9 +48,9 @@ public:
}
//! Returns the size of the largest mipmap.
const core::dimension2d<s32>& getMaxMipMapSize() const
f32 getLODFactor( const f32 texArea ) const
{
return MipMap[0]->getDimension();
return MipMap[0]->getImageDataSizeInPixels () * texArea;
}
//! Returns (=size) of the texture.
@ -116,7 +116,7 @@ public:
private:
//! returns the size of a texture which would be the optimize size for rendering it
inline s32 getTextureSizeFromSurfaceSize(s32 size) const;
s32 getTextureSizeFromSurfaceSize(s32 size) const;
core::dimension2d<s32> OrigSize;

View File

@ -256,7 +256,6 @@ void CTRGouraud2::scanline_bilinear ()
void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
return;
// sort on height, y
if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);
if ( a->Pos.y > c->Pos.y ) swapVertexPointer(&a, &c);

View File

@ -564,7 +564,8 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear ()
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
//#ifdef BURNINGVIDEO_RENDERER_FAST
#if 1
void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
@ -646,7 +647,7 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVert
lockedSurface = (tVideoSample*)RenderTarget->lock();
#ifdef USE_ZBUFFER
lockedDepthBuffer = DepthBuffer->lock();
lockedDepthBuffer = (fp24*) DepthBuffer->lock();
#endif
#ifdef IPOL_T0

View File

@ -79,9 +79,6 @@ namespace video
{
sInternalTexture *it = &IT[stage];
if ( it->Texture == texture )
return;
if ( it->Texture)
it->Texture->drop();
@ -101,8 +98,9 @@ namespace video
// prepare for optimal fixpoint
it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() );
it->textureXMask = s32_to_fixPoint ( it->Texture->getSize().Width - 1 ) & FIX_POINT_UNSIGNED_MASK;
it->textureYMask = s32_to_fixPoint ( it->Texture->getSize().Height - 1 ) & FIX_POINT_UNSIGNED_MASK;
const core::dimension2d<s32> &dim = it->Texture->getSize();
it->textureXMask = s32_to_fixPoint ( dim.Width - 1 ) & FIX_POINT_UNSIGNED_MASK;
it->textureYMask = s32_to_fixPoint ( dim.Height - 1 ) & FIX_POINT_UNSIGNED_MASK;
it->data = (tVideoSample*) it->Texture->lock();
}
}

View File

@ -60,18 +60,18 @@
// mip mapping
#ifdef SOFTWARE_DRIVER_2_MIPMAPPING
#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
#define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0
#else
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 8
#define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS -1
#else
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 8
#define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0
#endif
#else
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 1
#define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0
#endif
#define SOFTWARE_DRIVER_2_MIPMAPPING_SCALE (8/SOFTWARE_DRIVER_2_MIPMAPPING_MAX)
#ifndef REALINLINE
#ifdef _MSC_VER