HOOPS/3dGS I.M. Interface

     << Back      Full Index      Forward >>


dx9drive.h

00001 /*
00002 * Copyright (c) 2007 by Tech Soft 3D, LLC.
00003 * The information contained herein is confidential and proprietary to
00004 * Tech Soft 3D, LLC., and considered a trade secret as defined under
00005 * civil and criminal statutes.  Tech Soft 3D shall pursue its civil
00006 * and criminal remedies in the event of unauthorized use or misappropriation
00007 * of its trade secrets.  Use of this information by anyone other than
00008 * authorized employees of Tech Soft 3D, LLC. is granted only under a
00009 * written non-disclosure agreement, expressly prescribing the scope and
00010 * manner of such use.
00011 *
00012  * $Id: dx9drive_8h-source.html,v 1.29 2008-03-10 07:09:28 stage Exp $
00013 */
00014 
00015 
00016 #ifndef __DX9DRIVE_H_DEFINED__
00017 #define __DX9DRIVE_H_DEFINED__
00018 
00019 // SIL: This provides a lot of additional debugging information - e.g. inspecting surfaces, etc.
00020 #ifdef _DEBUG
00021 #define D3D_DEBUG_INFO
00022 #endif // _DEBUG
00023 
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 /*D3D includes*/
00027 #include <D3D9.h>
00028 #include <d3dx9math.h>
00029 
00030 #include "adt.h"
00031 #include "database.h"
00032 #include "driver.h"
00033 #include "hpserror.h"
00034 #include "patterns.h"
00035 #include "phedron.h"
00036 #include "please.h"
00037 #include "searchh.h"
00038 #include "tandt.h"
00039 #include "hversion.h"
00040 #include "d3dutil.h"
00041 
00042 /*forward declarations*/
00043 class HD3DEnumeration;
00044 class HD3DSettings;
00045 class HDX9VertexBufferCache;
00046 class HDX9IndexBufferCache;
00047 class HDX9Shader;
00048 class H3DShaderID;
00049 class HDX9Post;
00050 
00051 #   ifndef WIN32_LEAN_AND_MEAN
00052 #       define WIN32_LEAN_AND_MEAN
00053 #   endif
00054 #include <windows.h>
00055 #include <Pbt.h>
00056 #include "msw.h"
00057 
00058 #pragma warning(disable : 4710)
00059 
00060 // SIL: Enable for PRT demo build
00061 //#define PRT_DEMO
00062 
00063 // D3DPOOL_MANAGED or D3DPOOL_DEFAULT, 
00064 #define HDX9_MANAGED_POOL
00065 #ifdef HDX9_MANAGED_POOL
00066 #   define HDX9_POOL_TYPE                   D3DPOOL_MANAGED
00067 #else
00068 #   define HDX9_POOL_TYPE                   D3DPOOL_DEFAULT
00069 #endif
00070 
00071 
00072 typedef struct dx9region_t {
00073     LPDIRECT3DSURFACE9 pCurrentSurface; // the current image/z region
00074     LPDIRECT3DSURFACE9 pSavedSurface;   // saved image/z region
00075     HT_Int_Rectangle original_area;
00076     struct dx9region_t * next;          // pointer to next region - required during Reset of device
00077 } dx9region;
00078 
00079 
00080 
00081 D3DPRIMITIVETYPE d3dprimitive(H3DPRIMITIVETYPE type)
00082 {
00083     switch (type) {
00084         case H3DPT_POINTLIST:       return D3DPT_POINTLIST;
00085         case H3DPT_LINELIST:        return D3DPT_LINELIST;
00086         case H3DPT_LINESTRIP:       return D3DPT_LINESTRIP;
00087         case H3DPT_TRIANGLELIST:    return D3DPT_TRIANGLELIST;
00088         case H3DPT_TRIANGLESTRIP:   return D3DPT_TRIANGLESTRIP;
00089         case H3DPT_TRIANGLEFAN:     return D3DPT_TRIANGLEFAN;
00090         case H3DPT_FORCE_DWORD:     return D3DPT_FORCE_DWORD; 
00091         default:
00092             HE_ERROR(HEC_INTERNAL_ERROR, HEC_INTERNAL_ERROR,
00093                 "Internal error: Unhandled primitive type mapping.");
00094             return D3DPT_FORCE_DWORD;
00095     }
00096 }
00097 
00098 D3DBLEND d3dblend(H3DBLEND type)
00099 {
00100     switch (type) {
00101         case H3DBLEND_ZERO:             return D3DBLEND_ZERO;
00102         case H3DBLEND_ONE:              return D3DBLEND_ONE;
00103         case H3DBLEND_SRCCOLOR:         return D3DBLEND_SRCCOLOR;
00104         case H3DBLEND_INVSRCCOLOR:      return D3DBLEND_INVSRCCOLOR;
00105         case H3DBLEND_SRCALPHA:         return D3DBLEND_SRCALPHA;
00106         case H3DBLEND_INVSRCALPHA:      return D3DBLEND_INVSRCALPHA;
00107         case H3DBLEND_DESTALPHA:        return D3DBLEND_DESTALPHA;
00108         case H3DBLEND_INVDESTALPHA:     return D3DBLEND_INVDESTALPHA;
00109         case H3DBLEND_DESTCOLOR:        return D3DBLEND_DESTCOLOR;
00110         case H3DBLEND_INVDESTCOLOR:     return D3DBLEND_INVDESTCOLOR;
00111         case H3DBLEND_SRCALPHASAT:      return D3DBLEND_SRCALPHASAT;
00112         case H3DBLEND_BOTHSRCALPHA:     return D3DBLEND_BOTHSRCALPHA;
00113         case H3DBLEND_BOTHINVSRCALPHA:  return D3DBLEND_BOTHINVSRCALPHA;
00114         case H3DBLEND_BLENDFACTOR:      return D3DBLEND_BLENDFACTOR;
00115         case H3DBLEND_INVBLENDFACTOR:   return D3DBLEND_INVBLENDFACTOR;
00116         /* H3D9Ex only -- */
00117 #if !defined(H3D_DISABLE_9EX)
00118         //case H3DBLEND_SRCCOLOR2:        return D3DBLEND_SRCCOLOR2;
00119         //case H3DBLEND_INVSRCCOLOR2:     return D3DBLEND_INVSRCCOLOR2;
00120 #endif // !H3D_DISABLE_9EX
00121         /* -- H3D9Ex only */
00122         case H3DBLEND_FORCE_DWORD:      return D3DBLEND_FORCE_DWORD;
00123         default:
00124             HE_ERROR(HEC_INTERNAL_ERROR, HEC_INTERNAL_ERROR,
00125                 "Internal error: Unhandled blend type mapping.");
00126             return D3DBLEND_FORCE_DWORD;
00127     }
00128 }
00129 
00130 
00131 
00132 DWORD d3dclear(int flags)
00133 {
00134     DWORD clear_flags = 0;
00135     if (BIT(flags, H3DCLEAR_TARGET))
00136         clear_flags |= D3DCLEAR_TARGET;
00137     if (BIT(flags, H3DCLEAR_ZBUFFER))
00138         clear_flags |= D3DCLEAR_ZBUFFER;
00139     if (BIT(flags, H3DCLEAR_STENCIL))
00140         clear_flags |= D3DCLEAR_STENCIL;
00141     return clear_flags;
00142 }
00143 
00144 D3DSHADEMODE d3dshademode(H3DSHADEMODE type)
00145 {
00146     switch (type) {
00147         case H3DSHADE_FLAT:         return D3DSHADE_FLAT;
00148         case H3DSHADE_GOURAUD:      return D3DSHADE_GOURAUD;
00149         case H3DSHADE_PHONG:        return D3DSHADE_PHONG;
00150         case H3DSHADE_FORCE_DWORD:  return D3DSHADE_FORCE_DWORD;
00151         default:
00152             HE_ERROR(HEC_INTERNAL_ERROR, HEC_INTERNAL_ERROR,
00153                 "Internal error: Unhandled shade mode mapping.");
00154             return D3DSHADE_FORCE_DWORD;
00155     }
00156 }
00157 
00158 D3DCULL d3dcull(H3DCULL type)
00159 {
00160     switch (type) {
00161         case H3DCULL_NONE:          return D3DCULL_NONE;
00162         case H3DCULL_CW:            return D3DCULL_CW;
00163         case H3DCULL_CCW:           return D3DCULL_CCW;
00164         case H3DCULL_FORCE_DWORD:   return D3DCULL_FORCE_DWORD;
00165         default:
00166             HE_ERROR(HEC_INTERNAL_ERROR, HEC_INTERNAL_ERROR,
00167                 "Internal error: Unhandled cull mode mapping.");
00168             return D3DCULL_FORCE_DWORD;
00169     }
00170 }
00171 
00172 D3DFORMAT d3dformat(H3DFORMAT type)
00173 {
00174     switch (type) {
00175         case H3DFMT_INDEX16:        return D3DFMT_INDEX16;
00176         case H3DFMT_INDEX32:        return D3DFMT_INDEX32;
00177         default:
00178             HE_ERROR(HEC_INTERNAL_ERROR, HEC_INTERNAL_ERROR,
00179                 "Internal error: Unhandled format mapping.");
00180             return D3DFMT_INDEX32;
00181     }
00182 }
00183 
00184 D3DVIEWPORT9 d3dviewport(H3DVIEWPORT const *hvp)
00185 {
00186     D3DVIEWPORT9 vp;
00187     vp.X = hvp->X;
00188     vp.Y = hvp->Y;
00189     vp.Width = hvp->Width;
00190     vp.Height = hvp->Height;
00191     vp.MinZ = hvp->MinZ;
00192     vp.MaxZ = hvp->MaxZ;
00193     return vp;
00194 }
00195 
00196 H3DVIEWPORT h3dviewport(D3DVIEWPORT9 const *vp)
00197 {
00198     H3DVIEWPORT hvp;
00199     hvp.X = vp->X;
00200     hvp.Y = vp->Y;
00201     hvp.Width = vp->Width;
00202     hvp.Height = vp->Height;
00203     hvp.MinZ = vp->MinZ;
00204     hvp.MaxZ = vp->MaxZ;
00205     return hvp;
00206 }
00207 /*****************************************************************************
00208 *****************************************************************************
00209                     H3DVertexFormat helper functions
00210 *****************************************************************************
00211 *****************************************************************************/
00212 
00213 H3DVertexFormat fvf2vf(DWORD fvf) 
00214 {
00215     H3DVertexFormat vf;
00216     int i = 0;
00217 
00218     if (BIT(fvf, D3DFVF_XYZ))       vf.set_position();
00219     if (BIT(fvf, D3DFVF_NORMAL))    vf.set_normals();
00220     if (BIT(fvf, D3DFVF_DIFFUSE))   vf.set_diffuse();
00221     if (BIT(fvf, D3DFVF_SPECULAR))  vf.set_specular();
00222     vf.set_tex_count((fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT);
00223 
00224     for(i = 0; i < vf.get_tex_count(); i++) {
00225         int texcoordsize = fvf & D3DFVF_TEXCOORDSIZE1(i);
00226 
00227         if (D3DFVF_TEXCOORDSIZE1(i) == texcoordsize)        vf.set_tex_size(i,1);
00228         else if (D3DFVF_TEXCOORDSIZE2(i) == texcoordsize)   vf.set_tex_size(i,2);
00229         else if (D3DFVF_TEXCOORDSIZE3(i) == texcoordsize)   vf.set_tex_size(i,3);
00230         else if (D3DFVF_TEXCOORDSIZE4(i) == texcoordsize)   vf.set_tex_size(i,4);
00231     }
00232     return vf;
00233 }
00234 
00235 local DWORD vf2fvf(H3DVertexFormat vf)
00236 {
00237     int i = 0;
00238     DWORD fvf = 0;
00239 
00240     if (vf.get_position())      fvf |= D3DFVF_XYZ;
00241     if (vf.get_normals())       fvf |= D3DFVF_NORMAL;
00242     if (vf.get_diffuse())       fvf |= D3DFVF_DIFFUSE;
00243     if (vf.get_specular())      fvf |= D3DFVF_SPECULAR;
00244 
00245     for(i = 0; i < vf.get_tex_count(); i++) {
00246         fvf += D3DFVF_TEX1;
00247 
00248         if (vf.get_tex_size(i) == 1)        fvf |= D3DFVF_TEXCOORDSIZE1(i);
00249         else if (vf.get_tex_size(i) == 2)   fvf |= D3DFVF_TEXCOORDSIZE2(i);
00250         else if (vf.get_tex_size(i) == 3)   fvf |= D3DFVF_TEXCOORDSIZE3(i);
00251         else if (vf.get_tex_size(i) == 4)   fvf |= D3DFVF_TEXCOORDSIZE4(i);
00252         
00253     }
00254 
00255     return fvf;
00256 }
00257 
00258 
00259 typedef struct dx9data_s : h3ddata_s
00260 {
00261     HD3DEnumeration         *enumeration;           // available D3D settings: adapters, devices, modes, etc
00262     HD3DSettings            *settings;              // current D3D settings: adapter, device, mode, formats, etc
00263     D3DPRESENT_PARAMETERS   presentation_params;    // presentation parameters for the device to be created 
00264     LPDIRECT3DDEVICE9       pDevice;                // The D3D rendering device
00265 
00266     LPDIRECT3DSURFACE9      render_target;
00267     LPDIRECT3DSURFACE9      depth_stencil;
00268 
00269 #define REGION_SHARING
00270 #ifdef REGION_SHARING
00271     LPDIRECT3DSURFACE9      saved_render_target;
00272     LPDIRECT3DSURFACE9      saved_depth_stencil;
00273 #endif // REGION_SHARING
00274 
00275     HDX9Post                *post;
00276 
00277 #define INVALID_CACHE                   (-1)
00278 #define INVALID_TEXTURE_CACHE           (LPDIRECT3DTEXTURE9)(-1)
00279 #define INVALID_CUBE_TEXTURE_CACHE      (LPDIRECT3DCUBETEXTURE9)(-1)
00280 #define INVALID_GEOMETRY_CACHE          (void*)(-1)
00281 
00282     
00283     //spriting
00284     dx9region * image_regions;      
00285     dx9region * z_regions;          
00286 
00287     D3DCAPS9                capabilities;           //Caps for the device
00288 
00289     HRESULT hr;
00290 } DX9Data;
00291 
00292 
00293 #ifndef DX9DATA_ONLY
00294 
00295 
00296 #define Debug_NO_TWO_SIDED_LIGHTING             0x00000001
00297 #define Debug_ENABLE_NVPERFHUD                  0x00000002
00298 #define Debug_UNUSED3                           0x00000004
00299 #define Debug_UNUSED4                           0x00000008
00300 #define Debug_UNUSED5                           0x00000010
00301 #define Debug_UNUSED6                           0x00000020
00302 #define Debug_NO_WINDOWS_HOOK                   0x00000040
00303 #define Debug_UNUSED8                           0x00000080
00304 #define Debug_UNUSED9                           0x00000100
00305 #define Debug_UNUSED10                          0x00000200
00306 #define Debug_UNUSED11                          0x00000400
00307 #define Debug_UNUSED12                          0x00000800
00308 #define Debug_UNUSED13                          0x00001000
00309 #define Debug_UNUSED14                          0x00002000
00310 #define DEBUG_STARTUP_CLEAR_BLACK               0x00004000
00311 #define Debug_UNUSED16                          0x00008000
00312 #define Debug_UNUSED17                          0x00010000
00313 #define Debug_UNUSED18                          0x00020000
00314 #define Debug_UNUSED19                          0x00040000
00315 #define Debug_UNUSED20                          0x00080000
00316 #define Debug_USE_WINDOW_IS_IMAGE               0x00100000
00317 #define Debug_UNUSED22                          0x00200000
00318 #define Debug_UNUSED23                          0x00400000
00319 #define Debug_UNUSED24                          0x00800000
00320 #define Debug_FORCE_SOFTWARE                    0x01000000
00321 #define Debug_UNUSED26                          0x02000000
00322 #define Debug_UNUSED27                          0x04000000
00323 #define Debug_UNUSED28                          0x08000000
00324 #define Debug_UNUSED29                          0x10000000
00325 #define Debug_UNUSED30                          0x20000000
00326 #define Debug_UNUSED31                          0x40000000
00327 #define Debug_UNUSED32                          0x80000000
00328 
00329 /* XBIT STUFF */
00330 #define XBIT_NONE                           0L
00331 #define XBIT_NO_INDEXED_PRIMITIVES          1L
00332 
00333 
00334 typedef struct dx9_system_data 
00335 {
00336     int                     ref_count;              // reference count
00337     LPDIRECT3D9             pD3D;                   // the main D3D object
00338 } DX9_System_Data;
00339 
00340 #define DX9D(dc) ((DX9Data alter *)((dc)->data2))
00341 #define DX9NRD(nr) (DX9D((nr)->display_context))
00342 
00343 /* SIL: No longer used?
00344 #define ENSURE_RGB32_SHADER(dx9data,nr,ppShader)  SEMI_PROTECT(\
00345     H3DShaderID _id_; \
00346     HDX9Shader *_shader_; \
00347     _id_.InitRGB32 (nr); \
00348     _shader_ = dx9data->ShaderHash->Lookup (_id_);  \
00349     if (!_shader_) { \
00350         _shader_ = new HDX9Shader(_id_); \
00351         _shader_->Create(dx9data->pDevice); \
00352         dx9data->ShaderHash->Insert (_id_, _shader_);  \
00353     } \
00354     _shader_->Activate(); \
00355     dx9data->cache.Shader = _shader_; \
00356     *(ppShader) = dx9data->cache.Shader; \
00357 ) 
00358 */
00359 
00360 #define BEGIN_SCENE(dx9data) SEMI_PROTECT(      \
00361     if (!dx9data->has_scene_began) {            \
00362         dx9data->pDevice->BeginScene();         \
00363         dx9data->has_scene_began = true;        \
00364     }                                           \
00365 )
00366 #define END_SCENE(dx9data) SEMI_PROTECT(        \
00367     if (dx9data->has_scene_began) {             \
00368         dx9data->pDevice->EndScene();           \
00369         dx9data->has_scene_began = false;       \
00370     }                                           \
00371 )
00372 
00373 #define D3DXMatrix_2_floats(d3d_mat_in, floats_out)     \
00374     floats_out[0][0] = d3d_mat_in._11;                  \
00375     floats_out[0][1] = d3d_mat_in._12;                  \
00376     floats_out[0][2] = d3d_mat_in._13;                  \
00377     floats_out[0][3] = d3d_mat_in._14;                  \
00378     \
00379     floats_out[1][0] = d3d_mat_in._21;                  \
00380     floats_out[1][1] = d3d_mat_in._22;                  \
00381     floats_out[1][2] = d3d_mat_in._23;                  \
00382     floats_out[1][3] = d3d_mat_in._24;                  \
00383     \
00384     floats_out[2][0] = d3d_mat_in._31;                  \
00385     floats_out[2][1] = d3d_mat_in._32;                  \
00386     floats_out[2][2] = d3d_mat_in._33;                  \
00387     floats_out[2][3] = d3d_mat_in._34;                  \
00388     \
00389     floats_out[3][0] = d3d_mat_in._41;                  \
00390     floats_out[3][1] = d3d_mat_in._42;                  \
00391     floats_out[3][2] = d3d_mat_in._43;                  \
00392     floats_out[3][3] = d3d_mat_in._44;          
00393 
00394 
00395 /* 
00396  * SCISSORING
00397  */
00398 #define INVALIDATE_SCISSOR_SET(dx9data) SEMI_PROTECT(\
00399     dx9data->cache.scissor_rect.left        = INVALID_CACHE; \
00400     dx9data->cache.scissor_rect.top         = INVALID_CACHE; \
00401     dx9data->cache.scissor_rect.right       = INVALID_CACHE; \
00402     dx9data->cache.scissor_rect.bottom      = INVALID_CACHE; \
00403 )
00404 #define FORCE_SCISSOR_OFF(dx9data) SEMI_PROTECT(\
00405     if (dx9data->can_scissor) {\
00406         INVALIDATE_SCISSOR_SET(dx9data); \
00407         dx9data->cache.scissoring = false; \
00408         dx9data->pDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);/*glDisable (GL_SCISSOR_TEST);*/ \
00409     }\
00410 )
00411 #define ENSURE_SCISSOR_OFF(dx9data) SEMI_PROTECT(\
00412     if (dx9data->cache.scissoring) \
00413         FORCE_SCISSOR_OFF (dx9data); \
00414 )
00415 
00416 #define ENSURE_SCISSOR_SET(dx9data, left, bottom, right, top)  SEMI_PROTECT(    \
00417     RECT scr_rect;                                                              \
00418     SetRect(&scr_rect, left, dx9data->yfudge - top , right + 1, dx9data->yfudge - bottom + 1);  \
00419     if (!EqualRect(&scr_rect, &dx9data->cache.scissor_rect)) {                  \
00420         CopyRect(&dx9data->cache.scissor_rect, &scr_rect);                      \
00421         dx9data->pDevice->SetScissorRect(&scr_rect); \
00422     }                                                                                                                                                       \
00423 )
00424 
00425 /* update the ref_matrix_negative_3x3 boolean, and make sure handedness stays 
00426  * in synch.  (ref_matrix_negative_3x3 tracks whether geometry has been put 
00427  * through a geometry reference with a negative scale matrix */
00428 #define ENSURE_NEG3X3(dx9data, tr, val) SEMI_PROTECT(\
00429     if (val != dx9data->ref_matrix_negative_3x3) { \
00430         dx9data->ref_matrix_negative_3x3 = val; \
00431         set_handedness (dx9data, tr, FALSE); \
00432     } \
00433     else \
00434         dx9data->ref_matrix_negative_3x3 = val; \
00435 )
00436 
00437 /*
00438  * BLEND
00439  */
00440 #define FORCE_BLEND(dx9data, src, dest) SEMI_PROTECT(\
00441     dx9data->cache.src_blend = src; \
00442     dx9data->pDevice->SetRenderState(D3DRS_SRCBLEND, src); \
00443     dx9data->cache.dest_blend = dest; \
00444     dx9data->pDevice->SetRenderState(D3DRS_DESTBLEND, dest); \
00445 )
00446 #define ENSURE_BLEND(dx9data, src, dest) SEMI_PROTECT(\
00447     if (dx9data->cache.src_blend != src || dx9data->cache.dest_blend != dest) \
00448         FORCE_BLEND(dx9data, src, dest); \
00449 )
00450 
00451 
00452 /*
00453  * STENCIL
00454  */
00455 #define FORCE_STENCILLING(dx9data, onoff) SEMI_PROTECT(\
00456     dx9data->cache.stencilling = onoff; \
00457     dx9data->pDevice->SetRenderState(D3DRS_STENCILENABLE, onoff); \
00458 )
00459 #define ENSURE_STENCILLING(dx9data, onoff) SEMI_PROTECT(\
00460     if (dx9data->cache.stencilling != onoff) { \
00461         FORCE_STENCILLING(dx9data, onoff); \
00462     } \
00463 )
00464 
00465 
00466 #define FORCE_STENCIL_MASK(dx9data, val) SEMI_PROTECT(  \
00467     dx9data->cache.stencil_mask = val;              \
00468     dx9data->pDevice->SetRenderState(D3DRS_STENCILMASK, val); \
00469 )
00470 #define ENSURE_STENCIL_MASK(dx9data, val) SEMI_PROTECT(\
00471     if (dx9data->cache.stencil_mask != val) { \
00472         FORCE_STENCIL_MASK(dx9data, val);   \
00473     } \
00474 )
00475 
00476 #define FORCE_STENCIL_WRITE_MASK(dx9data, val) SEMI_PROTECT(    \
00477     dx9data->cache.stencil_write_mask = val;                \
00478     dx9data->pDevice->SetRenderState(D3DRS_STENCILWRITEMASK, val); \
00479 )
00480 #define ENSURE_STENCIL_WRITE_MASK(dx9data, val) SEMI_PROTECT(\
00481     if (dx9data->cache.stencil_write_mask != val) { \
00482         FORCE_STENCIL_WRITE_MASK(dx9data, val); \
00483     } \
00484 )
00485 
00486 #define FORCE_STENCIL_REF(dx9data, val) SEMI_PROTECT(   \
00487     dx9data->cache.stencil_ref = val;               \
00488     dx9data->pDevice->SetRenderState(D3DRS_STENCILREF, val); \
00489 )
00490 #define ENSURE_STENCIL_REF(dx9data, val) SEMI_PROTECT(\
00491     if (dx9data->cache.stencil_ref != val) { \
00492         FORCE_STENCIL_REF(dx9data, val);    \
00493     } \
00494 )
00495 
00496 #define FORCE_STENCIL_FUNC(dx9data, val) SEMI_PROTECT(  \
00497     dx9data->cache.stencil_func = val;              \
00498     dx9data->pDevice->SetRenderState(D3DRS_STENCILFUNC, val); \
00499 )
00500 #define ENSURE_STENCIL_FUNC(dx9data, val) SEMI_PROTECT(\
00501     if (dx9data->cache.stencil_func != val) { \
00502         FORCE_STENCIL_FUNC(dx9data, val);   \
00503     } \
00504 )
00505 
00506 
00507 #define FORCE_STENCIL_OP(dx9data, fail, zfail, pass) SEMI_PROTECT(  \
00508     dx9data->cache.stencil_fail = fail;             \
00509     dx9data->cache.stencil_zfail = zfail;               \
00510     dx9data->cache.stencil_pass = pass;             \
00511     dx9data->pDevice->SetRenderState(D3DRS_STENCILFAIL, fail); \
00512     dx9data->pDevice->SetRenderState(D3DRS_STENCILZFAIL, zfail); \
00513     dx9data->pDevice->SetRenderState(D3DRS_STENCILPASS, pass); \
00514 )
00515 #define ENSURE_STENCIL_OP(dx9data, fail, zfail, pass) SEMI_PROTECT(\
00516     if (dx9data->cache.stencil_fail != fail ||      \
00517         dx9data->cache.stencil_zfail != zfail ||    \
00518         dx9data->cache.stencil_pass != pass) { \
00519         FORCE_STENCIL_OP(dx9data, fail, zfail, pass);   \
00520     } \
00521 )
00522 
00523 #define STENCIL_BIT ((DWORD)(0x0080))
00524 #define SET_STENCIL_FUNC(dx9data, cmp, ref, mask, writemask) SEMI_PROTECT(\
00525     ENSURE_STENCIL_FUNC(dx9data, cmp); \
00526     ENSURE_STENCIL_REF(dx9data, ref); \
00527     ENSURE_STENCIL_MASK(dx9data, mask); \
00528     ENSURE_STENCIL_WRITE_MASK(dx9data, writemask); \
00529 )
00530 
00531 #define SET_STENCIL_OP(dx9data, fail, zfail, pass) SEMI_PROTECT(\
00532     ENSURE_STENCIL_OP(dx9data, fail, zfail, pass); \
00533 )
00534 
00535 /*
00536  * TEXTURE STATES
00537  */
00538 #define FORCE_TEXTURE_WRAP_S(dx9data, unit, mode) SEMI_PROTECT(\
00539     dx9data->cache.texture_wrap_s[unit] = mode; \
00540     dx9data->pDevice->SetSamplerState(unit, D3DSAMP_ADDRESSU, mode); \
00541 )
00542 
00543 #define ENSURE_TEXTURE_WRAP_S(dx9data, unit, mode) SEMI_PROTECT(\
00544     if (dx9data->cache.texture_wrap_s[unit] != mode) \
00545         FORCE_TEXTURE_WRAP_S(dx9data, unit, mode); \
00546 )
00547 
00548 #define FORCE_TEXTURE_WRAP_T(dx9data, unit, mode) SEMI_PROTECT(\
00549     dx9data->cache.texture_wrap_t[unit] = mode; \
00550     dx9data->pDevice->SetSamplerState(unit, D3DSAMP_ADDRESSV, mode); \
00551 )
00552 
00553 #define ENSURE_TEXTURE_WRAP_T(dx9data, unit, mode) SEMI_PROTECT(\
00554     if (dx9data->cache.texture_wrap_t[unit] != mode) \
00555         FORCE_TEXTURE_WRAP_T(dx9data, unit, mode); \
00556 )
00557 
00558 #define FORCE_TEXTURE_MIN_FILTER(dx9data, unit, mode) SEMI_PROTECT(\
00559     dx9data->cache.texture_min_filter[unit] = mode; \
00560     dx9data->pDevice->SetSamplerState(unit, D3DSAMP_MINFILTER, mode); \
00561 )
00562 
00563 #define ENSURE_TEXTURE_MIN_FILTER(dx9data, unit, mode) SEMI_PROTECT(\
00564     if (dx9data->cache.texture_min_filter[unit] != mode) \
00565         FORCE_TEXTURE_MIN_FILTER(dx9data, unit, mode); \
00566 )
00567 
00568 #define FORCE_TEXTURE_MAG_FILTER(dx9data, unit, mode) SEMI_PROTECT(\
00569     dx9data->cache.texture_mag_filter[unit] = mode; \
00570     dx9data->pDevice->SetSamplerState(unit, D3DSAMP_MAGFILTER, mode); \
00571 )
00572 
00573 #define ENSURE_TEXTURE_MAG_FILTER(dx9data, unit, mode) SEMI_PROTECT(\
00574     if (dx9data->cache.texture_mag_filter[unit] != mode) \
00575         FORCE_TEXTURE_MAG_FILTER(dx9data, unit, mode); \
00576 )
00577 
00578 #define FORCE_TEXTURE_MIP_FILTER(dx9data, unit, mode) SEMI_PROTECT(\
00579     dx9data->cache.texture_mip_filter[unit] = mode; \
00580     dx9data->pDevice->SetSamplerState(unit, D3DSAMP_MIPFILTER, mode); \
00581 )
00582 
00583 #define ENSURE_TEXTURE_MIP_FILTER(dx9data, unit, mode) SEMI_PROTECT(\
00584     if (dx9data->cache.texture_mip_filter[unit] != mode) \
00585         FORCE_TEXTURE_MIP_FILTER(dx9data, unit, mode); \
00586 )
00587 
00588 #define ENSURE_SAMPLER_STATE(dx9data, unit, filter, mip_filter, wrap) SEMI_PROTECT(\
00589     ENSURE_TEXTURE_MIN_FILTER(dx9data, unit, filter); \
00590     ENSURE_TEXTURE_MAG_FILTER(dx9data, unit, filter); \
00591     ENSURE_TEXTURE_MIP_FILTER(dx9data, unit, mip_filter); \
00592     ENSURE_TEXTURE_WRAP_S(dx9data, unit, wrap); \
00593     ENSURE_TEXTURE_WRAP_T(dx9data, unit, wrap); \
00594 )
00595 
00596 #define INVALIDATE_TEXTURE_SETTING_CACHE(dx9data) SEMI_PROTECT(\
00597     { \
00598         int _unit_; \
00599         for (_unit_ = 0; _unit_ < MAX_TEXTURE_UNIT; ++_unit_) { \
00600             (dx9data)->cache.texture_wrap_s[_unit_] = INVALID_CACHE; \
00601             (dx9data)->cache.texture_wrap_t[_unit_] = INVALID_CACHE; \
00602             (dx9data)->cache.texture_mag_filter[_unit_] = INVALID_CACHE; \
00603             (dx9data)->cache.texture_min_filter[_unit_] = INVALID_CACHE; \
00604             (dx9data)->cache.texture_mip_filter[_unit_] = INVALID_CACHE; \
00605         } \
00606     } \
00607 )
00608 
00609 
00610 /*
00611  * ATMOSPHERIC ATTENUATION
00612  */
00613 #define ENSURE_FOG_OFF(dx9data, nr) SEMI_PROTECT(\
00614     if ((dx9data)->cache.fog_on != false) { \
00615         (dx9data)->cache.fog_on = false; \
00616         (dx9data)->pDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); \
00617     } \
00618 )
00619 
00620 #define ENSURE_FOG_ON(dx9data, nr) SEMI_PROTECT (\
00621     dx9data->cache.fog_on = true; \
00622     dx9data->pDevice->SetRenderState(D3DRS_FOGENABLE, TRUE); /*glEnable (GL_FOG);*/ \
00623     if (nr->visualization_rendition->incarnation != dx9data->fog_incarnation) { \
00624         /*float fog_color[4];*/ \
00625         dx9data->fog_incarnation = nr->misc_rendition->incarnation; \
00626         /* do not do pixel fog calculations */ \
00627         dx9data->pDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE); \
00628         dx9data->pDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR); \
00629         dx9data->pDevice->SetRenderState(D3DRS_FOGCOLOR, D3DCOLOR_XRGB(nr->window_rendition->window_color.direct_rgb.r, nr->window_rendition->window_color.direct_rgb.g, nr->window_rendition->window_color.direct_rgb.r)); \
00630     } \
00631 )
00632 
00633 
00634 //stores a substrip of an HT_Tristrip or HT_Polyedge
00635 struct hdx9_indexed_primitive
00636 {
00637     H3DPRIMITIVETYPE type; //e.g. H3DPT_TRIANGLESTRIP or H3DPT_TRIANGLEFAN
00638     unsigned int size;
00639     unsigned int count;
00640     IDirect3DIndexBuffer9 *idx_buff;
00641 };
00642 
00643 
00644 #define HDX9_PER_OBJECT_PENALTY 128
00645 
00646 
00647 
00648 class HDX9Mesh : public H3DIndexedBufferObject
00649 {
00650 public:
00651     ID3DXMesh                               *m_d3dxmesh;
00652 
00653     HDX9Mesh() 
00654     {
00655         OUR(display_list_vram_usage) += HDX9_PER_OBJECT_PENALTY;
00656     }
00657     ~HDX9Mesh()
00658     {
00659         m_d3dxmesh->Release();
00660     }
00661 
00662     //called once per HT_Tristrip
00663     bool CreateMesh (H3DData *h3ddata,
00664                         UINT point_count, 
00665                         UINT face_count,
00666                         H3DVertexFormat VF)
00667     {
00668         DX9Data *dx9data = (DX9Data *) h3ddata;
00669         HRESULT hr;
00670 
00671         m_point_count   = point_count;
00672         m_stride        = VF.get_size();
00673         m_VF            = VF;
00674 
00675         do {
00676              hr = D3DXCreateMeshFVF(
00677                                 face_count,
00678                                 point_count,
00679                                 D3DXMESH_32BIT | D3DXMESH_SYSTEMMEM,
00680                                 vf2fvf(VF),
00681                                 dx9data->pDevice,
00682                                 &m_d3dxmesh);
00683         } while (hr == D3DERR_NOTAVAILABLE);
00684         return SUCCEEDED(hr);
00685     }
00686 
00687 
00688     bool LockIndexBuffer(UINT OffsetToLock, UINT SizeToLock, H3DIndexBuffer *ib, DWORD Flags)
00689     {
00690         UNREFERENCED(OffsetToLock);
00691         UNREFERENCED(SizeToLock);
00692         void *p;
00693 
00694         m_format = H3DFMT_INDEX32;
00695 
00696         HRESULT hr = m_d3dxmesh->LockIndexBuffer(Flags, (void**)&p);
00697         ib->Init(m_format, p);
00698         return SUCCEEDED(hr);
00699     }
00700 
00701     bool LockVertexBuffer(UINT OffsetToLock, UINT SizeToLock, H3DVertexBuffer *pv, DWORD Flags)
00702     {
00703         UNREFERENCED(OffsetToLock);
00704         UNREFERENCED(SizeToLock);
00705         float *data;
00706         HRESULT hr = m_d3dxmesh->LockVertexBuffer(Flags, (void**)&data);
00707         pv->Init(data, m_VF);
00708         return SUCCEEDED(hr);
00709     }
00710 
00711     void UnlockIndexBuffer()
00712     {
00713         m_d3dxmesh->UnlockIndexBuffer();
00714     }
00715 
00716     void UnlockVertexBuffer()
00717     {
00718         m_d3dxmesh->UnlockVertexBuffer();
00719     }
00720 
00721     bool CreateVertexBuffer (H3DData *h3ddata,
00722                                 UINT point_count, 
00723                                 H3DVertexFormat VF)
00724     {
00725         UNREFERENCED(h3ddata);
00726         UNREFERENCED(point_count);
00727         UNREFERENCED(VF);
00728         return false;
00729     };
00730     bool CreateIndexBuffer (H3DData *h3ddata,
00731                                 H3DPRIMITIVETYPE type, 
00732                                 UINT size,
00733                                 UINT count)
00734     {
00735         UNREFERENCED(h3ddata);
00736         UNREFERENCED(type);
00737         UNREFERENCED(size);
00738         UNREFERENCED(count);
00739         return false;
00740     };
00741     void Draw(H3DData *h3ddata, HT_Test *cull_results = null)
00742     {
00743         UNREFERENCED(h3ddata);
00744         UNREFERENCED(cull_results);
00745     }
00746 };
00747 
00748 
00749 // this is the buffer object data structure which caches the vertex and index buffers
00750 // Stores an entire HT_Tristrip or HT_Polyedge
00751 class HDX9IndexedBufferObject : public H3DIndexedBufferObject
00752 {
00753 public:
00754     IDirect3DVertexBuffer9                  *m_vtx_buff;
00755     hdx9_indexed_primitive                  *m_primitives;
00756 
00757     HDX9IndexedBufferObject() 
00758     {
00759         OUR(display_list_vram_usage) += HDX9_PER_OBJECT_PENALTY;
00760         m_primitives = null;
00761     }
00762     ~HDX9IndexedBufferObject()
00763     {
00764         H_SAFE_RELEASE(m_vtx_buff);
00765         OUR(display_list_vram_usage) -= HDX9_PER_OBJECT_PENALTY;
00766         OUR(display_list_vram_usage) -= (m_stride * m_point_count);
00767 
00768         if (m_format == H3DFMT_INDEX16)
00769             OUR(display_list_vram_usage) -= (m_primitives->size * sizeof(short));
00770         else
00771             OUR(display_list_vram_usage) -= (m_primitives->size * sizeof(int));
00772         H_SAFE_RELEASE(m_primitives->idx_buff);
00773         H_SAFE_DELETE(m_primitives);
00774     }
00775 
00776     //called once per HT_Tristrip
00777     bool CreateVertexBuffer (H3DData *h3ddata,
00778                                 UINT point_count, 
00779                                 H3DVertexFormat VF)
00780     {
00781         DX9Data *dx9data = (DX9Data *) h3ddata;
00782         m_point_count   = point_count;
00783         m_stride        = VF.get_size();
00784         m_VF            = VF;       //the flexible vertex format
00785         HRESULT hr;
00786         do {
00787             hr = dx9data->pDevice->CreateVertexBuffer(
00788                                                     point_count*m_stride, 
00789                                                     D3DUSAGE_WRITEONLY,  
00790                                                     vf2fvf(VF), 
00791                                                     HDX9_POOL_TYPE,
00792                                                     &m_vtx_buff, 
00793                                                     NULL);
00794         } while (hr == D3DERR_NOTAVAILABLE);
00795 
00796         OUR(display_list_vram_usage) += (m_stride * m_point_count);
00797         return SUCCEEDED(hr);
00798     }
00799 
00800     //called ts->strips times per HT_Tristrip
00801     bool CreateIndexBuffer (H3DData *h3ddata,
00802                                H3DPRIMITIVETYPE type, 
00803                                UINT size,
00804                                UINT count)
00805     {
00806         DX9Data *dx9data = (DX9Data *) h3ddata;
00807         IDirect3DIndexBuffer9* pIndexBuffer;
00808         D3DCAPS9 caps;
00809         dx9data->pDevice->GetDeviceCaps(&caps);
00810 
00811         hdx9_indexed_primitive * ip = new hdx9_indexed_primitive();
00812         ip->type = type;
00813         ip->size = size;
00814         ip->count = count;
00815         m_primitives = ip;
00816 
00817         if (m_point_count > caps.MaxVertexIndex)
00818             HE_ERROR(HEC_DX9_DRIVER, HEC_DX9_DRIVER,
00819             "Internal error: point count exceeds maximum vertex index.");
00820 
00821         if (m_point_count <= 0x0000ffff && count <= 0x0000ffff)
00822             m_format = H3DFMT_INDEX16;
00823         else
00824             m_format = H3DFMT_INDEX32;
00825 
00826         HRESULT hr;
00827         do {
00828             hr = dx9data->pDevice->CreateIndexBuffer(
00829                                                     size, 
00830                                                     D3DUSAGE_WRITEONLY,  
00831                                                     d3dformat(m_format), 
00832                                                     HDX9_POOL_TYPE,
00833                                                     &pIndexBuffer, 
00834                                                     NULL);
00835         } while (hr == D3DERR_NOTAVAILABLE);
00836         ip->idx_buff = pIndexBuffer;
00837 
00838         if (m_format == D3DFMT_INDEX16)
00839             OUR(display_list_vram_usage) += (ip->size * sizeof(short));
00840         else
00841             OUR(display_list_vram_usage) += (ip->size * sizeof(int));
00842         return SUCCEEDED(hr);
00843     }
00844 
00845     bool LockIndexBuffer(UINT OffsetToLock, UINT SizeToLock, H3DIndexBuffer *ib, DWORD Flags)
00846     {
00847         void *p;
00848         HRESULT hr = m_primitives->idx_buff->Lock(OffsetToLock, SizeToLock, &p, Flags);
00849         ib->Init(m_format, p);
00850         return SUCCEEDED(hr);
00851     }
00852 
00853     bool LockVertexBuffer(UINT OffsetToLock, UINT SizeToLock, H3DVertexBuffer *pv, DWORD Flags)
00854     {
00855         float *data;
00856         HRESULT hr = m_vtx_buff->Lock(OffsetToLock, SizeToLock, (void **) &data, Flags);
00857 
00858         pv->Init(data, m_VF);
00859         return SUCCEEDED(hr);
00860     }
00861 
00862     void UnlockIndexBuffer()
00863     {
00864         if (m_primitives)
00865             m_primitives->idx_buff->Unlock();
00866     }
00867 
00868     void UnlockVertexBuffer()
00869     {
00870         m_vtx_buff->Unlock();
00871     }
00872 
00873     void Draw(H3DData *h3ddata, HT_Test *cull_results = null)
00874     {
00875         DX9Data *dx9data = (DX9Data *) h3ddata;
00876         ENSURE_VF(dx9data, m_VF);
00877         dx9data->pDevice->SetStreamSource (0, m_vtx_buff, 0, m_stride);
00878         dx9data->pDevice->SetIndices(m_primitives->idx_buff);
00879 
00880         if (cull_results == null) {
00881             dx9data->pDevice->DrawIndexedPrimitive (
00882                                     d3dprimitive(m_primitives->type), 
00883                                     0, 
00884                                     0, 
00885                                     m_point_count, 
00886                                     0, 
00887                                     m_primitives->count);
00888         }
00889         else {
00890             int prev = 0;
00891             int len = 0;
00892             int k = 0;
00893             int primitive_count = 0;
00894 
00895             for (;;) {
00896                 while (k < m_tristrip_count && 
00897                     CULL_ACCEPT(cull_results[k + m_tristrip_first])) {
00898                         len = m_tristrip_offsets[k] - prev;             
00899                         k++;
00900                 }
00901 
00902                 // Either we failed on a culling test, or we successfully finished. In both cases, we
00903                 // need to figure out what length of the last tristrip to be drawn, and add to the
00904                 // total length.
00905                 if (k == m_tristrip_count) {
00906                     // since we only store the first index of each tristrip, we need to calculate
00907                     // the length of the last one (as it's not readily stored in the offsets array)
00908 
00909                     int bytes_per_index = 0;
00910                     if (m_format == H3DFMT_INDEX32)
00911                         bytes_per_index = sizeof(int);
00912                     else
00913                         bytes_per_index = sizeof(short);
00914 
00915                     len += ((m_primitives->size / bytes_per_index) - m_tristrip_offsets[k-1]);
00916                 }
00917                 else
00918                     len = m_tristrip_offsets[k] - prev;
00919 
00920 
00921                 if (len > 0) {
00922                     switch (m_primitives->type) {
00923                         case H3DPT_TRIANGLELIST:
00924                             primitive_count = len / 3;
00925                             break;
00926                         case H3DPT_TRIANGLESTRIP:
00927                             primitive_count = len - 2;
00928                             break;
00929                         default:
00930                             ASSERT(0);
00931                             break;
00932                     }
00933 
00934                     dx9data->pDevice->DrawIndexedPrimitive (
00935                                     d3dprimitive(m_primitives->type), 
00936                                     0, 
00937                                     0, 
00938                                     m_point_count, 
00939                                     prev, 
00940                                     primitive_count);
00941                 }
00942                 while (k < m_tristrip_count && 
00943                     !CULL_ACCEPT(cull_results[k + m_tristrip_first])) {
00944                         prev = m_tristrip_offsets[k];
00945                         k++;
00946                 }
00947                 if (k == m_tristrip_count)
00948                     break;
00949             }
00950         }
00951     }
00952 };
00953 
00954 
00955 // this is the global vertex buffer cache, being used for view dependent geometry
00956 class HDX9VertexBufferCache : public H3DVertexBufferCache
00957 {
00958 public:
00959     HDX9VertexBufferCache()
00960     {
00961         OUR(display_list_vram_usage) += HDX9_PER_OBJECT_PENALTY;
00962         m_pVertexBuffer = 0;
00963         m_nMaxPoints    = 0;
00964         m_nNextVertexData = 0;
00965         m_nCurVertexData = 0;
00966     }
00967 
00968     ~HDX9VertexBufferCache()
00969     {
00970         OUR(display_list_vram_usage) -= HDX9_PER_OBJECT_PENALTY;
00971         H_SAFE_RELEASE(m_pVertexBuffer);
00972         OUR(display_list_vram_usage) -= (m_nMaxPoints * m_nVertexStride);
00973     }
00974 
00975     bool CreateVertexBuffer(H3DData *h3ddata, UINT max_points, 
00976         H3DVertexFormat VF)
00977     {
00978         H_SAFE_RELEASE(m_pVertexBuffer);
00979         DX9Data *dx9data = (DX9Data *) h3ddata;
00980 
00981         m_nMaxPoints    = max_points;
00982         m_nVertexStride = VF.get_size();
00983         m_VF            = VF;
00984         HRESULT hr = dx9data->pDevice->CreateVertexBuffer(m_nMaxPoints*m_nVertexStride, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,  
00985                                                 vf2fvf(VF), D3DPOOL_DEFAULT, &m_pVertexBuffer, NULL);
00986 
00987         OUR(display_list_vram_usage) += (m_nMaxPoints * m_nVertexStride);
00988         return !FAILED(hr);
00989     }
00990 
00991     bool Reset()
00992     {
00993         H_SAFE_RELEASE(m_pVertexBuffer);
00994         OUR(display_list_vram_usage) -= (m_nMaxPoints * m_nVertexStride);
00995 
00996         m_nMaxPoints    = 0;
00997         m_nNextVertexData = 0;
00998         m_nCurVertexData = 0;
00999         return true;
01000     }
01001 
01002     bool Discard()
01003     {
01004         m_nNextVertexData = 0;
01005         m_nCurVertexData = 0;
01006         void * pData;
01007         m_pVertexBuffer->Lock((UINT)m_nNextVertexData, 0, &pData, D3DLOCK_DISCARD);
01008         m_pVertexBuffer->Unlock();
01009         return true;
01010     }
01011 
01012     bool Lock(UINT count, H3DVertexBuffer *pv)
01013     {
01014         float *pvbuf = null;
01015 
01016         // Determine the size of data to be moved into the vertex buffer.
01017         UINT data_size = count * m_nVertexStride;
01018 
01019         // No overwrite will be used if the vertices can fit into 
01020         //       the space remaining in the vertex buffer.
01021         DWORD dwLockFlags = D3DLOCK_NOOVERWRITE;
01022 
01023         // Check to see if the entire vertex buffer has been used up yet.
01024         if (m_nNextVertexData > (m_nMaxPoints*m_nVertexStride - data_size))
01025         {
01026             // No space remains. Start over from the beginning 
01027             //       of the vertex buffer.
01028             dwLockFlags = D3DLOCK_DISCARD;
01029             m_nCurVertexData = 0;
01030             m_nNextVertexData = 0;
01031         }
01032 
01033         // Lock the vertex buffer.
01034         HRESULT hr;
01035         if (FAILED(hr = m_pVertexBuffer->Lock((UINT)m_nNextVertexData, data_size, 
01036             (void **) &pvbuf, dwLockFlags)))
01037             return false;
01038 
01039         pv->Init(pvbuf, m_VF);
01040 
01041         // Advance to the next position in the vertex buffer.
01042         m_nNextVertexData += data_size;
01043 
01044         return true;
01045     }
01046 
01047     bool Unlock(VOID)
01048     {
01049         return !FAILED(m_pVertexBuffer->Unlock());
01050     }
01051 
01052     bool Draw(H3DData *h3ddata , H3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount)
01053     {
01054         // Render the primitives.
01055         bool result = DrawRepeatable(h3ddata, PrimitiveType, PrimitiveCount);
01056         DrawComplete();
01057         return result;
01058     }
01059 
01060     bool DrawRepeatable(H3DData *h3ddata , H3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount)
01061     {
01062         // Render the primitives.
01063         DX9Data *dx9data = (DX9Data *) h3ddata;
01064         ENSURE_VF(dx9data, m_VF);
01065         dx9data->pDevice->SetStreamSource(0, m_pVertexBuffer, 0, m_nVertexStride);
01066         HRESULT hr = dx9data->pDevice->DrawPrimitive(d3dprimitive(PrimitiveType), m_nCurVertexData/m_nVertexStride, PrimitiveCount);
01067         return !FAILED(hr);
01068     }
01069 
01070     void DrawComplete()
01071     {
01072         m_nCurVertexData = m_nNextVertexData;
01073     }
01074 
01075     IDirect3DVertexBuffer9  *m_pVertexBuffer;
01076 };
01077 
01078 
01079 // an index buffer, used in conjunction with a HDX9VertexBufferCache class. Can use any HDX9VertexBufferCache
01080 class HDX9IndexBufferCache : public H3DIndexBufferCache
01081 {
01082 public:
01083     HDX9IndexBufferCache()
01084     {
01085         OUR(display_list_vram_usage) += HDX9_PER_OBJECT_PENALTY;
01086         m_pIndexBuffer = 0;
01087         m_nNextIndexData = 0;
01088         m_nCurIndexData = 0;
01089     }
01090 
01091     ~HDX9IndexBufferCache()
01092     {
01093         OUR(display_list_vram_usage) -= HDX9_PER_OBJECT_PENALTY;
01094         OUR(display_list_vram_usage) -= (VB_CACHE_MAX_SIZE * sizeof(short));
01095         H_SAFE_RELEASE(m_pIndexBuffer);
01096     }
01097 
01098     bool CreateIndexBuffer(H3DData *h3ddata)
01099     {
01100         HRESULT hr = S_OK;
01101         DX9Data *dx9data = (DX9Data *) h3ddata;
01102         LPDIRECT3DDEVICE9 pDevice = dx9data->pDevice;
01103 
01104         ASSERT(VB_CACHE_MAX_SIZE < 0x0000ffff); //index buffer cache does not support 32 bit indices
01105         if (m_pIndexBuffer == NULL)
01106             hr = pDevice->CreateIndexBuffer (
01107                 VB_CACHE_MAX_SIZE * sizeof(short), 
01108                 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 
01109                 D3DFMT_INDEX16,
01110                 D3DPOOL_DEFAULT,
01111                 &m_pIndexBuffer,
01112                 NULL);
01113 
01114         OUR(display_list_vram_usage) += (VB_CACHE_MAX_SIZE * sizeof(short));
01115         return SUCCEEDED(hr);
01116     }
01117 
01118     bool Lock(short count, VOID **ppbData)
01119     {
01120         HRESULT hr;
01121         int sizetolock = count * sizeof(short);
01122         if (m_nNextIndexData > (VB_CACHE_MAX_SIZE * sizeof(short) - sizetolock)) {
01123             m_nCurIndexData = m_nNextIndexData = 0;
01124             hr = m_pIndexBuffer->Lock(0, sizetolock, ppbData, D3DLOCK_DISCARD);
01125         }
01126         else {
01127             hr = m_pIndexBuffer->Lock(m_nNextIndexData, sizetolock, ppbData, D3DLOCK_NOOVERWRITE);
01128         }
01129         m_nNextIndexData += sizetolock;
01130 
01131         return SUCCEEDED(hr);
01132     }
01133 
01134     bool Unlock(VOID)
01135     {
01136         return SUCCEEDED(m_pIndexBuffer->Unlock());
01137     }
01138 
01139     bool Draw(H3DData *h3ddata , H3DPRIMITIVETYPE PrimitiveType, 
01140         UINT VertexCount,
01141         UINT PrimitiveCount)
01142     {
01143         DX9Data *dx9data = (DX9Data *) h3ddata;
01144         // Render the primitives.
01145         ENSURE_VF(dx9data, m_pVertexBufferCache->m_VF);
01146         dx9data->pDevice->SetStreamSource (0, 
01147             (IDirect3DVertexBuffer9 *) m_pVertexBufferCache->m_pVertexBuffer, 
01148             m_pVertexBufferCache->m_nCurVertexData, 
01149             m_pVertexBufferCache->m_nVertexStride);
01150         dx9data->pDevice->SetIndices (m_pIndexBuffer);
01151         HRESULT hr = dx9data->pDevice->DrawIndexedPrimitive (
01152             d3dprimitive(PrimitiveType), 
01153             0, 
01154             0, 
01155             VertexCount, 
01156             m_nCurIndexData/sizeof(short), 
01157             PrimitiveCount);
01158         return SUCCEEDED(hr);
01159     }
01160 
01161     void DrawComplete()
01162     {
01163         m_nCurIndexData = m_nNextIndexData;
01164         m_pVertexBufferCache->m_nCurVertexData = m_pVertexBufferCache->m_nNextVertexData;
01165     }
01166 
01167     void SetVertexBufferCache (H3DVertexBufferCache *vbcache)
01168     {
01169         m_pVertexBufferCache = (HDX9VertexBufferCache *) vbcache;
01170     }
01171 
01172     IDirect3DIndexBuffer9   *m_pIndexBuffer;
01173     HDX9VertexBufferCache   *m_pVertexBufferCache;
01174     UINT                    m_nCurIndexData;
01175     UINT                    m_nNextIndexData;
01176 };
01177 
01178 
01179 /*****************************************************************************
01180 *****************************************************************************
01181                         HDX9Shader Class
01182 *****************************************************************************
01183 *****************************************************************************/
01184 class HDX9Shader : public H3DShader
01185 {
01186 protected:
01187     virtual void ComposeDumpFilename (H3DShaderID &id, bool isVS, char alter *dump_filename);
01188     virtual bool DumpHLSL (char const *filename, char const *contents);
01189     virtual char alter *ComposePreamble (H3DShaderID &id, char alter *ptr, char const *end, int model, char const *dump_filename);
01190     virtual char alter *AppendBaseHLSL (const char *filename, const char *string, char alter *ptr, char const *end);
01191 
01192 public:
01193     IDirect3DDevice9 *m_pDevice;
01194     IDirect3DVertexShader9 *m_pVS;
01195     IDirect3DPixelShader9 *m_pPS;
01196     ID3DXConstantTable *m_pVSConstantTable;
01197     ID3DXConstantTable *m_pPSConstantTable;
01198 
01199 #define INVALID_HANDLE      (D3DXHANDLE)(-1)
01200     struct Cache {
01201         // 3D constants
01202         D3DXHANDLE model;
01203         D3DXHANDLE modelview;
01204         D3DXHANDLE projection;
01205         D3DXHANDLE normalizedmodelview;
01206 
01207         D3DXHANDLE materialgloss_ps;
01208         D3DXHANDLE materialgloss_vs;
01209         D3DXHANDLE colormapsize;
01210         D3DXHANDLE mirror;
01211         D3DXHANDLE camerapos;
01212 
01213         D3DXHANDLE ambient;
01214         D3DXHANDLE *distantlight_direction;
01215         D3DXHANDLE *distantlight_diffuse;
01216         D3DXHANDLE *distantlight_specular;
01217         D3DXHANDLE *distantlight_halfway;
01218         D3DXHANDLE *pointlight_position;
01219         D3DXHANDLE *pointlight_diffuse;
01220         D3DXHANDLE *pointlight_specular;
01221         D3DXHANDLE *spotlight_position;
01222         D3DXHANDLE *spotlight_direction;
01223         D3DXHANDLE *spotlight_angles;
01224         D3DXHANDLE *spotlight_diffuse;
01225         D3DXHANDLE *spotlight_specular;
01226         
01227         D3DXHANDLE shadow_maps[H3D_MAX_SHADOW_MAPS];
01228 
01229 #ifdef SHADOW_DISTORTION_DEMO
01230         D3DXHANDLE create_shadow_distortion;
01231         D3DXHANDLE shadow_distortion[H3D_MAX_SHADOW_MAPS];
01232 #endif // SHADOW_DISTORTION_DEMO
01233 
01234         D3DXHANDLE modulationcolor[H3D_MAX_TEXTURES];
01235 
01236         D3DXHANDLE atmosphericattenuation_hither;
01237         D3DXHANDLE atmosphericattenuation_yon;
01238         D3DXHANDLE atmosphericattenuation_color;
01239 
01240         D3DXHANDLE reflection_plane;
01241 
01242         // DC constants
01243         D3DXHANDLE worldviewproj;
01244         D3DXHANDLE color;
01245         D3DXHANDLE lineweight;
01246         D3DXHANDLE circlesubimagestart;
01247         D3DXHANDLE cosjoincutoffangle;
01248 
01249         //constants that apply to both DC and 3D
01250         D3DXHANDLE viewport_scale_and_bias;
01251         D3DXHANDLE jitter_scale_and_bias;
01252         D3DXHANDLE window_width;
01253         D3DXHANDLE window_height;
01254         D3DXHANDLE facecontrastcolor;
01255         D3DXHANDLE linecontrastcolor;
01256         D3DXHANDLE facedisplacement;
01257         D3DXHANDLE generaldisplacement;
01258         D3DXHANDLE texture[H3D_MAX_TEXTURES];
01259         D3DXHANDLE diffuse_ps;
01260         D3DXHANDLE materialdiffuse_ps;
01261         D3DXHANDLE materialdiffuse_vs;
01262         D3DXHANDLE cuttingplane[H3D_MAX_CUTTING_PLANES];
01263     } cache;
01264 
01265     HDX9Shader (const H3DShaderID& id);
01266     ~HDX9Shader ();
01267 
01268     bool Create (H3DData *h3ddata);
01269     bool Activate (void);
01270 
01271     void Force2DTransform (float *matrix);
01272     void Ensure3DTransform (HT_Net_Rendition const *nr);
01273     void EnsureDCTransform (HT_Net_Rendition const *nr);
01274     void EnsureColor (HT_Direct_RGB const *color);
01275     void EnsureLights (
01276                     HT_Net_Rendition const *nr, 
01277                     HT_Light_Rendition const *lr, 
01278                     HT_Material_Rendition const *mr,
01279                     HT_Driver_Color const *color);
01280     void EnsureLineStyle (
01281                     HT_Net_Rendition const *nr, 
01282                     HT_Line_Rendition const *er);
01283     void EnsureCuttingPlanes (HT_Net_Rendition const *nr, HT_Cutting_Plane_Set const *cutset);
01284     void EnsureDCCuttingPlanes (HT_Cutting_Plane_Set const *cutset);
01285     void EnsureReflectionPlane (H3DData::ReflectionPlaneConstants const & constants);
01286     void EnsureDepthPeeling (H3DTexture *texture, H3DData *h3ddata);
01287 };
01288 
01289 
01290 #define ENSURE_CONSTANT_HANDLE(const_table, cache, parent, constant) SEMI_PROTECT (\
01291     if (cache == null) { \
01292         cache = const_table->GetConstantByName(parent, constant); \
01293         if (cache == null) \
01294             cache = INVALID_HANDLE; \
01295     } \
01296 );
01297 #define SET_CONSTANT(device, const_table, cache, parent, constant, value, action) SEMI_PROTECT (\
01298     ENSURE_CONSTANT_HANDLE(const_table, cache, parent, constant); \
01299     if (cache != INVALID_HANDLE) \
01300         const_table->action(device, cache, value); \
01301 );
01302 #define SET_CONSTANT_ARRAY(device, const_table, cache, parent, constant, value, size, action) SEMI_PROTECT (\
01303     ENSURE_CONSTANT_HANDLE(const_table, cache, parent, constant); \
01304     if (cache != INVALID_HANDLE) \
01305         const_table->action(device, cache, value, size); \
01306 );
01307 
01308 #define SET_CONSTANT_FLOAT(device, const_table, cache, parent, constant, value) \
01309     SET_CONSTANT(device, const_table, cache, parent, constant, value, SetFloat);
01310 
01311 #define SET_CONSTANT_FLOAT_ARRAY(device, const_table, cache, parent, constant, value, size) \
01312     SET_CONSTANT_ARRAY(device, const_table, cache, parent, constant, value, size, SetFloatArray);
01313 
01314 #define SET_CONSTANT_INT(device, const_table, cache, parent, constant, value) \
01315     SET_CONSTANT(device, const_table, cache, parent, constant, value, SetInt);
01316 
01317 #define SET_CONSTANT_INT_ARRAY(device, const_table, cache, parent, constant, value, size) \
01318     SET_CONSTANT_ARRAY(device, const_table, cache, parent, constant, value, size, SetIntArray);
01319 
01320 #define SET_CONSTANT_MATRIX(device, const_table, cache, parent, constant, value) \
01321     SET_CONSTANT(device, const_table, cache, parent, constant, value, SetMatrix);
01322 
01323 #define SET_CONSTANT_MATRIX_ARRAY(device, const_table, cache, parent, constant, value, size) \
01324     SET_CONSTANT_ARRAY(device, const_table, cache, parent, constant, value, size, SetMatrixArray);
01325 
01326 #define SET_CONSTANT_VECTOR(device, const_table, cache, parent, constant, value) \
01327     SET_CONSTANT(device, const_table, cache, parent, constant, value, SetVector)
01328 
01329 #define SET_CONSTANT_VECTOR_ARRAY(device, const_table, cache, parent, constant, value, size) \
01330     SET_CONSTANT_ARRAY(device, const_table, cache, parent, constant, value, size, SetVectorArray);
01331 
01332 
01333 
01334 local void depth_peeling_hardware(HT_Display_Context alter * dc);
01335 local void depth_peeling_float(HT_Display_Context alter * dc);
01336 
01337 
01338 
01339 
01340 /*****************************************************************************
01341 *****************************************************************************
01342                             HDX9Texture Class
01343 *****************************************************************************
01344 *****************************************************************************/
01345 class HDX9Texture : public H3DTexture
01346 {
01347 private:
01348     LPDIRECT3DTEXTURE9 m_id;
01349     D3DLOCKED_RECT m_rect;
01350 
01351 public:
01352     HRESULT hr;
01353 
01354 public:
01355     HDX9Texture(H3DData *h3ddata, 
01356         unsigned int width, 
01357         unsigned int height,
01358         unsigned int levels,
01359         unsigned int usage,
01360         H3DFORMAT z_format)
01361     {
01362         DX9Data *dx9data = (DX9Data *) h3ddata;
01363         m_h3ddata = h3ddata;
01364         D3DFORMAT format = D3DFMT_A8R8G8B8;
01365         D3DPOOL pool = D3DPOOL_DEFAULT;
01366         unsigned int tex_usage = 0;
01367 
01368         if (BIT(usage, H3DTEXUSAGE_RENDERTARGET)) 
01369             tex_usage = D3DUSAGE_RENDERTARGET;
01370         else if (BIT(usage, H3DTEXUSAGE_DEPTHSTENCIL))
01371             tex_usage = D3DUSAGE_DEPTHSTENCIL;
01372         else
01373             pool = D3DPOOL_MANAGED;
01374 
01375         if (BIT(usage, H3DTEXUSAGE_AUTOGENMIPMAP))
01376             tex_usage |= D3DUSAGE_AUTOGENMIPMAP;
01377         
01378         switch (z_format)
01379         {
01380         case H3DFMT_A8R8G8B8:
01381             format = D3DFMT_A8R8G8B8;
01382             break;
01383         case H3DFMT_R32F:
01384             format = D3DFMT_R32F;
01385             break;
01386         default:
01387             HE_ERROR(HEC_DX9_DRIVER, HEC_DX9_DRIVER, 
01388                 "Internal error: unhandled DX9 texture format!");
01389         }
01390 
01391         hr = dx9data->pDevice->CreateTexture(width, height, levels, tex_usage,
01392             format, pool, &m_id, NULL);
01393     }
01394 
01395     ~HDX9Texture()
01396     {
01397         H_SAFE_RELEASE(m_id);
01398     };
01399 
01400     bool Lock(H3DRect *h3drect, void ** data, int * pitch = null)
01401     {
01402         HRESULT hr;
01403         RECT rect;
01404         if (h3drect)
01405         {
01406             rect.top = h3drect->top;
01407             rect.bottom = h3drect->bottom;
01408             rect.right = h3drect->right;
01409             rect.left = h3drect->left;
01410             hr = m_id->LockRect(0, &m_rect, &rect, 0);
01411         }
01412         else
01413             hr = m_id->LockRect(0, &m_rect, 0, 0);
01414         *data = m_rect.pBits;
01415         if (pitch)
01416             *pitch = m_rect.Pitch;
01417         return SUCCEEDED(hr);
01418     }
01419 
01420     void Unlock()
01421     {
01422         m_id->UnlockRect(0);
01423         ZERO_STRUCT(&m_rect, D3DLOCKED_RECT);
01424     }
01425 
01426     void GenerateMipMaps()
01427     {
01428         m_id->GenerateMipSubLevels();
01429     }
01430 
01431 
01432     /* HDX9Texture specific methods */
01433     /********************************/
01434     HRESULT GetSurfaceLevel(unsigned int level, LPDIRECT3DSURFACE9 *surface)
01435     {
01436         return m_id->GetSurfaceLevel(level, surface);
01437     }
01438 
01439     HRESULT GetLevelDesc(unsigned int level, D3DSURFACE_DESC *desc)
01440     {
01441         return m_id->GetLevelDesc(level, desc);
01442     }
01443 
01444     LPDIRECT3DTEXTURE9 GetTexture()
01445     {
01446         return m_id;
01447     }
01448 };
01449 
01450 
01451 
01452 /*****************************************************************************
01453 *****************************************************************************
01454                         HDX9Actions Class
01455 *****************************************************************************
01456 *****************************************************************************/
01457 class HDX9Actions : public H3DActions
01458 {
01459 private:
01460     DX9Data *m_dx9data;
01461 
01462 public:
01463     HDX9Actions(){};
01464     HDX9Actions(DX9Data *dx9data) : 
01465         H3DActions(dx9data),
01466         m_dx9data(dx9data) {};
01467     ~HDX9Actions(){};
01468 
01469     void Begin_Trace(wchar_t *string) {
01470         D3DPERF_BeginEvent(0,string);
01471     };
01472     void End_Trace() {D3DPERF_EndEvent();};
01473 
01474     H3DVertexBufferCache *CreateVertexBufferCache() {return new HDX9VertexBufferCache();}
01475     H3DIndexBufferCache *CreateIndexBufferCache() {return new HDX9IndexBufferCache();}
01476     H3DIndexedBufferObject* CreateIndexedBufferObject() {return new HDX9IndexedBufferObject();}
01477     H3DIndexedBufferObject* CreateMesh()  {return new HDX9Mesh();}
01478 
01479     void Clear(int flags, int color, float z_value, int stencil_value)
01480     {
01481         DWORD clearflags = d3dclear(flags);
01482         m_dx9data->pDevice->Clear(0, NULL, clearflags, color, z_value, stencil_value);
01483     }
01484 
01485     void SetViewport(H3DVIEWPORT const *hvp)
01486     {
01487         D3DVIEWPORT9 vp = d3dviewport(hvp);
01488         m_dx9data->pDevice->SetViewport(&vp);
01489     }
01490 
01491     /************************/
01492     /* Define/Bind Textures */
01493     /************************/
01494     void define_face_pattern (HT_Display_Context alter * dc, int face_pattern, int user_pattern = 0, int transparency_stipple = 0);
01495     bool bind_texture(const HT_Net_Rendition *nr, HT_Texture *txr, int usage, H3DTexture *id, int texture_unit);
01496 
01497 
01498     /*****************************/
01499     /* Texture Creation/Deletion */
01500     /*****************************/
01501     bool CreateTexture(unsigned int width, unsigned int height, unsigned int levels, unsigned int usage, H3DFORMAT z_format, H3DTexture **id);
01502     void SetTexture(int unit, H3DTexture *id)
01503     {
01504         if (id)
01505             m_dx9data->pDevice->SetTexture(unit, ((HDX9Texture *) id)->GetTexture());
01506         else
01507             m_dx9data->pDevice->SetTexture(unit, 0);
01508     }
01509 
01510 
01511     /****************************/
01512     /* Shader Creation/Deletion */
01513     /****************************/
01514     H3DShader *CreateShader(H3DShaderID id) 
01515     {
01516         return new HDX9Shader(id);
01517     };
01518     void DeleteShader(H3DShader *shader)
01519     {
01520         delete (HDX9Shader *) shader;
01521     };
01522 
01523     /************************/
01524     /* Device state "force" */
01525     /************************/
01526     void force_vf(H3DVertexFormat vf)
01527     {
01528         m_dx9data->h3dcache.vf = vf;
01529         m_dx9data->pDevice->SetFVF(vf2fvf(vf));
01530     }
01531 
01532     void force_scissor(bool mode)
01533     {
01534         if (m_dx9data->can_scissor) {
01535             INVALIDATE_SCISSOR_SET(m_dx9data);
01536             m_dx9data->cache.scissoring = mode;
01537             if (mode)
01538                 m_dx9data->pDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
01539             else
01540                 m_dx9data->pDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
01541         }
01542     }
01543 
01544     void force_shade_mode(H3DSHADEMODE mode)
01545     {
01546         m_dx9data->cache.shade_mode = mode;
01547         m_dx9data->pDevice->SetRenderState(D3DRS_SHADEMODE, d3dshademode(mode));
01548     }
01549 
01550     void force_culling(H3DCULL mode)
01551     {
01552         if (mode == H3DCULL_NONE)
01553             m_dx9data->culling = false;
01554         else
01555             m_dx9data->culling = true;
01556         m_dx9data->cache.cull_mode = mode;
01557         m_dx9data->pDevice->SetRenderState(D3DRS_CULLMODE, d3dcull(mode));
01558     }
01559 
01560     void force_zbuffering(bool mode)
01561     {
01562         if (!mode)
01563             m_dx9data->pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
01564         else {
01565             if (m_dx9data->cache.depth_test_reversed)
01566                 m_dx9data->pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATER);
01567             else
01568                 m_dx9data->pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
01569         }
01570         m_dx9data->cache.zbuffering = mode;
01571     }
01572 
01573     void force_depth_mask(bool mode)
01574     {
01575         m_dx9data->cache.depth_mask = mode;
01576         if (mode)
01577             m_dx9data->pDevice->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_TRUE);
01578         else
01579             m_dx9data->pDevice->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_FALSE);
01580     }
01581 
01582     void force_depth_range_set(float zmin, float zmax)
01583     {
01584         D3DVIEWPORT9 vp;
01585         vp.X                    = m_dx9data->cache.viewport.X;
01586         vp.Y                    = m_dx9data->cache.viewport.Y;
01587         vp.Width                = m_dx9data->cache.viewport.Width;
01588         vp.Height               = m_dx9data->cache.viewport.Height;
01589         vp.MinZ                 = m_dx9data->cache.z_range[0] = zmin;
01590         vp.MaxZ                 = m_dx9data->cache.z_range[1] = zmax;
01591         m_dx9data->pDevice->SetViewport(&vp);
01592     }
01593 
01594     void force_anti_alias(bool mode)
01595     {
01596         m_dx9data->cache.antialias = mode;
01597         m_dx9data->pDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, mode);
01598     }
01599 
01600     void force_color_mask(bool mode)
01601     {
01602         if (!mode) \
01603             m_dx9data->pDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0x0000000);          /*glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);*/ \
01604         else \
01605             m_dx9data->pDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_ALPHA);           /*glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);*/ \
01606         m_dx9data->cache.color_mask = mode; \
01607     }
01608 
01609     void force_transparency(bool mode)
01610     {
01611         if (mode) {
01612             m_dx9data->cache.transparency_on = true;
01613             m_dx9data->pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
01614         }
01615         else {
01616             m_dx9data->cache.transparency_on = false;
01617             m_dx9data->pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
01618         }
01619     }
01620 
01621 
01622 
01623     void set_dc_xform (HT_Net_Rendition const * nr);
01624     void set_3d_xform (HT_Net_Rendition const * nr);
01625 }; // HDX9Actions
01626 
01627 
01628 #endif // DX9DATA_ONLY
01629 
01630 #pragma warning(default : 4710)
01631 
01632 #endif // __DX9DRIVE_H_DEFINED__
01633 
01634 
Main Index
HOOPS/3dGS I.M. Interface

     << Back      Full Index      Forward >>