gxgraphics.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. #include "std.h"
  2. #include "gxgraphics.h"
  3. #include "gxruntime.h"
  4. extern gxRuntime *gx_runtime;
  5. gxGraphics::gxGraphics( gxRuntime *rt,IDirectDraw7 *dd,IDirectDrawSurface7 *fs,IDirectDrawSurface7 *bs,bool d3d ):
  6. runtime(rt),dirDraw(dd),dir3d(0),dir3dDev(0),def_font(0),gfx_lost(false),dummy_mesh(0){
  7. dirDraw->QueryInterface( IID_IDirectDraw,(void**)&ds_dirDraw );
  8. front_canvas=d_new gxCanvas( this,fs,0 );
  9. back_canvas=d_new gxCanvas( this,bs,0 );
  10. front_canvas->cls();
  11. back_canvas->cls();
  12. def_font=loadFont( "courier",12,0 );
  13. front_canvas->setFont( def_font );
  14. back_canvas->setFont( def_font );
  15. memset(&primFmt,0,sizeof(primFmt));
  16. primFmt.dwSize=sizeof(primFmt);
  17. fs->GetPixelFormat( &primFmt );
  18. //are we fullscreen?
  19. _gamma=0;
  20. if( fs!=bs ){
  21. if( fs->QueryInterface( IID_IDirectDrawGammaControl,(void**)&_gamma )>=0 ){
  22. if( _gamma->GetGammaRamp( 0,&_gammaRamp )<0 ) _gamma=0;
  23. }
  24. }
  25. if( !_gamma ){
  26. for( int k=0;k<256;++k ) _gammaRamp.red[k]=_gammaRamp.blue[k]=_gammaRamp.green[k]=k;
  27. }
  28. }
  29. gxGraphics::~gxGraphics(){
  30. if( _gamma ) _gamma->Release();
  31. #ifdef PRO
  32. while( scene_set.size() ) freeScene( *scene_set.begin() );
  33. #endif
  34. while( movie_set.size() ) closeMovie( *movie_set.begin() );
  35. while( font_set.size() ) freeFont( *font_set.begin() );
  36. while( canvas_set.size() ) freeCanvas( *canvas_set.begin() );
  37. set<string>::iterator it;
  38. for( it=font_res.begin();it!=font_res.end();++it ) RemoveFontResource( (*it).c_str() );
  39. font_res.clear();
  40. delete back_canvas;
  41. delete front_canvas;
  42. ds_dirDraw->Release();
  43. dirDraw->RestoreDisplayMode();
  44. dirDraw->Release();
  45. }
  46. void gxGraphics::setGamma( int r,int g,int b,float dr,float dg,float db ){
  47. _gammaRamp.red[r&255]=dr*257.0f;
  48. _gammaRamp.green[g&255]=dg*257.0f;
  49. _gammaRamp.blue[b&255]=db*257.0f;
  50. }
  51. void gxGraphics::updateGamma( bool calibrate ){
  52. if( !_gamma ) return;
  53. _gamma->SetGammaRamp( calibrate ? DDSGR_CALIBRATE : 0,&_gammaRamp );
  54. }
  55. void gxGraphics::getGamma( int r,int g,int b,float *dr,float *dg,float *db ){
  56. *dr=_gammaRamp.red[r&255]/257.0f;
  57. *dg=_gammaRamp.green[g&255]/257.0f;
  58. *db=_gammaRamp.blue[b&255]/257.0f;
  59. }
  60. void gxGraphics::backup(){
  61. }
  62. bool gxGraphics::restore(){
  63. while( dirDraw->TestCooperativeLevel()!=DD_OK ){
  64. if( dirDraw->TestCooperativeLevel()==DDERR_WRONGMODE ) return false;
  65. Sleep( 100 );
  66. }
  67. if( back_canvas->getSurface()->IsLost()==DD_OK ) return true;
  68. dirDraw->RestoreAllSurfaces();
  69. //restore all canvases
  70. set<gxCanvas*>::iterator it;
  71. for( it=canvas_set.begin();it!=canvas_set.end();++it ){
  72. (*it)->restore();
  73. }
  74. #ifdef PRO
  75. //restore all meshes (b3d surfaces)
  76. set<gxMesh*>::iterator mesh_it;
  77. for( mesh_it=mesh_set.begin();mesh_it!=mesh_set.end();++mesh_it ){
  78. (*mesh_it)->restore();
  79. }
  80. if( dir3d ) dir3d->EvictManagedTextures();
  81. #endif
  82. return true;
  83. }
  84. gxCanvas *gxGraphics::getFrontCanvas()const{
  85. return front_canvas;
  86. }
  87. gxCanvas *gxGraphics::getBackCanvas()const{
  88. return back_canvas;
  89. }
  90. gxFont *gxGraphics::getDefaultFont()const{
  91. return def_font;
  92. }
  93. void gxGraphics::vwait(){
  94. dirDraw->WaitForVerticalBlank( DDWAITVB_BLOCKBEGIN,0 );
  95. }
  96. void gxGraphics::flip( bool v ){
  97. runtime->flip( v );
  98. }
  99. void gxGraphics::copy( gxCanvas *dest,int dx,int dy,int dw,int dh,gxCanvas *src,int sx,int sy,int sw,int sh ){
  100. RECT r={ dx,dy,dx+dw,dy+dh };
  101. ddUtil::copy( dest->getSurface(),dx,dy,dw,dh,src->getSurface(),sx,sy,sw,sh );
  102. dest->damage( r );
  103. }
  104. int gxGraphics::getScanLine()const{
  105. DWORD t=0;
  106. dirDraw->GetScanLine( &t );
  107. return t;
  108. }
  109. int gxGraphics::getTotalVidmem()const{
  110. DDCAPS caps={sizeof(caps)};
  111. dirDraw->GetCaps( &caps,0 );
  112. return caps.dwVidMemTotal;
  113. }
  114. int gxGraphics::getAvailVidmem()const{
  115. DDCAPS caps={sizeof(caps)};
  116. dirDraw->GetCaps( &caps,0 );
  117. return caps.dwVidMemFree;
  118. }
  119. gxMovie *gxGraphics::openMovie( const string &file,int flags ){
  120. IAMMultiMediaStream *iam_stream;
  121. if( CoCreateInstance(
  122. CLSID_AMMultiMediaStream,NULL,CLSCTX_INPROC_SERVER,
  123. IID_IAMMultiMediaStream,(void **)&iam_stream )==S_OK ){
  124. if( iam_stream->Initialize( STREAMTYPE_READ,AMMSF_NOGRAPHTHREAD,NULL )==S_OK ){
  125. if( iam_stream->AddMediaStream( ds_dirDraw,&MSPID_PrimaryVideo,0,NULL )==S_OK ){
  126. iam_stream->AddMediaStream( NULL,&MSPID_PrimaryAudio,AMMSF_ADDDEFAULTRENDERER,NULL );
  127. WCHAR *path=new WCHAR[ file.size()+1 ];
  128. MultiByteToWideChar( CP_ACP,0,file.c_str(),-1,path,sizeof(WCHAR)*(file.size()+1) );
  129. int n=iam_stream->OpenFile( path,0 );
  130. delete path;
  131. if( n==S_OK ){
  132. gxMovie *movie=d_new gxMovie( this,iam_stream );
  133. movie_set.insert( movie );
  134. return movie;
  135. }
  136. }
  137. }
  138. iam_stream->Release();
  139. }
  140. return 0;
  141. }
  142. gxMovie *gxGraphics::verifyMovie( gxMovie *m ){
  143. return movie_set.count( m ) ? m : 0;
  144. }
  145. void gxGraphics::closeMovie( gxMovie *m ){
  146. if( movie_set.erase( m ) ) delete m;
  147. }
  148. gxCanvas *gxGraphics::createCanvas( int w,int h,int flags ){
  149. ddSurf *s=ddUtil::createSurface( w,h,flags,this );
  150. if( !s ) return 0;
  151. gxCanvas *c=d_new gxCanvas( this,s,flags );
  152. canvas_set.insert( c );
  153. c->cls();
  154. return c;
  155. }
  156. gxCanvas *gxGraphics::loadCanvas( const string &f,int flags ){
  157. ddSurf *s=ddUtil::loadSurface( f,flags,this );
  158. if( !s ) return 0;
  159. gxCanvas *c=d_new gxCanvas( this,s,flags );
  160. canvas_set.insert( c );
  161. return c;
  162. }
  163. gxCanvas *gxGraphics::verifyCanvas( gxCanvas *c ){
  164. return canvas_set.count( c ) || c==front_canvas || c==back_canvas ? c : 0;
  165. }
  166. void gxGraphics::freeCanvas( gxCanvas *c ){
  167. if( canvas_set.erase( c ) ) delete c;
  168. }
  169. int gxGraphics::getWidth()const{
  170. return front_canvas->getWidth();
  171. }
  172. int gxGraphics::getHeight()const{
  173. return front_canvas->getHeight();
  174. }
  175. int gxGraphics::getDepth()const{
  176. return front_canvas->getDepth();
  177. }
  178. gxFont *gxGraphics::loadFont( const string &f,int height,int flags ){
  179. int bold=flags & gxFont::FONT_BOLD ? FW_BOLD : FW_REGULAR;
  180. int italic=flags & gxFont::FONT_ITALIC ? 1 : 0;
  181. int underline=flags & gxFont::FONT_UNDERLINE ? 1 : 0;
  182. int strikeout=0;
  183. string t;
  184. int n=f.find('.');
  185. if( n!=string::npos ){
  186. t=fullfilename(f);
  187. if( !font_res.count(t) && AddFontResource( t.c_str() ) ) font_res.insert( t );
  188. t=filenamefile( f.substr(0,n) );
  189. }else{
  190. t=f;
  191. }
  192. //save and turn off font smoothing....
  193. BOOL smoothing=FALSE;
  194. SystemParametersInfo( SPI_GETFONTSMOOTHING,0,&smoothing,0 );
  195. SystemParametersInfo( SPI_SETFONTSMOOTHING,FALSE,0,0 );
  196. HFONT hfont=CreateFont(
  197. height,0,0,0,
  198. bold,italic,underline,strikeout,
  199. ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
  200. DEFAULT_PITCH|FF_DONTCARE,t.c_str() );
  201. if( !hfont ){
  202. //restore font smoothing
  203. SystemParametersInfo( SPI_SETFONTSMOOTHING,smoothing,0,0 );
  204. return 0;
  205. }
  206. HDC hdc=CreateCompatibleDC( 0 );
  207. HFONT pfont=(HFONT)SelectObject( hdc,hfont );
  208. TEXTMETRIC tm={0};
  209. if( !GetTextMetrics( hdc,&tm ) ){
  210. SelectObject( hdc,pfont );
  211. DeleteDC( hdc );
  212. DeleteObject( hfont );
  213. SystemParametersInfo( SPI_SETFONTSMOOTHING,smoothing,0,0 );
  214. return 0;
  215. }
  216. height=tm.tmHeight;
  217. int first=tm.tmFirstChar,last=tm.tmLastChar;
  218. int sz=last-first+1;
  219. int *offs=d_new int[sz];
  220. int *widths=d_new int[sz];
  221. int *as=d_new int[sz];
  222. //calc size of canvas to hold font.
  223. int x=0,y=0,max_x=0;
  224. for( int k=0;k<sz;++k ){
  225. char t=k+first;
  226. SIZE sz;
  227. GetTextExtentPoint32( hdc,&t,1,&sz );
  228. int w=sz.cx;
  229. as[k]=0;
  230. ABC abc;
  231. if( GetCharABCWidths( hdc,t,t,&abc ) ){
  232. if( abc.abcA<0 ){
  233. as[k]=ceil(-abc.abcA);
  234. w+=as[k];
  235. }
  236. if( abc.abcC<0 ) w+=ceil(-abc.abcC);
  237. }
  238. if( x && x+w>getWidth() ){ x=0;y+=height; }
  239. offs[k]=(x<<16)|y;
  240. widths[k]=w;
  241. x+=w;if( x>max_x ) max_x=x;
  242. }
  243. SelectObject( hdc,pfont );
  244. DeleteDC( hdc );
  245. int cw=max_x,ch=y+height;
  246. if( gxCanvas *c=createCanvas( cw,ch,0 ) ){
  247. ddSurf *surf=c->getSurface();
  248. HDC surf_hdc;
  249. if( surf->GetDC( &surf_hdc )>=0 ){
  250. HFONT pfont=(HFONT)SelectObject( surf_hdc,hfont );
  251. SetBkColor( surf_hdc,0x000000 );
  252. SetTextColor( surf_hdc,0xffffff );
  253. for( int k=0;k<sz;++k ){
  254. int x=(offs[k]>>16)&0xffff,y=offs[k]&0xffff;
  255. char t=k+first;
  256. RECT rect={x,y,x+widths[k],y+height};
  257. ExtTextOut( surf_hdc,x+as[k],y,ETO_CLIPPED,&rect,&t,1,0 );
  258. }
  259. SelectObject( surf_hdc,pfont );
  260. surf->ReleaseDC( surf_hdc );
  261. DeleteObject( hfont );
  262. delete[] as;
  263. c->backup();
  264. gxFont *font=d_new gxFont( this,c,tm.tmMaxCharWidth,height,first,last+1,tm.tmDefaultChar,offs,widths );
  265. font_set.insert( font );
  266. //restore font smoothing
  267. SystemParametersInfo( SPI_SETFONTSMOOTHING,smoothing,0,0 );
  268. return font;
  269. }else{
  270. }
  271. freeCanvas( c );
  272. }else{
  273. }
  274. DeleteObject( hfont );
  275. delete[] as;
  276. delete[] widths;
  277. delete[] offs;
  278. //restore font smoothing
  279. SystemParametersInfo( SPI_SETFONTSMOOTHING,smoothing,0,0 );
  280. return 0;
  281. }
  282. gxFont *gxGraphics::verifyFont( gxFont *f ){
  283. return font_set.count( f ) ? f : 0;
  284. }
  285. void gxGraphics::freeFont( gxFont *f ){
  286. if( font_set.erase( f ) ) delete f;
  287. }
  288. //////////////
  289. // 3D STUFF //
  290. //////////////
  291. #ifdef PRO
  292. static int maxDevType;
  293. static HRESULT CALLBACK enumDevice( char *desc,char *name,D3DDEVICEDESC7 *devDesc,void *context ){
  294. gxGraphics *g=(gxGraphics*)context;
  295. int t=0;
  296. GUID guid=devDesc->deviceGUID;
  297. if( guid==IID_IDirect3DRGBDevice ) t=1;
  298. else if( guid==IID_IDirect3DHALDevice ) t=2;
  299. else if( guid==IID_IDirect3DTnLHalDevice ) t=3;
  300. if( t>maxDevType ){
  301. g->dir3dDevDesc=*devDesc;
  302. maxDevType=t;
  303. }
  304. return D3DENUMRET_OK;
  305. }
  306. static HRESULT CALLBACK enumZbuffFormat( LPDDPIXELFORMAT format,void *context ){
  307. gxGraphics *g=(gxGraphics*)context;
  308. if( format->dwZBufferBitDepth==g->primFmt.dwRGBBitCount ){
  309. g->zbuffFmt=*format;
  310. return D3DENUMRET_CANCEL;
  311. }
  312. if( format->dwZBufferBitDepth>g->zbuffFmt.dwZBufferBitDepth ){
  313. if( format->dwZBufferBitDepth<g->primFmt.dwRGBBitCount ){
  314. g->zbuffFmt=*format;
  315. }
  316. }
  317. return D3DENUMRET_OK;
  318. }
  319. struct TexFmt{
  320. DDPIXELFORMAT fmt;
  321. int bits,a_bits,rgb_bits;
  322. };
  323. static int cntBits( int mask ){
  324. int n=0;
  325. for( int k=0;k<32;++k ){
  326. if( mask & (1<<k) ) ++n;
  327. }
  328. return n;
  329. }
  330. static vector<TexFmt> tex_fmts;
  331. static HRESULT CALLBACK enumTextureFormat( DDPIXELFORMAT *fmt,void *p ){
  332. TexFmt t;
  333. t.fmt=*fmt;
  334. t.bits=fmt->dwRGBBitCount;
  335. t.a_bits=(fmt->dwFlags & DDPF_ALPHAPIXELS) ? cntBits(fmt->dwRGBAlphaBitMask) : 0;
  336. t.rgb_bits=(fmt->dwFlags & DDPF_RGB) ? cntBits(fmt->dwRBitMask|fmt->dwGBitMask|fmt->dwBBitMask) : 0;
  337. tex_fmts.push_back( t );
  338. return D3DENUMRET_OK;
  339. }
  340. static string itobin( int n ){
  341. string t;
  342. for( int k=0;k<32;n<<=1,++k ){
  343. t+=(n&0x80000000) ? '1' : '0';
  344. }
  345. return t;
  346. }
  347. static void debugPF( const DDPIXELFORMAT &pf ){
  348. string t;
  349. t="Bits:"+itoa( pf.dwRGBBitCount );
  350. gx_runtime->debugLog( t.c_str() );
  351. t="R Mask:"+itobin( pf.dwRBitMask );
  352. gx_runtime->debugLog( t.c_str() );
  353. t="G Mask:"+itobin( pf.dwGBitMask );
  354. gx_runtime->debugLog( t.c_str() );
  355. t="B Mask:"+itobin( pf.dwBBitMask );
  356. gx_runtime->debugLog( t.c_str() );
  357. t="A Mask:"+itobin( pf.dwRGBAlphaBitMask );
  358. gx_runtime->debugLog( t.c_str() );
  359. }
  360. static void pickTexFmts( gxGraphics *g,int hi ){
  361. //texRGBFmt.
  362. {
  363. int pick=-1,max=0,bits;
  364. for( int d=g->primFmt.dwRGBBitCount;d<=32;d+=8 ){
  365. for( int k=0;k<tex_fmts.size();++k ){
  366. const TexFmt &t=tex_fmts[k];
  367. if( t.bits>d || !t.rgb_bits || t.rgb_bits<max ) continue;
  368. if( t.rgb_bits==max && t.bits>=bits ) continue;
  369. pick=k;max=t.rgb_bits;bits=t.bits;
  370. }
  371. if( !hi && pick>=0 ) break;
  372. }
  373. if( pick<0 ) g->texRGBFmt[hi]=g->primFmt;
  374. else g->texRGBFmt[hi]=tex_fmts[pick].fmt;
  375. }
  376. //texAlphaFmt
  377. {
  378. int pick=-1,max=0,bits;
  379. for( int d=g->primFmt.dwRGBBitCount;d<=32;d+=8 ){
  380. for( int k=0;k<tex_fmts.size();++k ){
  381. const TexFmt &t=tex_fmts[k];
  382. if( t.bits>d || !t.a_bits || t.a_bits<max ) continue;
  383. if( t.a_bits==max && t.bits>=bits ) continue;
  384. pick=k;max=t.a_bits;bits=t.bits;
  385. }
  386. if( !hi && pick>=0 ) break;
  387. }
  388. if( pick<0 ) g->texAlphaFmt[hi]=g->primFmt;
  389. else g->texAlphaFmt[hi]=tex_fmts[pick].fmt;
  390. }
  391. //texRGBAlphaFmt
  392. {
  393. int pick=-1,a8rgb8=-1,max=0,bits;
  394. for( int d=g->primFmt.dwRGBBitCount;d<=32;d+=8 ){
  395. for( int k=0;k<tex_fmts.size();++k ){
  396. const TexFmt &t=tex_fmts[k];
  397. if( t.a_bits==8 && t.bits==16 ){ a8rgb8=k;continue; }
  398. if( t.bits>d || !t.a_bits || !t.rgb_bits || t.a_bits<max ) continue;
  399. if( t.a_bits==max && t.bits>=bits ) continue;
  400. pick=k;max=t.a_bits;bits=t.bits;
  401. }
  402. if( !hi && pick>=0 ) break;
  403. }
  404. if( pick<0 ) pick=a8rgb8;
  405. if( pick<0 ) g->texRGBAlphaFmt[hi]=g->primFmt;
  406. else g->texRGBAlphaFmt[hi]=tex_fmts[pick].fmt;
  407. }
  408. //texRGBMaskFmt...
  409. {
  410. int pick=-1,max=0,bits;
  411. for( int d=g->primFmt.dwRGBBitCount;d<=32;d+=8 ){
  412. for( int k=0;k<tex_fmts.size();++k ){
  413. const TexFmt &t=tex_fmts[k];
  414. if( !t.a_bits || !t.rgb_bits || t.rgb_bits<max ) continue;
  415. if( t.rgb_bits==max && t.bits>=bits ) continue;
  416. pick=k;max=t.rgb_bits;bits=t.bits;
  417. }
  418. if( !hi && pick>=0 ) break;
  419. }
  420. if( pick<0 ) g->texRGBMaskFmt[hi]=g->primFmt;
  421. else g->texRGBMaskFmt[hi]=tex_fmts[pick].fmt;
  422. }
  423. }
  424. gxScene *gxGraphics::createScene( int flags ){
  425. if( scene_set.size() ) return 0;
  426. //get d3d
  427. if( dirDraw->QueryInterface( IID_IDirect3D7,(void**)&dir3d )>=0 ){
  428. //enum devices
  429. maxDevType=0;
  430. if( dir3d->EnumDevices( enumDevice,this )>=0 && maxDevType>1 ){
  431. //enum zbuffer formats
  432. zbuffFmt.dwZBufferBitDepth=0;
  433. if( dir3d->EnumZBufferFormats( dir3dDevDesc.deviceGUID,enumZbuffFormat,this )>=0 ){
  434. //create zbuff for back buffer
  435. if( back_canvas->attachZBuffer() ){
  436. //create 3d device
  437. if( dir3d->CreateDevice( dir3dDevDesc.deviceGUID,back_canvas->getSurface(),&dir3dDev )>=0 ){
  438. //enum texture formats
  439. tex_fmts.clear();
  440. if( dir3dDev->EnumTextureFormats( enumTextureFormat,this )>=0 ){
  441. pickTexFmts( this,0 );
  442. pickTexFmts( this,1 );
  443. tex_fmts.clear();
  444. #ifdef BETA
  445. gx_runtime->debugLog( "Texture RGB format:" );
  446. debugPF( texRGBFmt );
  447. gx_runtime->debugLog( "Texture Alpha format:" );
  448. debugPF( texAlphaFmt );
  449. gx_runtime->debugLog( "Texture RGB Alpha format:" );
  450. debugPF( texRGBAlphaFmt );
  451. gx_runtime->debugLog( "Texture RGB Mask format:" );
  452. debugPF( texRGBMaskFmt );
  453. gx_runtime->debugLog( "Texture Primary format:" );
  454. debugPF( primFmt );
  455. string ts="ZBuffer Bit Depth:"+itoa( zbuffFmt.dwZBufferBitDepth );
  456. gx_runtime->debugLog( ts.c_str() );
  457. #endif
  458. gxScene *scene=d_new gxScene( this,back_canvas );
  459. scene_set.insert( scene );
  460. dummy_mesh=createMesh( 8,12,0 );
  461. return scene;
  462. }
  463. dir3dDev->Release();
  464. dir3dDev=0;
  465. }
  466. back_canvas->releaseZBuffer();
  467. }
  468. }
  469. }
  470. dir3d->Release();
  471. dir3d=0;
  472. }
  473. return 0;
  474. }
  475. gxScene *gxGraphics::verifyScene( gxScene *s ){
  476. return scene_set.count( s ) ? s : 0;
  477. }
  478. void gxGraphics::freeScene( gxScene *scene ){
  479. if( !scene_set.erase( scene ) ) return;
  480. dummy_mesh=0;
  481. while( mesh_set.size() ) freeMesh( *mesh_set.begin() );
  482. back_canvas->releaseZBuffer();
  483. if( dir3dDev ){ dir3dDev->Release();dir3dDev=0; }
  484. if( dir3d ){ dir3d->Release();dir3d=0; }
  485. delete scene;
  486. }
  487. gxMesh *gxGraphics::createMesh( int max_verts,int max_tris,int flags ){
  488. static const int VTXFMT=
  489. D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_TEX2|
  490. D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1);
  491. int vbflags=0;
  492. //XP or less?
  493. if( runtime->osinfo.dwMajorVersion<6 ){
  494. vbflags|=D3DVBCAPS_WRITEONLY;
  495. }
  496. D3DVERTEXBUFFERDESC desc={ sizeof(desc),vbflags,VTXFMT,max_verts };
  497. IDirect3DVertexBuffer7 *buff;
  498. if( dir3d->CreateVertexBuffer( &desc,&buff,0 )<0 ) return 0;
  499. WORD *indices=d_new WORD[max_tris*3];
  500. gxMesh *mesh=d_new gxMesh( this,buff,indices,max_verts,max_tris );
  501. mesh_set.insert( mesh );
  502. return mesh;
  503. }
  504. gxMesh *gxGraphics::verifyMesh( gxMesh *m ){
  505. return mesh_set.count( m ) ? m : 0;
  506. }
  507. void gxGraphics::freeMesh( gxMesh *mesh ){
  508. if( mesh_set.erase( mesh ) ) delete mesh;
  509. }
  510. #endif