graphics.cpp
上传用户:maxiaolivb
上传日期:2022-06-07
资源大小:915k
文件大小:23k
源码类别:

游戏引擎

开发平台:

Visual C++

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