620 lines
15 KiB
C++
620 lines
15 KiB
C++
|
|
#include "std.h"
|
|
#include "gxgraphics.h"
|
|
#include "gxruntime.h"
|
|
|
|
extern gxRuntime *gx_runtime;
|
|
|
|
gxGraphics::gxGraphics( gxRuntime *rt,IDirectDraw7 *dd,IDirectDrawSurface7 *fs,IDirectDrawSurface7 *bs,bool d3d ):
|
|
runtime(rt),dirDraw(dd),dir3d(0),dir3dDev(0),def_font(0),gfx_lost(false),dummy_mesh(0){
|
|
|
|
dirDraw->QueryInterface( IID_IDirectDraw,(void**)&ds_dirDraw );
|
|
|
|
front_canvas=d_new gxCanvas( this,fs,0 );
|
|
back_canvas=d_new gxCanvas( this,bs,0 );
|
|
|
|
front_canvas->cls();
|
|
back_canvas->cls();
|
|
|
|
def_font=loadFont( "courier",12,0 );
|
|
|
|
front_canvas->setFont( def_font );
|
|
back_canvas->setFont( def_font );
|
|
|
|
memset(&primFmt,0,sizeof(primFmt));
|
|
primFmt.dwSize=sizeof(primFmt);
|
|
fs->GetPixelFormat( &primFmt );
|
|
|
|
//are we fullscreen?
|
|
_gamma=0;
|
|
if( fs!=bs ){
|
|
if( fs->QueryInterface( IID_IDirectDrawGammaControl,(void**)&_gamma )>=0 ){
|
|
if( _gamma->GetGammaRamp( 0,&_gammaRamp )<0 ) _gamma=0;
|
|
}
|
|
}
|
|
if( !_gamma ){
|
|
for( int k=0;k<256;++k ) _gammaRamp.red[k]=_gammaRamp.blue[k]=_gammaRamp.green[k]=k;
|
|
}
|
|
}
|
|
|
|
gxGraphics::~gxGraphics(){
|
|
if( _gamma ) _gamma->Release();
|
|
#ifdef PRO
|
|
while( scene_set.size() ) freeScene( *scene_set.begin() );
|
|
#endif
|
|
while( movie_set.size() ) closeMovie( *movie_set.begin() );
|
|
while( font_set.size() ) freeFont( *font_set.begin() );
|
|
while( canvas_set.size() ) freeCanvas( *canvas_set.begin() );
|
|
|
|
set<string>::iterator it;
|
|
for( it=font_res.begin();it!=font_res.end();++it ) RemoveFontResource( (*it).c_str() );
|
|
font_res.clear();
|
|
|
|
delete back_canvas;
|
|
delete front_canvas;
|
|
|
|
ds_dirDraw->Release();
|
|
|
|
dirDraw->RestoreDisplayMode();
|
|
dirDraw->Release();
|
|
}
|
|
|
|
void gxGraphics::setGamma( int r,int g,int b,float dr,float dg,float db ){
|
|
_gammaRamp.red[r&255]=dr*257.0f;
|
|
_gammaRamp.green[g&255]=dg*257.0f;
|
|
_gammaRamp.blue[b&255]=db*257.0f;
|
|
}
|
|
|
|
void gxGraphics::updateGamma( bool calibrate ){
|
|
if( !_gamma ) return;
|
|
_gamma->SetGammaRamp( calibrate ? DDSGR_CALIBRATE : 0,&_gammaRamp );
|
|
}
|
|
|
|
void gxGraphics::getGamma( int r,int g,int b,float *dr,float *dg,float *db ){
|
|
*dr=_gammaRamp.red[r&255]/257.0f;
|
|
*dg=_gammaRamp.green[g&255]/257.0f;
|
|
*db=_gammaRamp.blue[b&255]/257.0f;
|
|
}
|
|
|
|
void gxGraphics::backup(){
|
|
}
|
|
|
|
bool gxGraphics::restore(){
|
|
|
|
while( dirDraw->TestCooperativeLevel()!=DD_OK ){
|
|
|
|
if( dirDraw->TestCooperativeLevel()==DDERR_WRONGMODE ) return false;
|
|
|
|
Sleep( 100 );
|
|
}
|
|
|
|
if( back_canvas->getSurface()->IsLost()==DD_OK ) return true;
|
|
|
|
dirDraw->RestoreAllSurfaces();
|
|
|
|
//restore all canvases
|
|
set<gxCanvas*>::iterator it;
|
|
for( it=canvas_set.begin();it!=canvas_set.end();++it ){
|
|
(*it)->restore();
|
|
}
|
|
|
|
#ifdef PRO
|
|
//restore all meshes (b3d surfaces)
|
|
set<gxMesh*>::iterator mesh_it;
|
|
for( mesh_it=mesh_set.begin();mesh_it!=mesh_set.end();++mesh_it ){
|
|
(*mesh_it)->restore();
|
|
}
|
|
if( dir3d ) dir3d->EvictManagedTextures();
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
gxCanvas *gxGraphics::getFrontCanvas()const{
|
|
return front_canvas;
|
|
}
|
|
|
|
gxCanvas *gxGraphics::getBackCanvas()const{
|
|
return back_canvas;
|
|
}
|
|
|
|
gxFont *gxGraphics::getDefaultFont()const{
|
|
return def_font;
|
|
}
|
|
|
|
void gxGraphics::vwait(){
|
|
dirDraw->WaitForVerticalBlank( DDWAITVB_BLOCKBEGIN,0 );
|
|
}
|
|
|
|
void gxGraphics::flip( bool v ){
|
|
runtime->flip( v );
|
|
}
|
|
|
|
void gxGraphics::copy( gxCanvas *dest,int dx,int dy,int dw,int dh,gxCanvas *src,int sx,int sy,int sw,int sh ){
|
|
RECT r={ dx,dy,dx+dw,dy+dh };
|
|
ddUtil::copy( dest->getSurface(),dx,dy,dw,dh,src->getSurface(),sx,sy,sw,sh );
|
|
dest->damage( r );
|
|
}
|
|
|
|
int gxGraphics::getScanLine()const{
|
|
DWORD t=0;
|
|
dirDraw->GetScanLine( &t );
|
|
return t;
|
|
}
|
|
|
|
int gxGraphics::getTotalVidmem()const{
|
|
DDCAPS caps={sizeof(caps)};
|
|
dirDraw->GetCaps( &caps,0 );
|
|
return caps.dwVidMemTotal;
|
|
}
|
|
|
|
int gxGraphics::getAvailVidmem()const{
|
|
DDCAPS caps={sizeof(caps)};
|
|
dirDraw->GetCaps( &caps,0 );
|
|
return caps.dwVidMemFree;
|
|
}
|
|
|
|
gxMovie *gxGraphics::openMovie( const string &file,int flags ){
|
|
|
|
IAMMultiMediaStream *iam_stream;
|
|
|
|
if( CoCreateInstance(
|
|
CLSID_AMMultiMediaStream,NULL,CLSCTX_INPROC_SERVER,
|
|
IID_IAMMultiMediaStream,(void **)&iam_stream )==S_OK ){
|
|
|
|
if( iam_stream->Initialize( STREAMTYPE_READ,AMMSF_NOGRAPHTHREAD,NULL )==S_OK ){
|
|
|
|
if( iam_stream->AddMediaStream( ds_dirDraw,&MSPID_PrimaryVideo,0,NULL )==S_OK ){
|
|
|
|
iam_stream->AddMediaStream( NULL,&MSPID_PrimaryAudio,AMMSF_ADDDEFAULTRENDERER,NULL );
|
|
|
|
WCHAR *path=new WCHAR[ file.size()+1 ];
|
|
MultiByteToWideChar( CP_ACP,0,file.c_str(),-1,path,sizeof(WCHAR)*(file.size()+1) );
|
|
int n=iam_stream->OpenFile( path,0 );
|
|
delete path;
|
|
|
|
if( n==S_OK ){
|
|
gxMovie *movie=d_new gxMovie( this,iam_stream );
|
|
movie_set.insert( movie );
|
|
return movie;
|
|
}
|
|
}
|
|
}
|
|
iam_stream->Release();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
gxMovie *gxGraphics::verifyMovie( gxMovie *m ){
|
|
return movie_set.count( m ) ? m : 0;
|
|
}
|
|
|
|
void gxGraphics::closeMovie( gxMovie *m ){
|
|
if( movie_set.erase( m ) ) delete m;
|
|
}
|
|
|
|
gxCanvas *gxGraphics::createCanvas( int w,int h,int flags ){
|
|
ddSurf *s=ddUtil::createSurface( w,h,flags,this );
|
|
if( !s ) return 0;
|
|
gxCanvas *c=d_new gxCanvas( this,s,flags );
|
|
canvas_set.insert( c );
|
|
c->cls();
|
|
return c;
|
|
}
|
|
|
|
gxCanvas *gxGraphics::loadCanvas( const string &f,int flags ){
|
|
ddSurf *s=ddUtil::loadSurface( f,flags,this );
|
|
if( !s ) return 0;
|
|
gxCanvas *c=d_new gxCanvas( this,s,flags );
|
|
canvas_set.insert( c );
|
|
return c;
|
|
}
|
|
|
|
gxCanvas *gxGraphics::verifyCanvas( gxCanvas *c ){
|
|
return canvas_set.count( c ) || c==front_canvas || c==back_canvas ? c : 0;
|
|
}
|
|
|
|
void gxGraphics::freeCanvas( gxCanvas *c ){
|
|
if( canvas_set.erase( c ) ) delete c;
|
|
}
|
|
|
|
int gxGraphics::getWidth()const{
|
|
return front_canvas->getWidth();
|
|
}
|
|
|
|
int gxGraphics::getHeight()const{
|
|
return front_canvas->getHeight();
|
|
}
|
|
|
|
int gxGraphics::getDepth()const{
|
|
return front_canvas->getDepth();
|
|
}
|
|
|
|
gxFont *gxGraphics::loadFont( const string &f,int height,int flags ){
|
|
|
|
int bold=flags & gxFont::FONT_BOLD ? FW_BOLD : FW_REGULAR;
|
|
int italic=flags & gxFont::FONT_ITALIC ? 1 : 0;
|
|
int underline=flags & gxFont::FONT_UNDERLINE ? 1 : 0;
|
|
int strikeout=0;
|
|
|
|
string t;
|
|
int n=f.find('.');
|
|
if( n!=string::npos ){
|
|
t=fullfilename(f);
|
|
if( !font_res.count(t) && AddFontResource( t.c_str() ) ) font_res.insert( t );
|
|
t=filenamefile( f.substr(0,n) );
|
|
}else{
|
|
t=f;
|
|
}
|
|
|
|
//save and turn off font smoothing....
|
|
BOOL smoothing=FALSE;
|
|
SystemParametersInfo( SPI_GETFONTSMOOTHING,0,&smoothing,0 );
|
|
SystemParametersInfo( SPI_SETFONTSMOOTHING,FALSE,0,0 );
|
|
|
|
HFONT hfont=CreateFont(
|
|
height,0,0,0,
|
|
bold,italic,underline,strikeout,
|
|
ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
|
|
DEFAULT_PITCH|FF_DONTCARE,t.c_str() );
|
|
|
|
if( !hfont ){
|
|
//restore font smoothing
|
|
SystemParametersInfo( SPI_SETFONTSMOOTHING,smoothing,0,0 );
|
|
return 0;
|
|
}
|
|
|
|
HDC hdc=CreateCompatibleDC( 0 );
|
|
HFONT pfont=(HFONT)SelectObject( hdc,hfont );
|
|
|
|
TEXTMETRIC tm={0};
|
|
if( !GetTextMetrics( hdc,&tm ) ){
|
|
SelectObject( hdc,pfont );
|
|
DeleteDC( hdc );
|
|
DeleteObject( hfont );
|
|
SystemParametersInfo( SPI_SETFONTSMOOTHING,smoothing,0,0 );
|
|
return 0;
|
|
}
|
|
height=tm.tmHeight;
|
|
|
|
int first=tm.tmFirstChar,last=tm.tmLastChar;
|
|
int sz=last-first+1;
|
|
int *offs=d_new int[sz];
|
|
int *widths=d_new int[sz];
|
|
int *as=d_new int[sz];
|
|
|
|
//calc size of canvas to hold font.
|
|
int x=0,y=0,max_x=0;
|
|
for( int k=0;k<sz;++k ){
|
|
|
|
char t=k+first;
|
|
|
|
SIZE sz;
|
|
GetTextExtentPoint32( hdc,&t,1,&sz );
|
|
int w=sz.cx;
|
|
|
|
as[k]=0;
|
|
|
|
ABC abc;
|
|
if( GetCharABCWidths( hdc,t,t,&abc ) ){
|
|
if( abc.abcA<0 ){
|
|
as[k]=ceil(-abc.abcA);
|
|
w+=as[k];
|
|
}
|
|
if( abc.abcC<0 ) w+=ceil(-abc.abcC);
|
|
}
|
|
|
|
if( x && x+w>getWidth() ){ x=0;y+=height; }
|
|
offs[k]=(x<<16)|y;
|
|
widths[k]=w;
|
|
x+=w;if( x>max_x ) max_x=x;
|
|
}
|
|
SelectObject( hdc,pfont );
|
|
DeleteDC( hdc );
|
|
|
|
int cw=max_x,ch=y+height;
|
|
|
|
if( gxCanvas *c=createCanvas( cw,ch,0 ) ){
|
|
ddSurf *surf=c->getSurface();
|
|
|
|
HDC surf_hdc;
|
|
if( surf->GetDC( &surf_hdc )>=0 ){
|
|
HFONT pfont=(HFONT)SelectObject( surf_hdc,hfont );
|
|
|
|
SetBkColor( surf_hdc,0x000000 );
|
|
SetTextColor( surf_hdc,0xffffff );
|
|
|
|
for( int k=0;k<sz;++k ){
|
|
int x=(offs[k]>>16)&0xffff,y=offs[k]&0xffff;
|
|
char t=k+first;
|
|
RECT rect={x,y,x+widths[k],y+height};
|
|
ExtTextOut( surf_hdc,x+as[k],y,ETO_CLIPPED,&rect,&t,1,0 );
|
|
}
|
|
|
|
SelectObject( surf_hdc,pfont );
|
|
surf->ReleaseDC( surf_hdc );
|
|
DeleteObject( hfont );
|
|
delete[] as;
|
|
|
|
c->backup();
|
|
gxFont *font=d_new gxFont( this,c,tm.tmMaxCharWidth,height,first,last+1,tm.tmDefaultChar,offs,widths );
|
|
font_set.insert( font );
|
|
|
|
//restore font smoothing
|
|
SystemParametersInfo( SPI_SETFONTSMOOTHING,smoothing,0,0 );
|
|
return font;
|
|
}else{
|
|
}
|
|
freeCanvas( c );
|
|
}else{
|
|
}
|
|
DeleteObject( hfont );
|
|
delete[] as;
|
|
delete[] widths;
|
|
delete[] offs;
|
|
|
|
//restore font smoothing
|
|
SystemParametersInfo( SPI_SETFONTSMOOTHING,smoothing,0,0 );
|
|
return 0;
|
|
}
|
|
|
|
gxFont *gxGraphics::verifyFont( gxFont *f ){
|
|
return font_set.count( f ) ? f : 0;
|
|
}
|
|
|
|
void gxGraphics::freeFont( gxFont *f ){
|
|
if( font_set.erase( f ) ) delete f;
|
|
}
|
|
|
|
//////////////
|
|
// 3D STUFF //
|
|
//////////////
|
|
|
|
#ifdef PRO
|
|
|
|
static int maxDevType;
|
|
|
|
static HRESULT CALLBACK enumDevice( char *desc,char *name,D3DDEVICEDESC7 *devDesc,void *context ){
|
|
gxGraphics *g=(gxGraphics*)context;
|
|
int t=0;
|
|
GUID guid=devDesc->deviceGUID;
|
|
if( guid==IID_IDirect3DRGBDevice ) t=1;
|
|
else if( guid==IID_IDirect3DHALDevice ) t=2;
|
|
else if( guid==IID_IDirect3DTnLHalDevice ) t=3;
|
|
if( t>maxDevType ){
|
|
g->dir3dDevDesc=*devDesc;
|
|
maxDevType=t;
|
|
}
|
|
return D3DENUMRET_OK;
|
|
}
|
|
|
|
static HRESULT CALLBACK enumZbuffFormat( LPDDPIXELFORMAT format,void *context ){
|
|
gxGraphics *g=(gxGraphics*)context;
|
|
if( format->dwZBufferBitDepth==g->primFmt.dwRGBBitCount ){
|
|
g->zbuffFmt=*format;
|
|
return D3DENUMRET_CANCEL;
|
|
}
|
|
if( format->dwZBufferBitDepth>g->zbuffFmt.dwZBufferBitDepth ){
|
|
if( format->dwZBufferBitDepth<g->primFmt.dwRGBBitCount ){
|
|
g->zbuffFmt=*format;
|
|
}
|
|
}
|
|
return D3DENUMRET_OK;
|
|
}
|
|
|
|
struct TexFmt{
|
|
DDPIXELFORMAT fmt;
|
|
int bits,a_bits,rgb_bits;
|
|
};
|
|
|
|
static int cntBits( int mask ){
|
|
int n=0;
|
|
for( int k=0;k<32;++k ){
|
|
if( mask & (1<<k) ) ++n;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
static vector<TexFmt> tex_fmts;
|
|
|
|
static HRESULT CALLBACK enumTextureFormat( DDPIXELFORMAT *fmt,void *p ){
|
|
TexFmt t;
|
|
t.fmt=*fmt;
|
|
t.bits=fmt->dwRGBBitCount;
|
|
t.a_bits=(fmt->dwFlags & DDPF_ALPHAPIXELS) ? cntBits(fmt->dwRGBAlphaBitMask) : 0;
|
|
t.rgb_bits=(fmt->dwFlags & DDPF_RGB) ? cntBits(fmt->dwRBitMask|fmt->dwGBitMask|fmt->dwBBitMask) : 0;
|
|
|
|
tex_fmts.push_back( t );
|
|
|
|
return D3DENUMRET_OK;
|
|
}
|
|
|
|
static string itobin( int n ){
|
|
string t;
|
|
for( int k=0;k<32;n<<=1,++k ){
|
|
t+=(n&0x80000000) ? '1' : '0';
|
|
}
|
|
return t;
|
|
}
|
|
|
|
static void debugPF( const DDPIXELFORMAT &pf ){
|
|
string t;
|
|
t="Bits:"+itoa( pf.dwRGBBitCount );
|
|
gx_runtime->debugLog( t.c_str() );
|
|
t="R Mask:"+itobin( pf.dwRBitMask );
|
|
gx_runtime->debugLog( t.c_str() );
|
|
t="G Mask:"+itobin( pf.dwGBitMask );
|
|
gx_runtime->debugLog( t.c_str() );
|
|
t="B Mask:"+itobin( pf.dwBBitMask );
|
|
gx_runtime->debugLog( t.c_str() );
|
|
t="A Mask:"+itobin( pf.dwRGBAlphaBitMask );
|
|
gx_runtime->debugLog( t.c_str() );
|
|
}
|
|
|
|
static void pickTexFmts( gxGraphics *g,int hi ){
|
|
//texRGBFmt.
|
|
{
|
|
int pick=-1,max=0,bits;
|
|
for( int d=g->primFmt.dwRGBBitCount;d<=32;d+=8 ){
|
|
for( int k=0;k<tex_fmts.size();++k ){
|
|
const TexFmt &t=tex_fmts[k];
|
|
if( t.bits>d || !t.rgb_bits || t.rgb_bits<max ) continue;
|
|
if( t.rgb_bits==max && t.bits>=bits ) continue;
|
|
pick=k;max=t.rgb_bits;bits=t.bits;
|
|
}
|
|
if( !hi && pick>=0 ) break;
|
|
}
|
|
if( pick<0 ) g->texRGBFmt[hi]=g->primFmt;
|
|
else g->texRGBFmt[hi]=tex_fmts[pick].fmt;
|
|
}
|
|
//texAlphaFmt
|
|
{
|
|
int pick=-1,max=0,bits;
|
|
for( int d=g->primFmt.dwRGBBitCount;d<=32;d+=8 ){
|
|
for( int k=0;k<tex_fmts.size();++k ){
|
|
const TexFmt &t=tex_fmts[k];
|
|
if( t.bits>d || !t.a_bits || t.a_bits<max ) continue;
|
|
if( t.a_bits==max && t.bits>=bits ) continue;
|
|
pick=k;max=t.a_bits;bits=t.bits;
|
|
}
|
|
if( !hi && pick>=0 ) break;
|
|
}
|
|
if( pick<0 ) g->texAlphaFmt[hi]=g->primFmt;
|
|
else g->texAlphaFmt[hi]=tex_fmts[pick].fmt;
|
|
}
|
|
//texRGBAlphaFmt
|
|
{
|
|
int pick=-1,a8rgb8=-1,max=0,bits;
|
|
for( int d=g->primFmt.dwRGBBitCount;d<=32;d+=8 ){
|
|
for( int k=0;k<tex_fmts.size();++k ){
|
|
const TexFmt &t=tex_fmts[k];
|
|
if( t.a_bits==8 && t.bits==16 ){ a8rgb8=k;continue; }
|
|
if( t.bits>d || !t.a_bits || !t.rgb_bits || t.a_bits<max ) continue;
|
|
if( t.a_bits==max && t.bits>=bits ) continue;
|
|
pick=k;max=t.a_bits;bits=t.bits;
|
|
}
|
|
if( !hi && pick>=0 ) break;
|
|
}
|
|
if( pick<0 ) pick=a8rgb8;
|
|
if( pick<0 ) g->texRGBAlphaFmt[hi]=g->primFmt;
|
|
else g->texRGBAlphaFmt[hi]=tex_fmts[pick].fmt;
|
|
}
|
|
//texRGBMaskFmt...
|
|
{
|
|
int pick=-1,max=0,bits;
|
|
for( int d=g->primFmt.dwRGBBitCount;d<=32;d+=8 ){
|
|
for( int k=0;k<tex_fmts.size();++k ){
|
|
const TexFmt &t=tex_fmts[k];
|
|
if( !t.a_bits || !t.rgb_bits || t.rgb_bits<max ) continue;
|
|
if( t.rgb_bits==max && t.bits>=bits ) continue;
|
|
pick=k;max=t.rgb_bits;bits=t.bits;
|
|
}
|
|
if( !hi && pick>=0 ) break;
|
|
}
|
|
if( pick<0 ) g->texRGBMaskFmt[hi]=g->primFmt;
|
|
else g->texRGBMaskFmt[hi]=tex_fmts[pick].fmt;
|
|
}
|
|
}
|
|
|
|
gxScene *gxGraphics::createScene( int flags ){
|
|
if( scene_set.size() ) return 0;
|
|
|
|
//get d3d
|
|
if( dirDraw->QueryInterface( IID_IDirect3D7,(void**)&dir3d )>=0 ){
|
|
//enum devices
|
|
maxDevType=0;
|
|
if( dir3d->EnumDevices( enumDevice,this )>=0 && maxDevType>1 ){
|
|
//enum zbuffer formats
|
|
zbuffFmt.dwZBufferBitDepth=0;
|
|
if( dir3d->EnumZBufferFormats( dir3dDevDesc.deviceGUID,enumZbuffFormat,this )>=0 ){
|
|
//create zbuff for back buffer
|
|
if( back_canvas->attachZBuffer() ){
|
|
//create 3d device
|
|
if( dir3d->CreateDevice( dir3dDevDesc.deviceGUID,back_canvas->getSurface(),&dir3dDev )>=0 ){
|
|
//enum texture formats
|
|
tex_fmts.clear();
|
|
if( dir3dDev->EnumTextureFormats( enumTextureFormat,this )>=0 ){
|
|
pickTexFmts( this,0 );
|
|
pickTexFmts( this,1 );
|
|
tex_fmts.clear();
|
|
#ifdef BETA
|
|
gx_runtime->debugLog( "Texture RGB format:" );
|
|
debugPF( texRGBFmt );
|
|
gx_runtime->debugLog( "Texture Alpha format:" );
|
|
debugPF( texAlphaFmt );
|
|
gx_runtime->debugLog( "Texture RGB Alpha format:" );
|
|
debugPF( texRGBAlphaFmt );
|
|
gx_runtime->debugLog( "Texture RGB Mask format:" );
|
|
debugPF( texRGBMaskFmt );
|
|
gx_runtime->debugLog( "Texture Primary format:" );
|
|
debugPF( primFmt );
|
|
string ts="ZBuffer Bit Depth:"+itoa( zbuffFmt.dwZBufferBitDepth );
|
|
gx_runtime->debugLog( ts.c_str() );
|
|
#endif
|
|
gxScene *scene=d_new gxScene( this,back_canvas );
|
|
scene_set.insert( scene );
|
|
|
|
dummy_mesh=createMesh( 8,12,0 );
|
|
|
|
return scene;
|
|
}
|
|
dir3dDev->Release();
|
|
dir3dDev=0;
|
|
}
|
|
back_canvas->releaseZBuffer();
|
|
}
|
|
}
|
|
}
|
|
dir3d->Release();
|
|
dir3d=0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
gxScene *gxGraphics::verifyScene( gxScene *s ){
|
|
return scene_set.count( s ) ? s : 0;
|
|
}
|
|
|
|
void gxGraphics::freeScene( gxScene *scene ){
|
|
if( !scene_set.erase( scene ) ) return;
|
|
dummy_mesh=0;
|
|
while( mesh_set.size() ) freeMesh( *mesh_set.begin() );
|
|
back_canvas->releaseZBuffer();
|
|
if( dir3dDev ){ dir3dDev->Release();dir3dDev=0; }
|
|
if( dir3d ){ dir3d->Release();dir3d=0; }
|
|
delete scene;
|
|
}
|
|
|
|
gxMesh *gxGraphics::createMesh( int max_verts,int max_tris,int flags ){
|
|
|
|
static const int VTXFMT=
|
|
D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_TEX2|
|
|
D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1);
|
|
|
|
int vbflags=0;
|
|
|
|
//XP or less?
|
|
if( runtime->osinfo.dwMajorVersion<6 ){
|
|
vbflags|=D3DVBCAPS_WRITEONLY;
|
|
}
|
|
|
|
D3DVERTEXBUFFERDESC desc={ sizeof(desc),vbflags,VTXFMT,max_verts };
|
|
|
|
IDirect3DVertexBuffer7 *buff;
|
|
if( dir3d->CreateVertexBuffer( &desc,&buff,0 )<0 ) return 0;
|
|
WORD *indices=d_new WORD[max_tris*3];
|
|
gxMesh *mesh=d_new gxMesh( this,buff,indices,max_verts,max_tris );
|
|
mesh_set.insert( mesh );
|
|
return mesh;
|
|
}
|
|
|
|
gxMesh *gxGraphics::verifyMesh( gxMesh *m ){
|
|
return mesh_set.count( m ) ? m : 0;
|
|
}
|
|
|
|
void gxGraphics::freeMesh( gxMesh *mesh ){
|
|
if( mesh_set.erase( mesh ) ) delete mesh;
|
|
}
|
|
|
|
#endif
|