graphics.cpp
上传用户:jnfxsk
上传日期:2022-06-16
资源大小:3675k
文件大小:24k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /*
  2. ** Haaf's Game Engine 1.8
  3. ** Copyright (C) 2003-2007, Relish Games
  4. ** hge.relishgames.com
  5. **
  6. ** Core functions implementation: graphics
  7. */
  8. #include "hge_impl.h"
  9. #include <d3d8.h>
  10. #include <d3dx8.h>
  11. void CALL HGE_Impl::Gfx_Clear(DWORD color)
  12. {
  13. if(pCurTarget)
  14. {
  15. if(pCurTarget->pDepth)
  16. pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, color, 1.0f, 0 );
  17. else
  18. pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, color, 1.0f, 0 );
  19. }
  20. else
  21. {
  22. if(bZBuffer)
  23. pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, color, 1.0f, 0 );
  24. else
  25. pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, color, 1.0f, 0 );
  26. }
  27. }
  28. void CALL HGE_Impl::Gfx_SetClipping(int x, int y, int w, int h)
  29. {
  30. D3DVIEWPORT8 vp;
  31. int scr_width, scr_height;
  32. if(!pCurTarget) {
  33. scr_width=pHGE->System_GetStateInt(HGE_SCREENWIDTH);
  34. scr_height=pHGE->System_GetStateInt(HGE_SCREENHEIGHT);
  35. }
  36. else {
  37. scr_width=Texture_GetWidth((HTEXTURE)pCurTarget->pTex);
  38. scr_height=Texture_GetHeight((HTEXTURE)pCurTarget->pTex);
  39. }
  40. if(!w) {
  41. vp.X=0;
  42. vp.Y=0;
  43. vp.Width=scr_width;
  44. vp.Height=scr_height;
  45. }
  46. else
  47. {
  48. if(x<0) { w+=x; x=0; }
  49. if(y<0) { h+=y; y=0; }
  50. if(x+w > scr_width) w=scr_width-x;
  51. if(y+h > scr_height) h=scr_height-y;
  52. vp.X=x;
  53. vp.Y=y;
  54. vp.Width=w;
  55. vp.Height=h;
  56. }
  57. vp.MinZ=0.0f;
  58. vp.MaxZ=1.0f;
  59. _render_batch();
  60. pD3DDevice->SetViewport(&vp);
  61. D3DXMATRIX tmp;
  62. D3DXMatrixScaling(&matProj, 1.0f, -1.0f, 1.0f);
  63. D3DXMatrixTranslation(&tmp, -0.5f, +0.5f, 0.0f);
  64. D3DXMatrixMultiply(&matProj, &matProj, &tmp);
  65. D3DXMatrixOrthoOffCenterLH(&tmp, (float)vp.X, (float)(vp.X+vp.Width), -((float)(vp.Y+vp.Height)), -((float)vp.Y), vp.MinZ, vp.MaxZ);
  66. D3DXMatrixMultiply(&matProj, &matProj, &tmp);
  67. pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
  68. }
  69. void CALL HGE_Impl::Gfx_SetTransform(float x, float y, float dx, float dy, float rot, float hscale, float vscale)
  70. {
  71. D3DXMATRIX tmp;
  72. if(vscale==0.0f) D3DXMatrixIdentity(&matView);
  73. else
  74. {
  75. D3DXMatrixTranslation(&matView, -x, -y, 0.0f);
  76. D3DXMatrixScaling(&tmp, hscale, vscale, 1.0f);
  77. D3DXMatrixMultiply(&matView, &matView, &tmp);
  78. D3DXMatrixRotationZ(&tmp, -rot);
  79. D3DXMatrixMultiply(&matView, &matView, &tmp);
  80. D3DXMatrixTranslation(&tmp, x+dx, y+dy, 0.0f);
  81. D3DXMatrixMultiply(&matView, &matView, &tmp);
  82. }
  83. _render_batch();
  84. pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
  85. }
  86. bool CALL HGE_Impl::Gfx_BeginScene(HTARGET targ)
  87. {
  88. LPDIRECT3DSURFACE8 pSurf=0, pDepth=0;
  89. D3DDISPLAYMODE Mode;
  90. CRenderTargetList *target=(CRenderTargetList *)targ;
  91. HRESULT hr = pD3DDevice->TestCooperativeLevel();
  92. if (hr == D3DERR_DEVICELOST) return false;
  93. else if (hr == D3DERR_DEVICENOTRESET)
  94. {
  95. if(bWindowed)
  96. {
  97. if(FAILED(pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Mode)) || Mode.Format==D3DFMT_UNKNOWN) 
  98. {
  99. _PostError("Can't determine desktop video mode");
  100. return false;
  101. }
  102. d3dppW.BackBufferFormat = Mode.Format;
  103. if(_format_id(Mode.Format) < 4) nScreenBPP=16;
  104. else nScreenBPP=32;
  105. }
  106.     if(!_GfxRestore()) return false; 
  107. }
  108.     
  109. if(VertArray)
  110. {
  111. _PostError("Gfx_BeginScene: Scene is already being rendered");
  112. return false;
  113. }
  114. if(target != pCurTarget)
  115. {
  116. if(target)
  117. {
  118. target->pTex->GetSurfaceLevel(0, &pSurf);
  119. pDepth=target->pDepth;
  120. }
  121. else
  122. {
  123. pSurf=pScreenSurf;
  124. pDepth=pScreenDepth;
  125. }
  126. if(FAILED(pD3DDevice->SetRenderTarget(pSurf, pDepth)))
  127. {
  128. if(target) pSurf->Release();
  129. _PostError("Gfx_BeginScene: Can't set render target");
  130. return false;
  131. }
  132. if(target)
  133. {
  134. pSurf->Release();
  135. if(target->pDepth) pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE ); 
  136. else pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE ); 
  137. _SetProjectionMatrix(target->width, target->height);
  138. }
  139. else
  140. {
  141. if(bZBuffer) pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE ); 
  142. else pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );
  143. _SetProjectionMatrix(nScreenWidth, nScreenHeight);
  144. }
  145. pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
  146. D3DXMatrixIdentity(&matView);
  147. pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
  148. pCurTarget=target;
  149. }
  150. pD3DDevice->BeginScene();
  151. pVB->Lock( 0, 0, (BYTE**)&VertArray, 0 );
  152. return true;
  153. }
  154. void CALL HGE_Impl::Gfx_EndScene()
  155. {
  156. _render_batch(true);
  157. pD3DDevice->EndScene();
  158. if(!pCurTarget) pD3DDevice->Present( NULL, NULL, NULL, NULL );
  159. }
  160. void CALL HGE_Impl::Gfx_RenderLine(float x1, float y1, float x2, float y2, DWORD color, float z)
  161. {
  162. if(VertArray)
  163. {
  164. if(CurPrimType!=HGEPRIM_LINES || nPrim>=VERTEX_BUFFER_SIZE/HGEPRIM_LINES || CurTexture || CurBlendMode!=BLEND_DEFAULT)
  165. {
  166. _render_batch();
  167. CurPrimType=HGEPRIM_LINES;
  168. if(CurBlendMode != BLEND_DEFAULT) _SetBlendMode(BLEND_DEFAULT);
  169. if(CurTexture) { pD3DDevice->SetTexture(0, 0); CurTexture=0; }
  170. }
  171. int i=nPrim*HGEPRIM_LINES;
  172. VertArray[i].x = x1; VertArray[i+1].x = x2;
  173. VertArray[i].y = y1; VertArray[i+1].y = y2;
  174. VertArray[i].z     = VertArray[i+1].z = z;
  175. VertArray[i].col   = VertArray[i+1].col = color;
  176. VertArray[i].tx    = VertArray[i+1].tx =
  177. VertArray[i].ty    = VertArray[i+1].ty = 0.0f;
  178. nPrim++;
  179. }
  180. }
  181. void CALL HGE_Impl::Gfx_RenderTriple(const hgeTriple *triple)
  182. {
  183. if(VertArray)
  184. {
  185. if(CurPrimType!=HGEPRIM_TRIPLES || nPrim>=VERTEX_BUFFER_SIZE/HGEPRIM_TRIPLES || CurTexture!=triple->tex || CurBlendMode!=triple->blend)
  186. {
  187. _render_batch();
  188. CurPrimType=HGEPRIM_TRIPLES;
  189. if(CurBlendMode != triple->blend) _SetBlendMode(triple->blend);
  190. if(triple->tex != CurTexture) {
  191. pD3DDevice->SetTexture( 0, (LPDIRECT3DTEXTURE8)triple->tex );
  192. CurTexture = triple->tex;
  193. }
  194. }
  195. memcpy(&VertArray[nPrim*HGEPRIM_TRIPLES], triple->v, sizeof(hgeVertex)*HGEPRIM_TRIPLES);
  196. nPrim++;
  197. }
  198. }
  199. void CALL HGE_Impl::Gfx_RenderQuad(const hgeQuad *quad)
  200. {
  201. if(VertArray)
  202. {
  203. if(CurPrimType!=HGEPRIM_QUADS || nPrim>=VERTEX_BUFFER_SIZE/HGEPRIM_QUADS || CurTexture!=quad->tex || CurBlendMode!=quad->blend)
  204. {
  205. _render_batch();
  206. CurPrimType=HGEPRIM_QUADS;
  207. if(CurBlendMode != quad->blend) _SetBlendMode(quad->blend);
  208. if(quad->tex != CurTexture)
  209. {
  210. pD3DDevice->SetTexture( 0, (LPDIRECT3DTEXTURE8)quad->tex );
  211. CurTexture = quad->tex;
  212. }
  213. }
  214. memcpy(&VertArray[nPrim*HGEPRIM_QUADS], quad->v, sizeof(hgeVertex)*HGEPRIM_QUADS);
  215. nPrim++;
  216. }
  217. }
  218. hgeVertex* CALL HGE_Impl::Gfx_StartBatch(int prim_type, HTEXTURE tex, int blend, int *max_prim)
  219. {
  220. if(VertArray)
  221. {
  222. _render_batch();
  223. CurPrimType=prim_type;
  224. if(CurBlendMode != blend) _SetBlendMode(blend);
  225. if(tex != CurTexture)
  226. {
  227. pD3DDevice->SetTexture( 0, (LPDIRECT3DTEXTURE8)tex );
  228. CurTexture = tex;
  229. }
  230. *max_prim=VERTEX_BUFFER_SIZE / prim_type;
  231. return VertArray;
  232. }
  233. else return 0;
  234. }
  235. void CALL HGE_Impl::Gfx_FinishBatch(int nprim)
  236. {
  237. nPrim=nprim;
  238. }
  239. HTARGET CALL HGE_Impl::Target_Create(int width, int height, bool zbuffer)
  240. {
  241. CRenderTargetList *pTarget;
  242. D3DSURFACE_DESC TDesc;
  243. pTarget = new CRenderTargetList;
  244. pTarget->pTex=0;
  245. pTarget->pDepth=0;
  246. if(FAILED(D3DXCreateTexture(pD3DDevice, width, height, 1, D3DUSAGE_RENDERTARGET,
  247. d3dpp->BackBufferFormat, D3DPOOL_DEFAULT, &pTarget->pTex)))
  248. {
  249. _PostError("Can't create render target texture");
  250. delete pTarget;
  251. return 0;
  252. }
  253. pTarget->pTex->GetLevelDesc(0, &TDesc);
  254. pTarget->width=TDesc.Width;
  255. pTarget->height=TDesc.Height;
  256. if(zbuffer)
  257. {
  258. if(FAILED(pD3DDevice->CreateDepthStencilSurface(pTarget->width, pTarget->height,
  259. D3DFMT_D16, D3DMULTISAMPLE_NONE, &pTarget->pDepth)))
  260. {   
  261. pTarget->pTex->Release();
  262. _PostError("Can't create render target depth buffer");
  263. delete pTarget;
  264. return 0;
  265. }
  266. }
  267. pTarget->next=pTargets;
  268. pTargets=pTarget;
  269. return (HTARGET)pTarget;
  270. }
  271. void CALL HGE_Impl::Target_Free(HTARGET target)
  272. {
  273. CRenderTargetList *pTarget=pTargets, *pPrevTarget=NULL;
  274. while(pTarget)
  275. {
  276. if((CRenderTargetList *)target == pTarget)
  277. {
  278. if(pPrevTarget)
  279. pPrevTarget->next = pTarget->next;
  280. else
  281. pTargets = pTarget->next;
  282. if(pTarget->pTex) pTarget->pTex->Release();
  283. if(pTarget->pDepth) pTarget->pDepth->Release();
  284. delete pTarget;
  285. return;
  286. }
  287. pPrevTarget = pTarget;
  288. pTarget = pTarget->next;
  289. }
  290. }
  291. HTEXTURE CALL HGE_Impl::Target_GetTexture(HTARGET target)
  292. {
  293. CRenderTargetList *targ=(CRenderTargetList *)target;
  294. if(target) return (HTEXTURE)targ->pTex;
  295. else return 0;
  296. }
  297. HTEXTURE CALL HGE_Impl::Texture_Create(int width, int height)
  298. {
  299. LPDIRECT3DTEXTURE8 pTex;
  300. if( FAILED( D3DXCreateTexture( pD3DDevice, width, height,
  301. 1, // Mip levels
  302. 0, // Usage
  303. D3DFMT_A8R8G8B8, // Format
  304. D3DPOOL_MANAGED, // Memory pool
  305. &pTex ) ) )
  306. {
  307. _PostError("Can't create texture");
  308. return NULL;
  309. }
  310. return (HTEXTURE)pTex;
  311. }
  312. HTEXTURE CALL HGE_Impl::Texture_Load(const char *filename, DWORD size, bool bMipmap)
  313. {
  314. void *data;
  315. DWORD _size;
  316. D3DFORMAT fmt1, fmt2;
  317. LPDIRECT3DTEXTURE8 pTex;
  318. D3DXIMAGE_INFO info;
  319. CTextureList *texItem;
  320. if(size) { data=(void *)filename; _size=size; }
  321. else
  322. {
  323. data=pHGE->Resource_Load(filename, &_size);
  324. if(!data) return NULL;
  325. }
  326. if(*(DWORD*)data == 0x20534444) // Compressed DDS format magic number
  327. {
  328. fmt1=D3DFMT_UNKNOWN;
  329. fmt2=D3DFMT_A8R8G8B8;
  330. }
  331. else
  332. {
  333. fmt1=D3DFMT_A8R8G8B8;
  334. fmt2=D3DFMT_UNKNOWN;
  335. }
  336. // if( FAILED( D3DXCreateTextureFromFileInMemory( pD3DDevice, data, _size, &pTex ) ) ) pTex=NULL;
  337. if( FAILED( D3DXCreateTextureFromFileInMemoryEx( pD3DDevice, data, _size,
  338. D3DX_DEFAULT, D3DX_DEFAULT,
  339. bMipmap ? 0:1, // Mip levels
  340. 0, // Usage
  341. fmt1, // Format
  342. D3DPOOL_MANAGED, // Memory pool
  343. D3DX_FILTER_NONE, // Filter
  344. D3DX_DEFAULT, // Mip filter
  345. 0, // Color key
  346. &info, NULL,
  347. &pTex ) ) )
  348. if( FAILED( D3DXCreateTextureFromFileInMemoryEx( pD3DDevice, data, _size,
  349. D3DX_DEFAULT, D3DX_DEFAULT,
  350. bMipmap ? 0:1, // Mip levels
  351. 0, // Usage
  352. fmt2, // Format
  353. D3DPOOL_MANAGED, // Memory pool
  354. D3DX_FILTER_NONE, // Filter
  355. D3DX_DEFAULT, // Mip filter
  356. 0, // Color key
  357. &info, NULL,
  358. &pTex ) ) )
  359. {
  360. _PostError("Can't create texture");
  361. if(!size) Resource_Free(data);
  362. return NULL;
  363. }
  364. if(!size) Resource_Free(data);
  365. texItem=new CTextureList;
  366. texItem->tex=(HTEXTURE)pTex;
  367. texItem->width=info.Width;
  368. texItem->height=info.Height;
  369. texItem->next=textures;
  370. textures=texItem;
  371. return (HTEXTURE)pTex;
  372. }
  373. void CALL HGE_Impl::Texture_Free(HTEXTURE tex)
  374. {
  375. LPDIRECT3DTEXTURE8 pTex=(LPDIRECT3DTEXTURE8)tex;
  376. CTextureList *texItem=textures, *texPrev=0;
  377. while(texItem)
  378. {
  379. if(texItem->tex==tex)
  380. {
  381. if(texPrev) texPrev->next=texItem->next;
  382. else textures=texItem->next;
  383. delete texItem;
  384. break;
  385. }
  386. texPrev=texItem;
  387. texItem=texItem->next;
  388. }
  389. if(pTex != NULL) pTex->Release();
  390. }
  391. int CALL HGE_Impl::Texture_GetWidth(HTEXTURE tex, bool bOriginal)
  392. {
  393. D3DSURFACE_DESC TDesc;
  394. LPDIRECT3DTEXTURE8 pTex=(LPDIRECT3DTEXTURE8)tex;
  395. CTextureList *texItem=textures;
  396. if(bOriginal)
  397. {
  398. while(texItem)
  399. {
  400. if(texItem->tex==tex) return texItem->width;
  401. texItem=texItem->next;
  402. }
  403. return 0;
  404. }
  405. else
  406. {
  407. if(FAILED(pTex->GetLevelDesc(0, &TDesc))) return 0;
  408. else return TDesc.Width;
  409. }
  410. }
  411. int CALL HGE_Impl::Texture_GetHeight(HTEXTURE tex, bool bOriginal)
  412. {
  413. D3DSURFACE_DESC TDesc;
  414. LPDIRECT3DTEXTURE8 pTex=(LPDIRECT3DTEXTURE8)tex;
  415. CTextureList *texItem=textures;
  416. if(bOriginal)
  417. {
  418. while(texItem)
  419. {
  420. if(texItem->tex==tex) return texItem->height;
  421. texItem=texItem->next;
  422. }
  423. return 0;
  424. }
  425. else
  426. {
  427. if(FAILED(pTex->GetLevelDesc(0, &TDesc))) return 0;
  428. else return TDesc.Height;
  429. }
  430. }
  431. DWORD * CALL HGE_Impl::Texture_Lock(HTEXTURE tex, bool bReadOnly, int left, int top, int width, int height)
  432. {
  433. LPDIRECT3DTEXTURE8 pTex=(LPDIRECT3DTEXTURE8)tex;
  434. D3DSURFACE_DESC TDesc;
  435. D3DLOCKED_RECT TRect;
  436. RECT region, *prec;
  437. int flags;
  438. pTex->GetLevelDesc(0, &TDesc);
  439. if(TDesc.Format!=D3DFMT_A8R8G8B8 && TDesc.Format!=D3DFMT_X8R8G8B8) return 0;
  440. if(width && height)
  441. {
  442. region.left=left;
  443. region.top=top;
  444. region.right=left+width;
  445. region.bottom=top+height;
  446. prec=&region;
  447. }
  448. else prec=0;
  449. if(bReadOnly) flags=D3DLOCK_READONLY;
  450. else flags=0;
  451. if(FAILED(pTex->LockRect(0, &TRect, prec, flags)))
  452. {
  453. _PostError("Can't lock texture");
  454. return 0;
  455. }
  456. return (DWORD *)TRect.pBits;
  457. }
  458. void CALL HGE_Impl::Texture_Unlock(HTEXTURE tex)
  459. {
  460. LPDIRECT3DTEXTURE8 pTex=(LPDIRECT3DTEXTURE8)tex;
  461. pTex->UnlockRect(0);
  462. }
  463. //////// Implementation ////////
  464. void HGE_Impl::_render_batch(bool bEndScene)
  465. {
  466. if(VertArray)
  467. {
  468. pVB->Unlock();
  469. if(nPrim)
  470. {
  471. switch(CurPrimType)
  472. {
  473. case HGEPRIM_QUADS:
  474. pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, nPrim<<2, 0, nPrim<<1);
  475. break;
  476. case HGEPRIM_TRIPLES:
  477. pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, nPrim);
  478. break;
  479. case HGEPRIM_LINES:
  480. pD3DDevice->DrawPrimitive(D3DPT_LINELIST, 0, nPrim);
  481. break;
  482. }
  483. nPrim=0;
  484. }
  485. if(bEndScene) VertArray = 0;
  486. else pVB->Lock( 0, 0, (BYTE**)&VertArray, 0 );
  487. }
  488. }
  489. void HGE_Impl::_SetBlendMode(int blend)
  490. {
  491. if((blend & BLEND_ALPHABLEND) != (CurBlendMode & BLEND_ALPHABLEND))
  492. {
  493. if(blend & BLEND_ALPHABLEND) pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  494. else pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
  495. }
  496.     if((blend & BLEND_ZWRITE) != (CurBlendMode & BLEND_ZWRITE))
  497. {
  498. if(blend & BLEND_ZWRITE) pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
  499. else pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
  500. }
  501. if((blend & BLEND_COLORADD) != (CurBlendMode & BLEND_COLORADD))
  502. {
  503. if(blend & BLEND_COLORADD) pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_ADD);
  504. else pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
  505. }
  506. CurBlendMode = blend;
  507. }
  508. void HGE_Impl::_SetProjectionMatrix(int width, int height)
  509. {
  510. D3DXMATRIX tmp;
  511. D3DXMatrixScaling(&matProj, 1.0f, -1.0f, 1.0f);
  512. D3DXMatrixTranslation(&tmp, -0.5f, height+0.5f, 0.0f);
  513. D3DXMatrixMultiply(&matProj, &matProj, &tmp);
  514. D3DXMatrixOrthoOffCenterLH(&tmp, 0, (float)width, 0, (float)height, 0.0f, 1.0f);
  515. D3DXMatrixMultiply(&matProj, &matProj, &tmp);
  516. }
  517. bool HGE_Impl::_GfxInit()
  518. {
  519. static const char *szFormats[]={"UNKNOWN", "R5G6B5", "X1R5G5B5", "A1R5G5B5", "X8R8G8B8", "A8R8G8B8"};
  520. D3DADAPTER_IDENTIFIER8 AdID;
  521. D3DDISPLAYMODE Mode;
  522. D3DFORMAT Format=D3DFMT_UNKNOWN;
  523. UINT nModes, i;
  524. // Init D3D
  525. pD3D=Direct3DCreate8(120); // D3D_SDK_VERSION
  526. if(pD3D==NULL)
  527. {
  528. _PostError("Can't create D3D interface");
  529. return false;
  530. }
  531. // Get adapter info
  532. pD3D->GetAdapterIdentifier(D3DADAPTER_DEFAULT, D3DENUM_NO_WHQL_LEVEL, &AdID);
  533. System_Log("D3D Driver: %s",AdID.Driver);
  534. System_Log("Description: %s",AdID.Description);
  535. System_Log("Version: %d.%d.%d.%d",
  536. HIWORD(AdID.DriverVersion.HighPart),
  537. LOWORD(AdID.DriverVersion.HighPart),
  538. HIWORD(AdID.DriverVersion.LowPart),
  539. LOWORD(AdID.DriverVersion.LowPart));
  540. // Set up Windowed presentation parameters
  541. if(FAILED(pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Mode)) || Mode.Format==D3DFMT_UNKNOWN) 
  542. {
  543. _PostError("Can't determine desktop video mode");
  544. if(bWindowed) return false;
  545. }
  546. ZeroMemory(&d3dppW, sizeof(d3dppW));
  547. d3dppW.BackBufferWidth  = nScreenWidth;
  548. d3dppW.BackBufferHeight = nScreenHeight;
  549. d3dppW.BackBufferFormat = Mode.Format;
  550. d3dppW.BackBufferCount  = 1;
  551. d3dppW.MultiSampleType  = D3DMULTISAMPLE_NONE;
  552. d3dppW.hDeviceWindow    = hwnd;
  553. d3dppW.Windowed         = TRUE;
  554. if(nHGEFPS==HGEFPS_VSYNC) d3dppW.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;
  555. else   d3dppW.SwapEffect = D3DSWAPEFFECT_COPY;
  556. if(bZBuffer)
  557. {
  558. d3dppW.EnableAutoDepthStencil = TRUE;
  559. d3dppW.AutoDepthStencilFormat = D3DFMT_D16;
  560. }
  561. // Set up Full Screen presentation parameters
  562. nModes=pD3D->GetAdapterModeCount(D3DADAPTER_DEFAULT);
  563. for(i=0; i<nModes; i++)
  564. {
  565. pD3D->EnumAdapterModes(D3DADAPTER_DEFAULT, i, &Mode);
  566. if(Mode.Width != (UINT)nScreenWidth || Mode.Height != (UINT)nScreenHeight) continue;
  567. if(nScreenBPP==16 && (_format_id(Mode.Format) > _format_id(D3DFMT_A1R5G5B5))) continue;
  568. if(_format_id(Mode.Format) > _format_id(Format)) Format=Mode.Format;
  569. }
  570. if(Format == D3DFMT_UNKNOWN)
  571. {
  572. _PostError("Can't find appropriate full screen video mode");
  573. if(!bWindowed) return false;
  574. }
  575. ZeroMemory(&d3dppFS, sizeof(d3dppFS));
  576. d3dppFS.BackBufferWidth  = nScreenWidth;
  577. d3dppFS.BackBufferHeight = nScreenHeight;
  578. d3dppFS.BackBufferFormat = Format;
  579. d3dppFS.BackBufferCount  = 1;
  580. d3dppFS.MultiSampleType  = D3DMULTISAMPLE_NONE;
  581. d3dppFS.hDeviceWindow    = hwnd;
  582. d3dppFS.Windowed         = FALSE;
  583. d3dppFS.SwapEffect       = D3DSWAPEFFECT_FLIP;
  584. d3dppFS.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  585. if(nHGEFPS==HGEFPS_VSYNC) d3dppFS.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE;
  586. else   d3dppFS.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
  587. if(bZBuffer)
  588. {
  589. d3dppFS.EnableAutoDepthStencil = TRUE;
  590. d3dppFS.AutoDepthStencilFormat = D3DFMT_D16;
  591. }
  592. d3dpp = bWindowed ? &d3dppW : &d3dppFS;
  593. if(_format_id(d3dpp->BackBufferFormat) < 4) nScreenBPP=16;
  594. else nScreenBPP=32;
  595. // Create D3D Device
  596. if( FAILED( pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
  597.                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING,
  598.                                   d3dpp, &pD3DDevice ) ) )
  599. {
  600. _PostError("Can't create D3D device");
  601. return false;
  602. }
  603. _AdjustWindow();
  604. System_Log("Mode: %d x %d x %sn",nScreenWidth,nScreenHeight,szFormats[_format_id(Format)]);
  605. // Create vertex batch buffer
  606. VertArray=0;
  607. textures=0;
  608. // Init all stuff that can be lost
  609. _SetProjectionMatrix(nScreenWidth, nScreenHeight);
  610. D3DXMatrixIdentity(&matView);
  611. if(!_init_lost()) return false;
  612. Gfx_Clear(0);
  613. return true;
  614. }
  615. int HGE_Impl::_format_id(D3DFORMAT fmt)
  616. {
  617. switch(fmt) {
  618. case D3DFMT_R5G6B5: return 1;
  619. case D3DFMT_X1R5G5B5: return 2;
  620. case D3DFMT_A1R5G5B5: return 3;
  621. case D3DFMT_X8R8G8B8: return 4;
  622. case D3DFMT_A8R8G8B8: return 5;
  623. default: return 0;
  624. }
  625. }
  626. void HGE_Impl::_AdjustWindow()
  627. {
  628. RECT *rc;
  629. LONG style;
  630. if(bWindowed) {rc=&rectW; style=styleW; }
  631. else  {rc=&rectFS; style=styleFS; }
  632. SetWindowLong(hwnd, GWL_STYLE, style);
  633. style=GetWindowLong(hwnd, GWL_EXSTYLE);
  634. if(bWindowed)
  635. {
  636. SetWindowLong(hwnd, GWL_EXSTYLE, style & (~WS_EX_TOPMOST));
  637.     SetWindowPos(hwnd, HWND_NOTOPMOST, rc->left, rc->top, rc->right-rc->left, rc->bottom-rc->top, SWP_FRAMECHANGED);
  638. }
  639. else
  640. {
  641. SetWindowLong(hwnd, GWL_EXSTYLE, style | WS_EX_TOPMOST);
  642.     SetWindowPos(hwnd, HWND_TOPMOST, rc->left, rc->top, rc->right-rc->left, rc->bottom-rc->top, SWP_FRAMECHANGED);
  643. }
  644. }
  645. void HGE_Impl::_Resize(int width, int height)
  646. {
  647. if(hwndParent)
  648. {
  649. //if(procFocusLostFunc) procFocusLostFunc();
  650. d3dppW.BackBufferWidth=width;
  651. d3dppW.BackBufferHeight=height;
  652. nScreenWidth=width;
  653. nScreenHeight=height;
  654. _SetProjectionMatrix(nScreenWidth, nScreenHeight);
  655. _GfxRestore();
  656. //if(procFocusGainFunc) procFocusGainFunc();
  657. }
  658. }
  659. void HGE_Impl::_GfxDone()
  660. {
  661. CRenderTargetList *target=pTargets, *next_target;
  662. while(textures) Texture_Free(textures->tex);
  663. if(pScreenSurf) { pScreenSurf->Release(); pScreenSurf=0; }
  664. if(pScreenDepth) { pScreenDepth->Release(); pScreenDepth=0; }
  665. while(target)
  666. {
  667. if(target->pTex) target->pTex->Release();
  668. if(target->pDepth) target->pDepth->Release();
  669. next_target=target->next;
  670. delete target;
  671. target=next_target;
  672. }
  673. pTargets=0;
  674. if(pIB)
  675. {
  676. pD3DDevice->SetIndices(NULL,0);
  677. pIB->Release();
  678. pIB=0;
  679. }
  680. if(pVB)
  681. {
  682. if(VertArray) { pVB->Unlock(); VertArray=0; }
  683. pD3DDevice->SetStreamSource( 0, NULL, sizeof(hgeVertex) );
  684. pVB->Release();
  685. pVB=0;
  686. }
  687. if(pD3DDevice) { pD3DDevice->Release(); pD3DDevice=0; }
  688. if(pD3D) { pD3D->Release(); pD3D=0; }
  689. }
  690. bool HGE_Impl::_GfxRestore()
  691. {
  692. CRenderTargetList *target=pTargets;
  693. //if(!pD3DDevice) return false;
  694. //if(pD3DDevice->TestCooperativeLevel() == D3DERR_DEVICELOST) return;
  695. if(pScreenSurf) pScreenSurf->Release();
  696. if(pScreenDepth) pScreenDepth->Release();
  697. while(target)
  698. {
  699. if(target->pTex) target->pTex->Release();
  700. if(target->pDepth) target->pDepth->Release();
  701. target=target->next;
  702. }
  703. if(pIB)
  704. {
  705. pD3DDevice->SetIndices(NULL,0);
  706. pIB->Release();
  707. }
  708. if(pVB)
  709. {
  710. pD3DDevice->SetStreamSource( 0, NULL, sizeof(hgeVertex) );
  711. pVB->Release();
  712. }
  713. pD3DDevice->Reset(d3dpp);
  714. if(!_init_lost()) return false;
  715. if(procGfxRestoreFunc) return procGfxRestoreFunc();
  716. return true;
  717. }
  718. bool HGE_Impl::_init_lost()
  719. {
  720. CRenderTargetList *target=pTargets;
  721. // Store render target
  722. pScreenSurf=0;
  723. pScreenDepth=0;
  724. pD3DDevice->GetRenderTarget(&pScreenSurf);
  725. pD3DDevice->GetDepthStencilSurface(&pScreenDepth);
  726. while(target)
  727. {
  728. if(target->pTex)
  729. D3DXCreateTexture(pD3DDevice, target->width, target->height, 1, D3DUSAGE_RENDERTARGET,
  730.   d3dpp->BackBufferFormat, D3DPOOL_DEFAULT, &target->pTex);
  731. if(target->pDepth)
  732. pD3DDevice->CreateDepthStencilSurface(target->width, target->height,
  733.   D3DFMT_D16, D3DMULTISAMPLE_NONE, &target->pDepth);
  734. target=target->next;
  735. }
  736. // Create Vertex buffer
  737. if( FAILED (pD3DDevice->CreateVertexBuffer(VERTEX_BUFFER_SIZE*sizeof(hgeVertex),
  738.                                               D3DUSAGE_WRITEONLY,
  739.   D3DFVF_HGEVERTEX,
  740.                                               D3DPOOL_DEFAULT, &pVB )))
  741. {
  742. _PostError("Can't create D3D vertex buffer");
  743. return false;
  744. }
  745. pD3DDevice->SetVertexShader( D3DFVF_HGEVERTEX );
  746. pD3DDevice->SetStreamSource( 0, pVB, sizeof(hgeVertex) );
  747. // Create and setup Index buffer
  748. if( FAILED( pD3DDevice->CreateIndexBuffer(VERTEX_BUFFER_SIZE*6/4*sizeof(WORD),
  749.                                               D3DUSAGE_WRITEONLY,
  750.   D3DFMT_INDEX16,
  751.                                               D3DPOOL_DEFAULT, &pIB ) ) )
  752. {
  753. _PostError("Can't create D3D index buffer");
  754. return false;
  755. }
  756. WORD *pIndices, n=0;
  757. if( FAILED( pIB->Lock( 0, 0, (BYTE**)&pIndices, 0 ) ) )
  758. {
  759. _PostError("Can't lock D3D index buffer");
  760. return false;
  761. }
  762. for(int i=0; i<VERTEX_BUFFER_SIZE/4; i++) {
  763. *pIndices++=n;
  764. *pIndices++=n+1;
  765. *pIndices++=n+2;
  766. *pIndices++=n+2;
  767. *pIndices++=n+3;
  768. *pIndices++=n;
  769. n+=4;
  770. }
  771. pIB->Unlock();
  772. pD3DDevice->SetIndices(pIB,0);
  773. // Set common render states
  774. //pD3DDevice->SetRenderState( D3DRS_LASTPIXEL, FALSE );
  775. pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  776. pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  777. pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE,   TRUE );
  778. pD3DDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
  779. pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
  780. pD3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
  781. pD3DDevice->SetRenderState( D3DRS_ALPHAREF,        0x01 );
  782. pD3DDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
  783. pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
  784. pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  785. pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  786. pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
  787. pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  788. pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
  789. pD3DDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
  790. if(bTextureFilter)
  791. {
  792. pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTEXF_LINEAR);
  793. pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTEXF_LINEAR);
  794. }
  795. else
  796. {
  797. pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTEXF_POINT);
  798. pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTEXF_POINT);
  799. }
  800. nPrim=0;
  801. CurPrimType=HGEPRIM_QUADS;
  802. CurBlendMode = BLEND_DEFAULT;
  803. CurTexture = NULL;
  804. pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
  805. pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
  806. return true;
  807. }