Gfx_wrapper.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  1. /* Copyright (c) 2002-2012 Croteam Ltd.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of version 2 of the GNU General Public License as published by
  4. the Free Software Foundation
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along
  10. with this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
  12. #include "stdh.h"
  13. #include <Engine/Graphics/GfxLibrary.h>
  14. #include <Engine/Graphics/ViewPort.h>
  15. #include <Engine/Graphics/GfxProfile.h>
  16. #include <Engine/Base/Statistics_internal.h>
  17. //#include <d3dx8math.h>
  18. //#pragma comment(lib, "d3dx8.lib")
  19. //#include <d3dx8tex.h>
  20. //#pragma comment(lib, "d3dx8.lib")
  21. //extern "C" HRESULT WINAPI D3DXGetErrorStringA( HRESULT hr, LPSTR pBuffer, UINT BufferLen);
  22. //char acErrorString[256];
  23. //D3DXGetErrorString( hr, acErrorString, 255);
  24. //ASSERTALWAYS( acErrorString);
  25. extern INDEX gap_bOptimizeStateChanges;
  26. extern INDEX gap_iOptimizeClipping;
  27. extern INDEX gap_iDithering;
  28. // cached states
  29. extern BOOL GFX_bDepthTest = FALSE;
  30. extern BOOL GFX_bDepthWrite = FALSE;
  31. extern BOOL GFX_bAlphaTest = FALSE;
  32. extern BOOL GFX_bDithering = TRUE;
  33. extern BOOL GFX_bBlending = TRUE;
  34. extern BOOL GFX_bClipping = TRUE;
  35. extern BOOL GFX_bClipPlane = FALSE;
  36. extern BOOL GFX_bColorArray = FALSE;
  37. extern BOOL GFX_bTruform = FALSE;
  38. extern BOOL GFX_bFrontFace = TRUE;
  39. extern BOOL GFX_bViewMatrix = TRUE;
  40. extern INDEX GFX_iActiveTexUnit = 0;
  41. extern FLOAT GFX_fMinDepthRange = 0.0f;
  42. extern FLOAT GFX_fMaxDepthRange = 0.0f;
  43. extern GfxBlend GFX_eBlendSrc = GFX_ONE;
  44. extern GfxBlend GFX_eBlendDst = GFX_ZERO;
  45. extern GfxComp GFX_eDepthFunc = GFX_LESS_EQUAL;
  46. extern GfxFace GFX_eCullFace = GFX_NONE;
  47. extern BOOL GFX_abTexture[GFX_MAXTEXUNITS] = { FALSE, FALSE, FALSE, FALSE };
  48. extern INDEX GFX_iTexModulation[GFX_MAXTEXUNITS] = { 0, 0, 0, 0 };
  49. // last ortho/frustum values (frustum has negative sign, because of orgho-frustum switching!)
  50. extern FLOAT GFX_fLastL = 0;
  51. extern FLOAT GFX_fLastR = 0;
  52. extern FLOAT GFX_fLastT = 0;
  53. extern FLOAT GFX_fLastB = 0;
  54. extern FLOAT GFX_fLastN = 0;
  55. extern FLOAT GFX_fLastF = 0;
  56. // number of vertices currently in buffer
  57. extern INDEX GFX_ctVertices = 0;
  58. // for D3D: mark need for clipping (when wants to be disable but cannot be because of user clip plane)
  59. static BOOL _bWantsClipping = TRUE;
  60. // current color mask (for Get... function)
  61. static ULONG _ulCurrentColorMask = (CT_RMASK|CT_GMASK|CT_BMASK|CT_AMASK);
  62. // locking state for OGL
  63. static BOOL _bCVAReallyLocked = FALSE;
  64. // clip plane and last view matrix for D3D
  65. extern FLOAT D3D_afClipPlane[4] = {0,0,0,0};
  66. extern FLOAT D3D_afViewMatrix[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
  67. static FLOAT _afActiveClipPlane[4] = {0,0,0,0};
  68. // Truform/N-Patches
  69. extern INDEX truform_iLevel = -1;
  70. extern BOOL truform_bLinear = FALSE;
  71. // functions' pointers
  72. extern void (*gfxEnableDepthWrite)(void) = NULL;
  73. extern void (*gfxEnableDepthBias)(void) = NULL;
  74. extern void (*gfxEnableDepthTest)(void) = NULL;
  75. extern void (*gfxEnableAlphaTest)(void) = NULL;
  76. extern void (*gfxEnableBlend)(void) = NULL;
  77. extern void (*gfxEnableDither)(void) = NULL;
  78. extern void (*gfxEnableTexture)(void) = NULL;
  79. extern void (*gfxEnableClipping)(void) = NULL;
  80. extern void (*gfxEnableClipPlane)(void) = NULL;
  81. extern void (*gfxDisableDepthWrite)(void) = NULL;
  82. extern void (*gfxDisableDepthBias)(void) = NULL;
  83. extern void (*gfxDisableDepthTest)(void) = NULL;
  84. extern void (*gfxDisableAlphaTest)(void) = NULL;
  85. extern void (*gfxDisableBlend)(void) = NULL;
  86. extern void (*gfxDisableDither)(void) = NULL;
  87. extern void (*gfxDisableTexture)(void) = NULL;
  88. extern void (*gfxDisableClipping)(void) = NULL;
  89. extern void (*gfxDisableClipPlane)(void) = NULL;
  90. extern void (*gfxBlendFunc)( GfxBlend eSrc, GfxBlend eDst) = NULL;
  91. extern void (*gfxDepthFunc)( GfxComp eFunc) = NULL;
  92. extern void (*gfxDepthRange)( FLOAT fMin, FLOAT fMax) = NULL;
  93. extern void (*gfxCullFace)( GfxFace eFace) = NULL;
  94. extern void (*gfxFrontFace)( GfxFace eFace) = NULL;
  95. extern void (*gfxClipPlane)( const DOUBLE *pdPlane) = NULL;
  96. extern void (*gfxSetOrtho)( const FLOAT fLeft, const FLOAT fRight, const FLOAT fTop, const FLOAT fBottom, const FLOAT fNear, const FLOAT fFar, const BOOL bSubPixelAdjust) = NULL;
  97. extern void (*gfxSetFrustum)( const FLOAT fLeft, const FLOAT fRight, const FLOAT fTop, const FLOAT fBottom, const FLOAT fNear, const FLOAT fFar) = NULL;
  98. extern void (*gfxSetTextureMatrix)( const FLOAT *pfMatrix) = NULL;
  99. extern void (*gfxSetViewMatrix)( const FLOAT *pfMatrix) = NULL;
  100. extern void (*gfxPolygonMode)( GfxPolyMode ePolyMode) = NULL;
  101. extern void (*gfxSetTextureWrapping)( enum GfxWrap eWrapU, enum GfxWrap eWrapV) = NULL;
  102. extern void (*gfxSetTextureModulation)( INDEX iScale) = NULL;
  103. extern void (*gfxGenerateTexture)( ULONG &ulTexObject) = NULL;
  104. extern void (*gfxDeleteTexture)( ULONG &ulTexObject) = NULL;
  105. extern void (*gfxSetVertexArray)( GFXVertex4 *pvtx, INDEX ctVtx) = NULL;
  106. extern void (*gfxSetNormalArray)( GFXNormal *pnor) = NULL;
  107. extern void (*gfxSetTexCoordArray)( GFXTexCoord *ptex, BOOL b4) = NULL;
  108. extern void (*gfxSetColorArray)( GFXColor *pcol) = NULL;
  109. extern void (*gfxDrawElements)( INDEX ctElem, INDEX *pidx) = NULL;
  110. extern void (*gfxSetConstantColor)(COLOR col) = NULL;
  111. extern void (*gfxEnableColorArray)(void) = NULL;
  112. extern void (*gfxDisableColorArray)(void) = NULL;
  113. extern void (*gfxFinish)(void) = NULL;
  114. extern void (*gfxLockArrays)(void) = NULL;
  115. extern void (*gfxEnableTruform)( void) = NULL;
  116. extern void (*gfxDisableTruform)(void) = NULL;
  117. extern void (*gfxSetColorMask)( ULONG ulColorMask) = NULL;
  118. // dummy function (one size fits all:)
  119. static void none_void(void)
  120. {
  121. ASSERT( _pGfx->gl_eCurrentAPI==GAT_NONE);
  122. }
  123. // error checkers (this is for debug version only)
  124. extern void OGL_CheckError(void)
  125. {
  126. #ifndef NDEBUG
  127. const GfxAPIType eAPI = _pGfx->gl_eCurrentAPI;
  128. if( eAPI==GAT_OGL) ASSERT( pglGetError()==GL_NO_ERROR);
  129. else ASSERT( eAPI==GAT_NONE);
  130. #endif
  131. }
  132. #ifdef SE1_D3D
  133. extern void D3D_CheckError(HRESULT hr)
  134. {
  135. #ifndef NDEBUG
  136. const GfxAPIType eAPI = _pGfx->gl_eCurrentAPI;
  137. if( eAPI==GAT_D3D) ASSERT( hr==D3D_OK);
  138. else ASSERT( eAPI==GAT_NONE);
  139. #endif
  140. }
  141. #endif // SE1_D3D
  142. // TEXTURE MANAGEMENT
  143. #ifdef SE1_D3D
  144. static LPDIRECT3DTEXTURE8 *_ppd3dCurrentTexture;
  145. #endif // SE1_D3D
  146. extern INDEX GetTexturePixRatio_OGL( GLuint uiBindNo);
  147. extern INDEX GetFormatPixRatio_OGL( GLenum eFormat);
  148. extern void MimicTexParams_OGL( CTexParams &tpLocal);
  149. extern void UploadTexture_OGL( ULONG *pulTexture, PIX pixSizeU, PIX pixSizeV,
  150. GLenum eInternalFormat, BOOL bUseSubImage);
  151. #ifdef SE1_D3D
  152. extern INDEX GetTexturePixRatio_D3D( LPDIRECT3DTEXTURE8 pd3dTexture);
  153. extern INDEX GetFormatPixRatio_D3D( D3DFORMAT d3dFormat);
  154. extern void MimicTexParams_D3D( CTexParams &tpLocal);
  155. extern void UploadTexture_D3D( LPDIRECT3DTEXTURE8 *ppd3dTexture, ULONG *pulTexture,
  156. PIX pixSizeU, PIX pixSizeV, D3DFORMAT eInternalFormat, BOOL bDiscard);
  157. #endif // SE1_D3D
  158. // update texture LOD bias
  159. extern FLOAT _fCurrentLODBias = 0; // LOD bias adjuster
  160. extern void UpdateLODBias( const FLOAT fLODBias)
  161. {
  162. // check API
  163. const GfxAPIType eAPI = _pGfx->gl_eCurrentAPI;
  164. #ifdef SE1_D3D
  165. ASSERT( eAPI==GAT_OGL || eAPI==GAT_D3D || eAPI==GAT_NONE);
  166. #else // SE1_D3D
  167. ASSERT( eAPI==GAT_OGL || eAPI==GAT_NONE);
  168. #endif // SE1_D3D
  169. // only if supported and needed
  170. if( _fCurrentLODBias==fLODBias && _pGfx->gl_fMaxTextureLODBias==0) return;
  171. _fCurrentLODBias = fLODBias;
  172. _sfStats.StartTimer(CStatForm::STI_GFXAPI);
  173. // OpenGL
  174. if( eAPI==GAT_OGL)
  175. { // if no multitexturing
  176. if( _pGfx->gl_ctTextureUnits<2) {
  177. pglTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, fLODBias);
  178. OGL_CHECKERROR;
  179. }
  180. // if multitexturing is active
  181. else {
  182. for( INDEX iUnit=0; iUnit<_pGfx->gl_ctTextureUnits; iUnit++) { // loop thru units
  183. pglActiveTexture(iUnit); // select the unit
  184. pglTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, fLODBias);
  185. OGL_CHECKERROR;
  186. } // reselect the original unit
  187. pglActiveTexture(GFX_iActiveTexUnit);
  188. OGL_CHECKERROR;
  189. }
  190. }
  191. // Direct3D
  192. #ifdef SE1_D3D
  193. else if( eAPI==GAT_D3D)
  194. { // just set it
  195. HRESULT hr;
  196. for( INDEX iUnit=0; iUnit<_pGfx->gl_ctTextureUnits; iUnit++) { // loop thru tex units
  197. hr = _pGfx->gl_pd3dDevice->SetTextureStageState( iUnit, D3DTSS_MIPMAPLODBIAS, *((DWORD*)&fLODBias));
  198. D3D_CHECKERROR(hr);
  199. }
  200. }
  201. #endif // SE1_D3D
  202. _sfStats.StopTimer(CStatForm::STI_GFXAPI);
  203. }
  204. // get current texture filtering mode
  205. extern void gfxGetTextureFiltering( INDEX &iFilterType, INDEX &iAnisotropyDegree)
  206. {
  207. iFilterType = _tpGlobal[0].tp_iFilter;
  208. iAnisotropyDegree = _tpGlobal[0].tp_iAnisotropy;
  209. }
  210. // set texture filtering mode
  211. extern void gfxSetTextureFiltering( INDEX &iFilterType, INDEX &iAnisotropyDegree)
  212. {
  213. // clamp vars
  214. INDEX iMagTex = iFilterType /100; iMagTex = Clamp( iMagTex, 0L, 2L); // 0=same as iMinTex, 1=nearest, 2=linear
  215. INDEX iMinTex = iFilterType /10 %10; iMinTex = Clamp( iMinTex, 1L, 2L); // 1=nearest, 2=linear
  216. INDEX iMinMip = iFilterType %10; iMinMip = Clamp( iMinMip, 0L, 2L); // 0=no mipmapping, 1=nearest, 2=linear
  217. iFilterType = iMagTex*100 + iMinTex*10 + iMinMip;
  218. iAnisotropyDegree = Clamp( iAnisotropyDegree, 1L, _pGfx->gl_iMaxTextureAnisotropy);
  219. // skip if not changed
  220. if( _tpGlobal[0].tp_iFilter==iFilterType && _tpGlobal[0].tp_iAnisotropy==iAnisotropyDegree) return;
  221. _tpGlobal[0].tp_iFilter = iFilterType;
  222. _tpGlobal[0].tp_iAnisotropy = iAnisotropyDegree;
  223. // for OpenGL, that's about it
  224. #ifdef SE1_D3D
  225. if( _pGfx->gl_eCurrentAPI!=GAT_D3D) return;
  226. _sfStats.StartTimer(CStatForm::STI_GFXAPI);
  227. // for D3D, it's a stage state (not texture state), so change it!
  228. HRESULT hr;
  229. _D3DTEXTUREFILTERTYPE eMagFilter, eMinFilter, eMipFilter;
  230. const LPDIRECT3DDEVICE8 pd3dDev = _pGfx->gl_pd3dDevice;
  231. extern void UnpackFilter_D3D( INDEX iFilter, _D3DTEXTUREFILTERTYPE &eMagFilter,
  232. _D3DTEXTUREFILTERTYPE &eMinFilter, _D3DTEXTUREFILTERTYPE &eMipFilter);
  233. UnpackFilter_D3D( iFilterType, eMagFilter, eMinFilter, eMipFilter);
  234. if( iAnisotropyDegree>1) { // adjust filter for anisotropy
  235. eMagFilter = D3DTEXF_ANISOTROPIC;
  236. eMinFilter = D3DTEXF_ANISOTROPIC;
  237. }
  238. // set filtering and anisotropy degree
  239. for( INDEX iUnit=0; iUnit<_pGfx->gl_ctTextureUnits; iUnit++) { // must loop thru all usable texture units
  240. hr = pd3dDev->SetTextureStageState( iUnit, D3DTSS_MAXANISOTROPY, iAnisotropyDegree); D3D_CHECKERROR(hr);
  241. hr = pd3dDev->SetTextureStageState( iUnit, D3DTSS_MAGFILTER, eMagFilter); D3D_CHECKERROR(hr);
  242. hr = pd3dDev->SetTextureStageState( iUnit, D3DTSS_MINFILTER, eMinFilter); D3D_CHECKERROR(hr);
  243. hr = pd3dDev->SetTextureStageState( iUnit, D3DTSS_MIPFILTER, eMipFilter); D3D_CHECKERROR(hr);
  244. }
  245. // done
  246. _sfStats.StopTimer(CStatForm::STI_GFXAPI);
  247. #endif // SE1_D3D
  248. }
  249. // set new texture LOD biasing
  250. extern void gfxSetTextureBiasing( FLOAT &fLODBias)
  251. {
  252. // adjust LOD biasing if needed
  253. fLODBias = Clamp( fLODBias, -_pGfx->gl_fMaxTextureLODBias, +_pGfx->gl_fMaxTextureLODBias);
  254. if( _pGfx->gl_fTextureLODBias != fLODBias) {
  255. _pGfx->gl_fTextureLODBias = fLODBias;
  256. UpdateLODBias( fLODBias);
  257. }
  258. }
  259. // set texture unit as active
  260. extern void gfxSetTextureUnit( INDEX iUnit)
  261. {
  262. // check API
  263. const GfxAPIType eAPI = _pGfx->gl_eCurrentAPI;
  264. #ifdef SE1_D3D
  265. ASSERT( eAPI==GAT_OGL || eAPI==GAT_D3D || eAPI==GAT_NONE);
  266. #else // SE1_D3D
  267. ASSERT( eAPI==GAT_OGL || eAPI==GAT_NONE);
  268. #endif // SE1_D3D
  269. ASSERT( iUnit>=0 && iUnit<4); // supports 4 layers (for now)
  270. // check consistency
  271. #ifndef NDEBUG
  272. if( eAPI==GAT_OGL) {
  273. GLint gliRet;
  274. pglGetIntegerv( GL_ACTIVE_TEXTURE_ARB, &gliRet);
  275. ASSERT( GFX_iActiveTexUnit==(gliRet-GL_TEXTURE0_ARB));
  276. pglGetIntegerv( GL_CLIENT_ACTIVE_TEXTURE_ARB, &gliRet);
  277. ASSERT( GFX_iActiveTexUnit==(gliRet-GL_TEXTURE0_ARB));
  278. }
  279. #endif
  280. // cached?
  281. if( GFX_iActiveTexUnit==iUnit) return;
  282. GFX_iActiveTexUnit = iUnit;
  283. // really set only for OpenGL
  284. if( eAPI!=GAT_OGL) return;
  285. _sfStats.StartTimer(CStatForm::STI_GFXAPI);
  286. pglActiveTexture(iUnit);
  287. _sfStats.StopTimer(CStatForm::STI_GFXAPI);
  288. }
  289. // set texture as current
  290. extern void gfxSetTexture( ULONG &ulTexObject, CTexParams &tpLocal)
  291. {
  292. // clamp texture filtering if needed
  293. static INDEX _iLastTextureFiltering = 0;
  294. if( _iLastTextureFiltering != _tpGlobal[0].tp_iFilter) {
  295. INDEX iMagTex = _tpGlobal[0].tp_iFilter /100; iMagTex = Clamp( iMagTex, 0L, 2L); // 0=same as iMinTex, 1=nearest, 2=linear
  296. INDEX iMinTex = _tpGlobal[0].tp_iFilter /10 %10; iMinTex = Clamp( iMinTex, 1L, 2L); // 1=nearest, 2=linear
  297. INDEX iMinMip = _tpGlobal[0].tp_iFilter %10; iMinMip = Clamp( iMinMip, 0L, 2L); // 0=no mipmapping, 1=nearest, 2=linear
  298. _tpGlobal[0].tp_iFilter = iMagTex*100 + iMinTex*10 + iMinMip;
  299. _iLastTextureFiltering = _tpGlobal[0].tp_iFilter;
  300. }
  301. // determine API and enable texturing
  302. const GfxAPIType eAPI = _pGfx->gl_eCurrentAPI;
  303. #ifdef SE1_D3D
  304. ASSERT(eAPI == GAT_OGL || eAPI == GAT_D3D || eAPI == GAT_NONE);
  305. #else // SE1_D3D
  306. ASSERT(eAPI == GAT_OGL || eAPI == GAT_NONE);
  307. #endif // SE1_D3D
  308. gfxEnableTexture();
  309. _sfStats.StartTimer(CStatForm::STI_BINDTEXTURE);
  310. _sfStats.StartTimer(CStatForm::STI_GFXAPI);
  311. _pfGfxProfile.StartTimer(CGfxProfile::PTI_SETCURRENTTEXTURE);
  312. _pfGfxProfile.IncrementTimerAveragingCounter(CGfxProfile::PTI_SETCURRENTTEXTURE);
  313. if( eAPI==GAT_OGL) { // OpenGL
  314. pglBindTexture( GL_TEXTURE_2D, ulTexObject);
  315. MimicTexParams_OGL(tpLocal);
  316. }
  317. #ifdef SE1_D3D
  318. else if( eAPI==GAT_D3D) { // Direct3D
  319. _ppd3dCurrentTexture = (LPDIRECT3DTEXTURE8*)&ulTexObject;
  320. HRESULT hr = _pGfx->gl_pd3dDevice->SetTexture( GFX_iActiveTexUnit, *_ppd3dCurrentTexture);
  321. D3D_CHECKERROR(hr);
  322. MimicTexParams_D3D(tpLocal);
  323. }
  324. #endif // SE1_D3D
  325. // done
  326. _pfGfxProfile.StopTimer(CGfxProfile::PTI_SETCURRENTTEXTURE);
  327. _sfStats.StopTimer(CStatForm::STI_BINDTEXTURE);
  328. _sfStats.StopTimer(CStatForm::STI_GFXAPI);
  329. }
  330. // upload texture
  331. extern void gfxUploadTexture( ULONG *pulTexture, PIX pixWidth, PIX pixHeight, ULONG ulFormat, BOOL bNoDiscard)
  332. {
  333. // determine API
  334. const GfxAPIType eAPI = _pGfx->gl_eCurrentAPI;
  335. #ifdef SE1_D3D
  336. ASSERT(eAPI == GAT_OGL || eAPI == GAT_D3D || eAPI == GAT_NONE);
  337. #else // SE1_D3D
  338. ASSERT(eAPI == GAT_OGL || eAPI == GAT_NONE);
  339. #endif // SE1_D3D
  340. _sfStats.StartTimer(CStatForm::STI_GFXAPI);
  341. if( eAPI==GAT_OGL) { // OpenGL
  342. UploadTexture_OGL( pulTexture, pixWidth, pixHeight, (GLenum)ulFormat, bNoDiscard);
  343. }
  344. #ifdef SE1_D3D
  345. else if( eAPI==GAT_D3D) { // Direct3D
  346. const LPDIRECT3DTEXTURE8 _pd3dLastTexture = *_ppd3dCurrentTexture;
  347. UploadTexture_D3D( _ppd3dCurrentTexture, pulTexture, pixWidth, pixHeight, (D3DFORMAT)ulFormat, !bNoDiscard);
  348. // in case that texture has been changed, must re-set it as current
  349. if( _pd3dLastTexture != *_ppd3dCurrentTexture) {
  350. HRESULT hr = _pGfx->gl_pd3dDevice->SetTexture( GFX_iActiveTexUnit, *_ppd3dCurrentTexture);
  351. D3D_CHECKERROR(hr);
  352. }
  353. }
  354. #endif // SE1_D3D
  355. _sfStats.StopTimer(CStatForm::STI_GFXAPI);
  356. }
  357. // returns size of uploaded texture
  358. extern SLONG gfxGetTextureSize( ULONG ulTexObject, BOOL bHasMipmaps/*=TRUE*/)
  359. {
  360. // nothing used if nothing uploaded
  361. if( ulTexObject==NULL) return 0;
  362. // determine API
  363. const GfxAPIType eAPI = _pGfx->gl_eCurrentAPI;
  364. #ifdef SE1_D3D
  365. ASSERT(eAPI == GAT_OGL || eAPI == GAT_D3D || eAPI == GAT_NONE);
  366. #else // SE1_D3D
  367. ASSERT(eAPI == GAT_OGL || eAPI == GAT_NONE);
  368. #endif // SE1_D3D
  369. SLONG slMipSize;
  370. _sfStats.StartTimer(CStatForm::STI_GFXAPI);
  371. // OpenGL
  372. if( eAPI==GAT_OGL)
  373. {
  374. // was texture compressed?
  375. pglBindTexture( GL_TEXTURE_2D, ulTexObject);
  376. BOOL bCompressed = FALSE;
  377. if( _pGfx->gl_ulFlags & GLF_EXTC_ARB) {
  378. pglGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB, (BOOL*)&bCompressed);
  379. OGL_CHECKERROR;
  380. }
  381. // for compressed textures, determine size directly
  382. if( bCompressed) {
  383. pglGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, (GLint*)&slMipSize);
  384. OGL_CHECKERROR;
  385. }
  386. // non-compressed textures goes thru determination of internal format
  387. else {
  388. PIX pixWidth, pixHeight;
  389. pglGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, (GLint*)&pixWidth);
  390. pglGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, (GLint*)&pixHeight);
  391. OGL_CHECKERROR;
  392. slMipSize = pixWidth*pixHeight * gfxGetTexturePixRatio(ulTexObject);
  393. }
  394. }
  395. // Direct3D
  396. #ifdef SE1_D3D
  397. else if( eAPI==GAT_D3D)
  398. {
  399. // we can determine exact size from texture surface (i.e. mipmap)
  400. D3DSURFACE_DESC d3dSurfDesc;
  401. HRESULT hr = ((LPDIRECT3DTEXTURE8)ulTexObject)->GetLevelDesc( 0, &d3dSurfDesc);
  402. D3D_CHECKERROR(hr);
  403. slMipSize = d3dSurfDesc.Size;
  404. }
  405. #endif // SE1_D3D
  406. // eventually count in all the mipmaps (takes extra 33% of texture size)
  407. extern INDEX gap_bAllowSingleMipmap;
  408. const SLONG slUploadSize = (bHasMipmaps || !gap_bAllowSingleMipmap) ? slMipSize*4/3 : slMipSize;
  409. _sfStats.StopTimer(CStatForm::STI_GFXAPI);
  410. return slUploadSize;
  411. }
  412. // returns bytes/pixels ratio for uploaded texture
  413. extern INDEX gfxGetTexturePixRatio( ULONG ulTextureObject)
  414. {
  415. // determine API
  416. const GfxAPIType eAPI = _pGfx->gl_eCurrentAPI;
  417. #ifdef SE1_D3D
  418. ASSERT(eAPI == GAT_OGL || eAPI == GAT_D3D || eAPI == GAT_NONE);
  419. #else // SE1_D3D
  420. ASSERT(eAPI == GAT_OGL || eAPI == GAT_NONE);
  421. #endif // SE1_D3D
  422. if( eAPI==GAT_OGL) {
  423. return GetTexturePixRatio_OGL( (GLuint)ulTextureObject);
  424. }
  425. #ifdef SE1_D3D
  426. else if( eAPI==GAT_D3D) return GetTexturePixRatio_D3D( (LPDIRECT3DTEXTURE8)ulTextureObject);
  427. #endif // SE1_D3D
  428. else return 0;
  429. }
  430. // returns bytes/pixels ratio for uploaded texture
  431. extern INDEX gfxGetFormatPixRatio( ULONG ulTextureFormat)
  432. {
  433. // determine API
  434. const GfxAPIType eAPI = _pGfx->gl_eCurrentAPI;
  435. #ifdef SE1_D3D
  436. ASSERT(eAPI == GAT_OGL || eAPI == GAT_D3D || eAPI == GAT_NONE);
  437. #else // SE1_D3D
  438. ASSERT(eAPI == GAT_OGL || eAPI == GAT_NONE);
  439. #endif // SE1_D3D
  440. if( eAPI==GAT_OGL) {
  441. return GetFormatPixRatio_OGL( (GLenum)ulTextureFormat);
  442. }
  443. #ifdef SE1_D3D
  444. else if( eAPI==GAT_D3D) return GetFormatPixRatio_D3D( (D3DFORMAT)ulTextureFormat);
  445. #endif // SE1_D3D
  446. else return 0;
  447. }
  448. // PATTERN TEXTURE FOR LINES
  449. CTexParams _tpPattern;
  450. extern ULONG _ulPatternTexture = NONE;
  451. extern ULONG _ulLastUploadedPattern = 0;
  452. // upload pattern to accelerator memory
  453. extern void gfxSetPattern( ULONG ulPattern)
  454. {
  455. // set pattern to be current texture
  456. _tpPattern.tp_bSingleMipmap = TRUE;
  457. gfxSetTextureWrapping( GFX_REPEAT, GFX_REPEAT);
  458. gfxSetTexture( _ulPatternTexture, _tpPattern);
  459. // if this pattern is currently uploaded, do nothing
  460. if( _ulLastUploadedPattern==ulPattern) return;
  461. // convert bits to ULONGs
  462. ULONG aulPattern[32];
  463. for( INDEX iBit=0; iBit<32; iBit++) {
  464. if( (0x80000000>>iBit) & ulPattern) aulPattern[iBit] = 0xFFFFFFFF;
  465. else aulPattern[iBit] = 0x00000000;
  466. }
  467. // remember new pattern and upload
  468. _ulLastUploadedPattern = ulPattern;
  469. gfxUploadTexture( &aulPattern[0], 32, 1, TS.ts_tfRGBA8, FALSE);
  470. }
  471. // VERTEX ARRAYS
  472. // for D3D - (type 0=vtx, 1=nor, 2=col, 3=tex)
  473. extern void SetVertexArray_D3D( INDEX iType, ULONG *pulVtx);
  474. extern void gfxUnlockArrays(void)
  475. {
  476. // only if locked (OpenGL can lock 'em)
  477. if( !_bCVAReallyLocked) return;
  478. ASSERT( _pGfx->gl_eCurrentAPI==GAT_OGL);
  479. #ifndef NDEBUG
  480. INDEX glctRet;
  481. pglGetIntegerv( GL_ARRAY_ELEMENT_LOCK_COUNT_EXT, (GLint*)&glctRet);
  482. ASSERT( glctRet==GFX_ctVertices);
  483. #endif
  484. pglUnlockArraysEXT();
  485. OGL_CHECKERROR;
  486. _bCVAReallyLocked = FALSE;
  487. }
  488. // OpenGL workarounds
  489. // initialization of commond quad elements array
  490. extern void AddQuadElements( const INDEX ctQuads)
  491. {
  492. const INDEX iStart = _aiCommonQuads.Count() /6*4;
  493. INDEX *piQuads = _aiCommonQuads.Push(ctQuads*6);
  494. for( INDEX i=0; i<ctQuads; i++) {
  495. piQuads[i*6 +0] = iStart+ i*4 +0;
  496. piQuads[i*6 +1] = iStart+ i*4 +1;
  497. piQuads[i*6 +2] = iStart+ i*4 +2;
  498. piQuads[i*6 +3] = iStart+ i*4 +2;
  499. piQuads[i*6 +4] = iStart+ i*4 +3;
  500. piQuads[i*6 +5] = iStart+ i*4 +0;
  501. }
  502. }
  503. // helper function for flushers
  504. static void FlushArrays( INDEX *piElements, INDEX ctElements)
  505. {
  506. // check
  507. const INDEX ctVertices = _avtxCommon.Count();
  508. ASSERT( _atexCommon.Count()==ctVertices);
  509. ASSERT( _acolCommon.Count()==ctVertices);
  510. extern BOOL CVA_b2D;
  511. gfxSetVertexArray( &_avtxCommon[0], ctVertices);
  512. if(CVA_b2D) gfxLockArrays();
  513. gfxSetTexCoordArray( &_atexCommon[0], FALSE);
  514. gfxSetColorArray( &_acolCommon[0]);
  515. gfxDrawElements( ctElements, piElements);
  516. gfxUnlockArrays();
  517. }
  518. // render quad elements to screen buffer
  519. extern void gfxFlushQuads(void)
  520. {
  521. // if there is something to draw
  522. const INDEX ctElements = _avtxCommon.Count()*6/4;
  523. if( ctElements<=0) return;
  524. // draw thru arrays (for OGL only) or elements?
  525. extern INDEX ogl_bAllowQuadArrays;
  526. if( _pGfx->gl_eCurrentAPI==GAT_OGL && ogl_bAllowQuadArrays) FlushArrays( NULL, _avtxCommon.Count());
  527. else {
  528. // make sure that enough quad elements has been initialized
  529. const INDEX ctQuads = _aiCommonQuads.Count();
  530. if( ctElements>ctQuads) AddQuadElements( ctElements-ctQuads); // yes, 4 times more!
  531. FlushArrays( &_aiCommonQuads[0], ctElements);
  532. }
  533. }
  534. // render elements to screen buffer
  535. extern void gfxFlushElements(void)
  536. {
  537. const INDEX ctElements = _aiCommonElements.Count();
  538. if( ctElements>0) FlushArrays( &_aiCommonElements[0], ctElements);
  539. }
  540. // set truform parameters
  541. extern void gfxSetTruform( INDEX iLevel, BOOL bLinearNormals)
  542. {
  543. // skip if Truform isn't supported
  544. if( _pGfx->gl_iMaxTessellationLevel<1) {
  545. truform_iLevel = 0;
  546. truform_bLinear = FALSE;
  547. return;
  548. }
  549. // skip if same as last time
  550. iLevel = Clamp( iLevel, 0L, _pGfx->gl_iMaxTessellationLevel);
  551. if( truform_iLevel==iLevel && !truform_bLinear==!bLinearNormals) return;
  552. // determine API
  553. const GfxAPIType eAPI = _pGfx->gl_eCurrentAPI;
  554. #ifdef SE1_D3D
  555. ASSERT(eAPI == GAT_OGL || eAPI == GAT_D3D || eAPI == GAT_NONE);
  556. #else // SE1_D3D
  557. ASSERT(eAPI == GAT_OGL || eAPI == GAT_NONE);
  558. #endif // SE1_D3D
  559. _sfStats.StartTimer(CStatForm::STI_GFXAPI);
  560. // OpenGL needs truform set here
  561. if( eAPI==GAT_OGL) {
  562. GLenum eTriMode = bLinearNormals ? GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI : GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI;
  563. pglPNTrianglesiATI( GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI, iLevel);
  564. pglPNTrianglesiATI( GL_PN_TRIANGLES_NORMAL_MODE_ATI, eTriMode);
  565. OGL_CHECKERROR;
  566. }
  567. // if disabled, Direct3D will set tessellation level at "enable" call
  568. #ifdef SE1_D3D
  569. else if( eAPI==GAT_D3D && GFX_bTruform) {
  570. FLOAT fSegments = iLevel+1;
  571. HRESULT hr = _pGfx->gl_pd3dDevice->SetRenderState( D3DRS_PATCHSEGMENTS, *((DWORD*)&fSegments));
  572. D3D_CHECKERROR(hr);
  573. }
  574. #endif // SE1_D3D
  575. // keep current truform params
  576. truform_iLevel = iLevel;
  577. truform_bLinear = bLinearNormals;
  578. _sfStats.StopTimer(CStatForm::STI_GFXAPI);
  579. }
  580. // readout current colormask
  581. extern ULONG gfxGetColorMask(void)
  582. {
  583. return _ulCurrentColorMask;
  584. }
  585. #include "GFX_wrapper_OpenGL.cpp"
  586. #include "GFX_wrapper_Direct3D.cpp"
  587. // DUMMY FUNCTIONS FOR NONE API
  588. static void none_BlendFunc( GfxBlend eSrc, GfxBlend eDst) { NOTHING; }
  589. static void none_DepthFunc( GfxComp eFunc) { NOTHING; };
  590. static void none_DepthRange( FLOAT fMin, FLOAT fMax) { NOTHING; };
  591. static void none_CullFace( GfxFace eFace) { NOTHING; };
  592. static void none_ClipPlane( const DOUBLE *pdViewPlane) { NOTHING; };
  593. static void none_SetOrtho( const FLOAT fLeft, const FLOAT fRight, const FLOAT fTop, const FLOAT fBottom, const FLOAT fNear, const FLOAT fFar, const BOOL bSubPixelAdjust) { NOTHING; };
  594. static void none_SetFrustum( const FLOAT fLeft, const FLOAT fRight, const FLOAT fTop, const FLOAT fBottom, const FLOAT fNear, const FLOAT fFar) { NOTHING; };
  595. static void none_SetMatrix( const FLOAT *pfMatrix) { NOTHING; };
  596. static void none_PolygonMode( GfxPolyMode ePolyMode) { NOTHING; };
  597. static void none_SetTextureWrapping( enum GfxWrap eWrapU, enum GfxWrap eWrapV) { NOTHING; };
  598. static void none_SetTextureModulation( INDEX iScale) { NOTHING; };
  599. static void none_GenDelTexture( ULONG &ulTexObject) { NOTHING; };
  600. static void none_SetVertexArray( GFXVertex4 *pvtx, INDEX ctVtx) { NOTHING; };
  601. static void none_SetNormalArray( GFXNormal *pnor) { NOTHING; };
  602. static void none_SetTexCoordArray( GFXTexCoord *ptex, BOOL b4) { NOTHING; };
  603. static void none_SetColorArray( GFXColor *pcol) { NOTHING; };
  604. static void none_DrawElements( INDEX ctElem, INDEX *pidx) { NOTHING; };
  605. static void none_SetConstantColor( COLOR col) { NOTHING; };
  606. static void none_SetColorMask( ULONG ulColorMask) { NOTHING; };
  607. // functions initialization for OGL, D3D or NONE (dummy)
  608. extern void GFX_SetFunctionPointers( INDEX iAPI)
  609. {
  610. // OpenGL?
  611. if( iAPI==(INDEX)GAT_OGL)
  612. {
  613. gfxEnableDepthWrite = &ogl_EnableDepthWrite;
  614. gfxEnableDepthBias = &ogl_EnableDepthBias;
  615. gfxEnableDepthTest = &ogl_EnableDepthTest;
  616. gfxEnableAlphaTest = &ogl_EnableAlphaTest;
  617. gfxEnableBlend = &ogl_EnableBlend;
  618. gfxEnableDither = &ogl_EnableDither;
  619. gfxEnableTexture = &ogl_EnableTexture;
  620. gfxEnableClipping = &ogl_EnableClipping;
  621. gfxEnableClipPlane = &ogl_EnableClipPlane;
  622. gfxEnableTruform = &ogl_EnableTruform;
  623. gfxDisableDepthWrite = &ogl_DisableDepthWrite;
  624. gfxDisableDepthBias = &ogl_DisableDepthBias;
  625. gfxDisableDepthTest = &ogl_DisableDepthTest;
  626. gfxDisableAlphaTest = &ogl_DisableAlphaTest;
  627. gfxDisableBlend = &ogl_DisableBlend;
  628. gfxDisableDither = &ogl_DisableDither;
  629. gfxDisableTexture = &ogl_DisableTexture;
  630. gfxDisableClipping = &ogl_DisableClipping;
  631. gfxDisableClipPlane = &ogl_DisableClipPlane;
  632. gfxDisableTruform = &ogl_DisableTruform;
  633. gfxBlendFunc = &ogl_BlendFunc;
  634. gfxDepthFunc = &ogl_DepthFunc;
  635. gfxDepthRange = &ogl_DepthRange;
  636. gfxCullFace = &ogl_CullFace;
  637. gfxFrontFace = &ogl_FrontFace;
  638. gfxClipPlane = &ogl_ClipPlane;
  639. gfxSetOrtho = &ogl_SetOrtho;
  640. gfxSetFrustum = &ogl_SetFrustum;
  641. gfxSetTextureMatrix = &ogl_SetTextureMatrix;
  642. gfxSetViewMatrix = &ogl_SetViewMatrix;
  643. gfxPolygonMode = &ogl_PolygonMode;
  644. gfxSetTextureWrapping = &ogl_SetTextureWrapping;
  645. gfxSetTextureModulation = &ogl_SetTextureModulation;
  646. gfxGenerateTexture = &ogl_GenerateTexture;
  647. gfxDeleteTexture = &ogl_DeleteTexture;
  648. gfxSetVertexArray = &ogl_SetVertexArray;
  649. gfxSetNormalArray = &ogl_SetNormalArray;
  650. gfxSetTexCoordArray = &ogl_SetTexCoordArray;
  651. gfxSetColorArray = &ogl_SetColorArray;
  652. gfxDrawElements = &ogl_DrawElements;
  653. gfxSetConstantColor = &ogl_SetConstantColor;
  654. gfxEnableColorArray = &ogl_EnableColorArray;
  655. gfxDisableColorArray = &ogl_DisableColorArray;
  656. gfxFinish = &ogl_Finish;
  657. gfxLockArrays = &ogl_LockArrays;
  658. gfxSetColorMask = &ogl_SetColorMask;
  659. }
  660. // Direct3D?
  661. #ifdef SE1_D3D
  662. else if( iAPI==(INDEX)GAT_D3D)
  663. {
  664. gfxEnableDepthWrite = &d3d_EnableDepthWrite;
  665. gfxEnableDepthBias = &d3d_EnableDepthBias;
  666. gfxEnableDepthTest = &d3d_EnableDepthTest;
  667. gfxEnableAlphaTest = &d3d_EnableAlphaTest;
  668. gfxEnableBlend = &d3d_EnableBlend;
  669. gfxEnableDither = &d3d_EnableDither;
  670. gfxEnableTexture = &d3d_EnableTexture;
  671. gfxEnableClipping = &d3d_EnableClipping;
  672. gfxEnableClipPlane = &d3d_EnableClipPlane;
  673. gfxEnableTruform = &d3d_EnableTruform;
  674. gfxDisableDepthWrite = &d3d_DisableDepthWrite;
  675. gfxDisableDepthBias = &d3d_DisableDepthBias;
  676. gfxDisableDepthTest = &d3d_DisableDepthTest;
  677. gfxDisableAlphaTest = &d3d_DisableAlphaTest;
  678. gfxDisableBlend = &d3d_DisableBlend;
  679. gfxDisableDither = &d3d_DisableDither;
  680. gfxDisableTexture = &d3d_DisableTexture;
  681. gfxDisableClipping = &d3d_DisableClipping;
  682. gfxDisableClipPlane = &d3d_DisableClipPlane;
  683. gfxDisableTruform = &d3d_DisableTruform;
  684. gfxBlendFunc = &d3d_BlendFunc;
  685. gfxDepthFunc = &d3d_DepthFunc;
  686. gfxDepthRange = &d3d_DepthRange;
  687. gfxCullFace = &d3d_CullFace;
  688. gfxFrontFace = &d3d_FrontFace;
  689. gfxClipPlane = &d3d_ClipPlane;
  690. gfxSetOrtho = &d3d_SetOrtho;
  691. gfxSetFrustum = &d3d_SetFrustum;
  692. gfxSetTextureMatrix = &d3d_SetTextureMatrix;
  693. gfxSetViewMatrix = &d3d_SetViewMatrix;
  694. gfxPolygonMode = &d3d_PolygonMode;
  695. gfxSetTextureWrapping = &d3d_SetTextureWrapping;
  696. gfxSetTextureModulation = &d3d_SetTextureModulation;
  697. gfxGenerateTexture = &d3d_GenerateTexture;
  698. gfxDeleteTexture = &d3d_DeleteTexture;
  699. gfxSetVertexArray = &d3d_SetVertexArray;
  700. gfxSetNormalArray = &d3d_SetNormalArray;
  701. gfxSetTexCoordArray = &d3d_SetTexCoordArray;
  702. gfxSetColorArray = &d3d_SetColorArray;
  703. gfxDrawElements = &d3d_DrawElements;
  704. gfxSetConstantColor = &d3d_SetConstantColor;
  705. gfxEnableColorArray = &d3d_EnableColorArray;
  706. gfxDisableColorArray = &d3d_DisableColorArray;
  707. gfxFinish = &d3d_Finish;
  708. gfxLockArrays = &d3d_LockArrays;
  709. gfxSetColorMask = &d3d_SetColorMask;
  710. }
  711. #endif // SE1_D3D
  712. // NONE!
  713. else
  714. {
  715. gfxEnableDepthWrite = &none_void;
  716. gfxEnableDepthBias = &none_void;
  717. gfxEnableDepthTest = &none_void;
  718. gfxEnableAlphaTest = &none_void;
  719. gfxEnableBlend = &none_void;
  720. gfxEnableDither = &none_void;
  721. gfxEnableTexture = &none_void;
  722. gfxEnableClipping = &none_void;
  723. gfxEnableClipPlane = &none_void;
  724. gfxEnableTruform = &none_void;
  725. gfxDisableDepthWrite = &none_void;
  726. gfxDisableDepthBias = &none_void;
  727. gfxDisableDepthTest = &none_void;
  728. gfxDisableAlphaTest = &none_void;
  729. gfxDisableBlend = &none_void;
  730. gfxDisableDither = &none_void;
  731. gfxDisableTexture = &none_void;
  732. gfxDisableClipping = &none_void;
  733. gfxDisableClipPlane = &none_void;
  734. gfxDisableTruform = &none_void;
  735. gfxBlendFunc = &none_BlendFunc;
  736. gfxDepthFunc = &none_DepthFunc;
  737. gfxDepthRange = &none_DepthRange;
  738. gfxCullFace = &none_CullFace;
  739. gfxFrontFace = &none_CullFace;
  740. gfxClipPlane = &none_ClipPlane;
  741. gfxSetOrtho = &none_SetOrtho;
  742. gfxSetFrustum = &none_SetFrustum;
  743. gfxSetTextureMatrix = &none_SetMatrix;
  744. gfxSetViewMatrix = &none_SetMatrix;
  745. gfxPolygonMode = &none_PolygonMode;
  746. gfxSetTextureWrapping = &none_SetTextureWrapping;
  747. gfxSetTextureModulation = &none_SetTextureModulation;
  748. gfxGenerateTexture = &none_GenDelTexture;
  749. gfxDeleteTexture = &none_GenDelTexture;
  750. gfxSetVertexArray = &none_SetVertexArray;
  751. gfxSetNormalArray = &none_SetNormalArray;
  752. gfxSetTexCoordArray = &none_SetTexCoordArray;
  753. gfxSetColorArray = &none_SetColorArray;
  754. gfxDrawElements = &none_DrawElements;
  755. gfxSetConstantColor = &none_SetConstantColor;
  756. gfxEnableColorArray = &none_void;
  757. gfxDisableColorArray = &none_void;
  758. gfxFinish = &none_void;
  759. gfxLockArrays = &none_void;
  760. gfxSetColorMask = &none_SetColorMask;
  761. }
  762. }