diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.cxx b/panda/src/dxgsg/dxGraphicsStateGuardian.cxx index ad4ae94fc1..72f9803816 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.cxx +++ b/panda/src/dxgsg/dxGraphicsStateGuardian.cxx @@ -101,44 +101,46 @@ static D3DMATRIX matIdentity; //////////////////////////////////////////////////////////////////// DXGraphicsStateGuardian:: DXGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) { - _light_enabled = (bool *)NULL; - _cur_light_enabled = (bool *)NULL; - _clip_plane_enabled = (bool *)NULL; - _cur_clip_plane_enabled = (bool *)NULL; - _pCurFvfBufPtr = NULL; - _pFvfBufBasePtr = new char[VERT_BUFFER_SIZE]; // allocate storage for vertex info. - _index_buf = new WORD[D3DMAXNUMVERTICES]; // allocate storage for vertex index info. + _light_enabled = (bool *)NULL; + _cur_light_enabled = (bool *)NULL; + _clip_plane_enabled = (bool *)NULL; + _cur_clip_plane_enabled = (bool *)NULL; + _pCurFvfBufPtr = NULL; + _pFvfBufBasePtr = new char[VERT_BUFFER_SIZE]; // allocate storage for vertex info. + _index_buf = new WORD[D3DMAXNUMVERTICES]; // allocate storage for vertex index info. - _dx_ready = false; + _dx_ready = false; - _CurShadeMode = D3DSHADE_FLAT; + _CurShadeMode = D3DSHADE_FLAT; - _pri = _zbuf = _back = NULL; - _pDD = NULL; - _d3dDevice = NULL; + _pri = _zbuf = _back = NULL; + _pDD = NULL; + _d3dDevice = NULL; - ZeroMemory(&matIdentity,sizeof(D3DMATRIX)); - matIdentity._11 = matIdentity._22 = matIdentity._33 = matIdentity._44 = 1.0f; + _cur_read_pixel_buffer=RenderBuffer::T_front; - _cNumTexPixFmts = 0; - _pTexPixFmts = NULL; - _pCurTexContext = NULL; + ZeroMemory(&matIdentity,sizeof(D3DMATRIX)); + matIdentity._11 = matIdentity._22 = matIdentity._33 = matIdentity._44 = 1.0f; - // Create a default RenderTraverser. - if (dx_cull_traversal) { - _render_traverser = new CullTraverser(this, RenderRelation::get_class_type()); - } else { - _render_traverser = new DirectRenderTraverser(this, RenderRelation::get_class_type()); - } + _cNumTexPixFmts = 0; + _pTexPixFmts = NULL; + _pCurTexContext = NULL; - //Color and alpha transform variables - _color_transform_enabled = false; - _alpha_transform_enabled = false; - _current_color_mat = LMatrix4f::ident_mat(); - _current_alpha_offset = 0; - _current_alpha_scale = 1; + // Create a default RenderTraverser. + if (dx_cull_traversal) { + _render_traverser = new CullTraverser(this, RenderRelation::get_class_type()); + } else { + _render_traverser = new DirectRenderTraverser(this, RenderRelation::get_class_type()); + } - reset(); + //Color and alpha transform variables + _color_transform_enabled = false; + _alpha_transform_enabled = false; + _current_color_mat = LMatrix4f::ident_mat(); + _current_alpha_offset = 0; + _current_alpha_scale = 1; + + reset(); } //////////////////////////////////////////////////////////////////// @@ -148,13 +150,13 @@ DXGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) { //////////////////////////////////////////////////////////////////// DXGraphicsStateGuardian:: ~DXGraphicsStateGuardian() { - if (_d3dDevice != NULL) - _d3dDevice->SetTexture(0, NULL); // this frees reference to the old texture - _pCurTexContext = NULL; + if (_d3dDevice != NULL) + _d3dDevice->SetTexture(0, NULL); // this frees reference to the old texture + _pCurTexContext = NULL; - free_pointers(); - delete [] _pFvfBufBasePtr; - delete [] _index_buf; + free_pointers(); + delete [] _pFvfBufBasePtr; + delete [] _index_buf; } //////////////////////////////////////////////////////////////////// @@ -165,79 +167,78 @@ DXGraphicsStateGuardian:: //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: reset() { - free_pointers(); - activate(); - GraphicsStateGuardian::reset(); - _buffer_mask = 0; + free_pointers(); + activate(); + GraphicsStateGuardian::reset(); + _buffer_mask = 0; - // All implementations have the following buffers. (?) - _buffer_mask = (RenderBuffer::T_color | - RenderBuffer::T_depth | - RenderBuffer::T_stencil | - RenderBuffer::T_accum ); + // All implementations have the following buffers. (?) + _buffer_mask = (RenderBuffer::T_color | + RenderBuffer::T_depth | + RenderBuffer::T_stencil | + RenderBuffer::T_accum ); - // WBD for now, let's assume a back buffer too); - _buffer_mask |= RenderBuffer::T_back; + // WBD for now, let's assume a back buffer too); + _buffer_mask |= RenderBuffer::T_back; - _current_projection_mat = LMatrix4f::ident_mat(); - _projection_mat_stack_count = 0; + _current_projection_mat = LMatrix4f::ident_mat(); + _projection_mat_stack_count = 0; - _issued_color_enabled = false; + _issued_color_enabled = false; - _buffer_mask &= ~RenderBuffer::T_right; // test for these later + _buffer_mask &= ~RenderBuffer::T_right; // test for these later - // Set up our clear values to invalid values, so the glClear* calls - // will be made initially. - _clear_color_red = -1.0; - _clear_color_green = -1.0; - _clear_color_blue = -1.0; - _clear_color_alpha = -1.0; - _clear_depth = -1.0; - _clear_stencil = -1; - _clear_accum_red = -1.0; - _clear_accum_green = -1.0; - _clear_accum_blue = -1.0; - _clear_accum_alpha = -1.0; - _line_width = 1.0; - _point_size = 1.0; - _depth_mask = false; - _fog_mode = D3DFOG_EXP; - _alpha_func = D3DCMP_ALWAYS; - _alpha_func_ref = 0; + // Set up our clear values to invalid values, so the glClear* calls + // will be made initially. + _clear_color_red = -1.0; + _clear_color_green = -1.0; + _clear_color_blue = -1.0; + _clear_color_alpha = -1.0; + _clear_depth = -1.0; + _clear_stencil = -1; + _clear_accum_red = -1.0; + _clear_accum_green = -1.0; + _clear_accum_blue = -1.0; + _clear_accum_alpha = -1.0; + _line_width = 1.0; + _point_size = 1.0; + _depth_mask = false; + _fog_mode = D3DFOG_EXP; + _alpha_func = D3DCMP_ALWAYS; + _alpha_func_ref = 0; // _polygon_mode = GL_FILL; - _pack_alignment = 4; - _unpack_alignment = 4; +// _pack_alignment = 4; +// _unpack_alignment = 4; - // Set up all the enabled/disabled flags to GL's known initial - // values: everything off. - _multisample_enabled = false; - _line_smooth_enabled = false; - _point_smooth_enabled = false; - _color_material_enabled = false; + // Set up all the enabled/disabled flags to GL's known initial + // values: everything off. + _multisample_enabled = false; + _line_smooth_enabled = false; + _point_smooth_enabled = false; + _color_material_enabled = false; // _scissor_enabled = false; - _lighting_enabled = false; - _normals_enabled = false; - _texturing_enabled = false; - _multisample_alpha_one_enabled = false; - _multisample_alpha_mask_enabled = false; - _blend_enabled = false; - _depth_test_enabled = false; - _fog_enabled = false; - _alpha_test_enabled = false; - _decal_level = 0; + _lighting_enabled = false; + _normals_enabled = false; + _texturing_enabled = false; + _multisample_alpha_one_enabled = false; + _multisample_alpha_mask_enabled = false; + _blend_enabled = false; + _depth_test_enabled = false; + _fog_enabled = false; + _alpha_test_enabled = false; + _decal_level = 0; - _dx_ready = false; + _dx_ready = false; } -HRESULT CALLBACK EnumTexFmtsCallback( LPDDPIXELFORMAT pddpf, VOID* param ) -{ - // wont build if its a member fn, so had to do this stuff - DXGraphicsStateGuardian *mystate = (DXGraphicsStateGuardian *) param; - assert(mystate->_cNumTexPixFmts < MAX_DX_TEXPIXFMTS); - memcpy( &(mystate->_pTexPixFmts[mystate->_cNumTexPixFmts]), pddpf, sizeof(DDPIXELFORMAT) ); - mystate->_cNumTexPixFmts++; - return DDENUMRET_OK; +HRESULT CALLBACK EnumTexFmtsCallback( LPDDPIXELFORMAT pddpf, VOID* param ) { + // wont build if its a member fn, so had to do this stuff + DXGraphicsStateGuardian *mystate = (DXGraphicsStateGuardian *) param; + assert(mystate->_cNumTexPixFmts < MAX_DX_TEXPIXFMTS); + memcpy( &(mystate->_pTexPixFmts[mystate->_cNumTexPixFmts]), pddpf, sizeof(DDPIXELFORMAT) ); + mystate->_cNumTexPixFmts++; + return DDENUMRET_OK; } //////////////////////////////////////////////////////////////////// @@ -248,206 +249,206 @@ HRESULT CALLBACK EnumTexFmtsCallback( LPDDPIXELFORMAT pddpf, VOID* param ) //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: init_dx( LPDIRECTDRAW7 context, - LPDIRECTDRAWSURFACE7 pri, - LPDIRECTDRAWSURFACE7 back, - LPDIRECTDRAWSURFACE7 zbuf, - LPDIRECT3D7 pD3D, - LPDIRECT3DDEVICE7 pDevice, - RECT viewrect) -{ - _pDD = context; - _pri = pri; - _back = back; - _zbuf = zbuf; - _d3d = pD3D; - _d3dDevice = pDevice; - _view_rect = viewrect; - HRESULT hr; + LPDIRECTDRAWSURFACE7 pri, + LPDIRECTDRAWSURFACE7 back, + LPDIRECTDRAWSURFACE7 zbuf, + LPDIRECT3D7 pD3D, + LPDIRECT3DDEVICE7 pDevice, + RECT viewrect) { + _pDD = context; + _pri = pri; + _back = back; + _zbuf = zbuf; + _d3d = pD3D; + _d3dDevice = pDevice; + _view_rect = viewrect; + HRESULT hr; - _pTexPixFmts = new DDPIXELFORMAT[MAX_DX_TEXPIXFMTS]; + _pTexPixFmts = new DDPIXELFORMAT[MAX_DX_TEXPIXFMTS]; - assert(_pTexPixFmts!=NULL); + assert(_pTexPixFmts!=NULL); - if (pDevice->EnumTextureFormats(EnumTexFmtsCallback, this) != S_OK) { - dxgsg_cat.error() << "EnumTextureFormats failed!!\n"; - } + if (pDevice->EnumTextureFormats(EnumTexFmtsCallback, this) != S_OK) { + dxgsg_cat.error() << "EnumTextureFormats failed!!\n"; + } - if(FAILED(hr = pDevice->GetCaps(&_D3DDevDesc))) { - dxgsg_cat.fatal() << "GetCaps failed on D3D Device\n"; - exit(1); - } + if (FAILED(hr = pDevice->GetCaps(&_D3DDevDesc))) { + dxgsg_cat.fatal() << "GetCaps failed on D3D Device\n"; + exit(1); + } - DX_DECLARE_CLEAN(DDCAPS,ddCaps); - if(FAILED(hr = _pDD->GetCaps(&ddCaps,NULL))) { - dxgsg_cat.fatal() << "GetCaps failed on DDraw\n"; - exit(1); - } + DX_DECLARE_CLEAN(DDCAPS,ddCaps); + if (FAILED(hr = _pDD->GetCaps(&ddCaps,NULL))) { + dxgsg_cat.fatal() << "GetCaps failed on DDraw\n"; + exit(1); + } - _bIsTNLDevice = (IsEqualGUID(_D3DDevDesc.deviceGUID,IID_IDirect3DTnLHalDevice)!=0); + _bIsTNLDevice = (IsEqualGUID(_D3DDevDesc.deviceGUID,IID_IDirect3DTnLHalDevice)!=0); - if((dx_decal_type==GDT_offset) && !(_D3DDevDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZBIAS)) { + if ((dx_decal_type==GDT_offset) && !(_D3DDevDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZBIAS)) { #ifdef _DEBUG - // dx7 doesnt support PLANEMASK renderstate - #if(DIRECT3D_VERSION < 0x700) - dxgsg_cat.error() << "dx-decal-type 'offset' not supported by hardware, switching to decal masking\n"; - #else - dxgsg_cat.error() << "dx-decal-type 'offset' not supported by hardware, switching to decal double-draw blend-based masking\n"; - #endif + + // dx7 doesnt support PLANEMASK renderstate +#if(DIRECT3D_VERSION < 0x700) + dxgsg_cat.error() << "dx-decal-type 'offset' not supported by hardware, switching to decal masking\n"; +#else + dxgsg_cat.error() << "dx-decal-type 'offset' not supported by hardware, switching to decal double-draw blend-based masking\n"; #endif - #if(DIRECT3D_VERSION < 0x700) - dx_decal_type = GDT_mask; - #else - dx_decal_type = GDT_blend; - #endif - } +#endif +#if(DIRECT3D_VERSION < 0x700) + dx_decal_type = GDT_mask; +#else + dx_decal_type = GDT_blend; +#endif + } #ifdef DISABLE_POLYGON_OFFSET_DECALING - #ifdef _DEBUG - dxgsg_cat.spam() << "polygon-offset decaling disabled in dxgsg, switching to double-draw decaling\n"; - #endif - - #if(DIRECT3D_VERSION < 0x700) - dx_decal_type = GDT_mask; - #else - dx_decal_type = GDT_blend; - #endif -#endif - - if((dx_decal_type==GDT_mask) && !(_D3DDevDesc.dpcTriCaps.dwMiscCaps & D3DPMISCCAPS_MASKPLANES)) { #ifdef _DEBUG - dxgsg_cat.error() << "No hardware support for colorwrite disabling, switching to dx-decal-type 'mask' to 'blend'\n"; + dxgsg_cat.spam() << "polygon-offset decaling disabled in dxgsg, switching to double-draw decaling\n"; #endif - dx_decal_type = GDT_blend; - } - if(((dx_decal_type==GDT_blend)||(dx_decal_type==GDT_mask)) && !(_D3DDevDesc.dpcTriCaps.dwMiscCaps & D3DPMISCCAPS_MASKZ)) { - dxgsg_cat.error() << "dx-decal-type mask impossible to implement, no hardware support for Z-masking, decals will not appear correctly\n"; - } +#if(DIRECT3D_VERSION < 0x700) + dx_decal_type = GDT_mask; +#else + dx_decal_type = GDT_blend; +#endif +#endif + + if ((dx_decal_type==GDT_mask) && !(_D3DDevDesc.dpcTriCaps.dwMiscCaps & D3DPMISCCAPS_MASKPLANES)) { +#ifdef _DEBUG + dxgsg_cat.error() << "No hardware support for colorwrite disabling, switching to dx-decal-type 'mask' to 'blend'\n"; +#endif + dx_decal_type = GDT_blend; + } + + if (((dx_decal_type==GDT_blend)||(dx_decal_type==GDT_mask)) && !(_D3DDevDesc.dpcTriCaps.dwMiscCaps & D3DPMISCCAPS_MASKZ)) { + dxgsg_cat.error() << "dx-decal-type mask impossible to implement, no hardware support for Z-masking, decals will not appear correctly\n"; + } //#define REQUIRED_BLENDCAPS (D3DPBLENDCAPS_ZERO|D3DPBLENDCAPS_ONE|D3DPBLENDCAPS_SRCCOLOR|D3DPBLENDCAPS_INVSRCCOLOR| \ // D3DPBLENDCAPS_SRCALPHA|D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA|D3DPBLENDCAPS_INVDESTALPHA|D3DPBLENDCAPS_DESTCOLOR|D3DPBLENDCAPS_INVDESTCOLOR) // voodoo3 doesnt support commented out ones, & we dont need them now - + #define REQUIRED_BLENDCAPS (D3DPBLENDCAPS_ZERO|D3DPBLENDCAPS_ONE| /*D3DPBLENDCAPS_SRCCOLOR|D3DPBLENDCAPS_INVSRCCOLOR| */ \ D3DPBLENDCAPS_SRCALPHA|D3DPBLENDCAPS_INVSRCALPHA /* | D3DPBLENDCAPS_DESTALPHA|D3DPBLENDCAPS_INVDESTALPHA|D3DPBLENDCAPS_DESTCOLOR|D3DPBLENDCAPS_INVDESTCOLOR*/) - if(((_D3DDevDesc.dpcTriCaps.dwSrcBlendCaps & REQUIRED_BLENDCAPS)!=REQUIRED_BLENDCAPS) || - ((_D3DDevDesc.dpcTriCaps.dwDestBlendCaps & REQUIRED_BLENDCAPS)!=REQUIRED_BLENDCAPS)) { - dxgsg_cat.error() << "device is missing alpha blending capabilities, blending may not work correctly: SrcBlendCaps: 0x"<< (void*) _D3DDevDesc.dpcTriCaps.dwSrcBlendCaps << " DestBlendCaps: "<< (void*) _D3DDevDesc.dpcTriCaps.dwDestBlendCaps << endl; - } + if (((_D3DDevDesc.dpcTriCaps.dwSrcBlendCaps & REQUIRED_BLENDCAPS)!=REQUIRED_BLENDCAPS) || + ((_D3DDevDesc.dpcTriCaps.dwDestBlendCaps & REQUIRED_BLENDCAPS)!=REQUIRED_BLENDCAPS)) { + dxgsg_cat.error() << "device is missing alpha blending capabilities, blending may not work correctly: SrcBlendCaps: 0x"<< (void*) _D3DDevDesc.dpcTriCaps.dwSrcBlendCaps << " DestBlendCaps: "<< (void*) _D3DDevDesc.dpcTriCaps.dwDestBlendCaps << endl; + } - if(!(_D3DDevDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_TRANSPARENCY)) { - dxgsg_cat.error() << "device is missing texture transparency capability, transparency may not work correctly! TextureCaps: 0x"<< (void*) _D3DDevDesc.dpcTriCaps.dwTextureCaps << endl; - } + if (!(_D3DDevDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_TRANSPARENCY)) { + dxgsg_cat.error() << "device is missing texture transparency capability, transparency may not work correctly! TextureCaps: 0x"<< (void*) _D3DDevDesc.dpcTriCaps.dwTextureCaps << endl; + } - // just require trilinear. if it can do that, it can probably do all the lesser point-sampling variations too + // just require trilinear. if it can do that, it can probably do all the lesser point-sampling variations too #define REQUIRED_TEXFILTERCAPS (D3DPTFILTERCAPS_MAGFLINEAR | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_LINEAR) - if((_D3DDevDesc.dpcTriCaps.dwTextureFilterCaps & REQUIRED_TEXFILTERCAPS)!=REQUIRED_TEXFILTERCAPS) { - dxgsg_cat.error() << "device is missing texture bilinear filtering capability, textures may appear blocky! TextureFilterCaps: 0x"<< (void*) _D3DDevDesc.dpcTriCaps.dwTextureFilterCaps << endl; - } + if ((_D3DDevDesc.dpcTriCaps.dwTextureFilterCaps & REQUIRED_TEXFILTERCAPS)!=REQUIRED_TEXFILTERCAPS) { + dxgsg_cat.error() << "device is missing texture bilinear filtering capability, textures may appear blocky! TextureFilterCaps: 0x"<< (void*) _D3DDevDesc.dpcTriCaps.dwTextureFilterCaps << endl; + } #define REQUIRED_MIPMAP_TEXFILTERCAPS (D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR) - if(!(ddCaps.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) { - dxgsg_cat.debug() << "device does not have mipmap texturing filtering capability! TextureFilterCaps: 0x"<< (void*) _D3DDevDesc.dpcTriCaps.dwTextureFilterCaps << endl; - dx_ignore_mipmaps = TRUE; - } else if((_D3DDevDesc.dpcTriCaps.dwTextureFilterCaps & REQUIRED_MIPMAP_TEXFILTERCAPS)!=REQUIRED_MIPMAP_TEXFILTERCAPS) { - dxgsg_cat.debug() << "device is missing tri-linear mipmap filtering capability, texture mipmaps may not supported! TextureFilterCaps: 0x"<< (void*) _D3DDevDesc.dpcTriCaps.dwTextureFilterCaps << endl; - } + if (!(ddCaps.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) { + dxgsg_cat.debug() << "device does not have mipmap texturing filtering capability! TextureFilterCaps: 0x"<< (void*) _D3DDevDesc.dpcTriCaps.dwTextureFilterCaps << endl; + dx_ignore_mipmaps = TRUE; + } else if ((_D3DDevDesc.dpcTriCaps.dwTextureFilterCaps & REQUIRED_MIPMAP_TEXFILTERCAPS)!=REQUIRED_MIPMAP_TEXFILTERCAPS) { + dxgsg_cat.debug() << "device is missing tri-linear mipmap filtering capability, texture mipmaps may not supported! TextureFilterCaps: 0x"<< (void*) _D3DDevDesc.dpcTriCaps.dwTextureFilterCaps << endl; + } #define REQUIRED_TEXBLENDCAPS (D3DTEXOPCAPS_MODULATE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SELECTARG2) - if((_D3DDevDesc.dwTextureOpCaps & REQUIRED_TEXBLENDCAPS)!=REQUIRED_TEXBLENDCAPS) { - dxgsg_cat.error() << "device is missing some required texture blending capabilities, texture blending may not work properly! TextureOpCaps: 0x"<< (void*) _D3DDevDesc.dwTextureOpCaps << endl; - } + if ((_D3DDevDesc.dwTextureOpCaps & REQUIRED_TEXBLENDCAPS)!=REQUIRED_TEXBLENDCAPS) { + dxgsg_cat.error() << "device is missing some required texture blending capabilities, texture blending may not work properly! TextureOpCaps: 0x"<< (void*) _D3DDevDesc.dwTextureOpCaps << endl; + } - SetRect(&clip_rect, 0,0,0,0); // no clip rect set + SetRect(&clip_rect, 0,0,0,0); // no clip rect set - _d3dDevice->SetRenderState(D3DRENDERSTATE_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1); + _d3dDevice->SetRenderState(D3DRENDERSTATE_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1); - // Lighting, let's turn it off by default - _lighting_enabled = true; - enable_lighting(false); + // Lighting, let's turn it off by default + _lighting_enabled = true; + enable_lighting(false); - // Dither, let's turn it off - _dither_enabled = true; - enable_dither(false); + // Dither, let's turn it off + _dither_enabled = true; + enable_dither(false); - // Stencil test is off by default - _stencil_test_enabled = false; + // Stencil test is off by default + _stencil_test_enabled = false; // _stencil_func = D3DCMP_NOTEQUAL; // _stencil_op = D3DSTENCILOP_REPLACE; - // Antialiasing. - enable_line_smooth(false); - enable_multisample(true); + // Antialiasing. + enable_line_smooth(false); + enable_multisample(true); - _max_lights = 16; // assume for now. This is totally arbitrary - _available_light_ids = PTA(Light*)(_max_lights); - _light_enabled = new bool[_max_lights]; - _cur_light_enabled = new bool[_max_lights]; - int i; - for (i = 0; i < _max_lights; i++ ) { - _available_light_ids[i] = NULL; - _light_enabled[i] = false; - } + _max_lights = 16; // assume for now. This is totally arbitrary + _available_light_ids = PTA(Light*)(_max_lights); + _light_enabled = new bool[_max_lights]; + _cur_light_enabled = new bool[_max_lights]; + int i; + for (i = 0; i < _max_lights; i++) { + _available_light_ids[i] = NULL; + _light_enabled[i] = false; + } - // Set up the clip plane id map - _max_clip_planes = D3DMAXUSERCLIPPLANES; - _available_clip_plane_ids = PTA(PlaneNode*)(_max_clip_planes); - _clip_plane_enabled = new bool[_max_clip_planes]; - _cur_clip_plane_enabled = new bool[_max_clip_planes]; - for (i = 0; i < _max_clip_planes; i++) { - _available_clip_plane_ids[i] = NULL; - _clip_plane_enabled[i] = false; - } + // Set up the clip plane id map + _max_clip_planes = D3DMAXUSERCLIPPLANES; + _available_clip_plane_ids = PTA(PlaneNode*)(_max_clip_planes); + _clip_plane_enabled = new bool[_max_clip_planes]; + _cur_clip_plane_enabled = new bool[_max_clip_planes]; + for (i = 0; i < _max_clip_planes; i++) { + _available_clip_plane_ids[i] = NULL; + _clip_plane_enabled[i] = false; + } - // initial clip rect - SetRect(&clip_rect, 0,0,0,0); // no clip rect set + // initial clip rect + SetRect(&clip_rect, 0,0,0,0); // no clip rect set - // Make sure the GL state matches all of our initial attribute - // states. - PT(DepthTestAttribute) dta = new DepthTestAttribute; - PT(DepthWriteAttribute) dwa = new DepthWriteAttribute; - PT(CullFaceAttribute) cfa = new CullFaceAttribute; - PT(LightAttribute) la = new LightAttribute; - PT(TextureAttribute) ta = new TextureAttribute; + // Make sure the GL state matches all of our initial attribute + // states. + PT(DepthTestAttribute) dta = new DepthTestAttribute; + PT(DepthWriteAttribute) dwa = new DepthWriteAttribute; + PT(CullFaceAttribute) cfa = new CullFaceAttribute; + PT(LightAttribute) la = new LightAttribute; + PT(TextureAttribute) ta = new TextureAttribute; - dta->issue(this); - dwa->issue(this); - cfa->issue(this); - la->issue(this); + dta->issue(this); + dwa->issue(this); + cfa->issue(this); + la->issue(this); - // must do SetTSS here because redundant states are filtered out by our code based on current values above, so - // initial conditions must be correct + // must do SetTSS here because redundant states are filtered out by our code based on current values above, so + // initial conditions must be correct - _CurTexBlendMode = TextureApplyProperty::M_modulate; - SetTextureBlendMode(_CurTexBlendMode,FALSE); - _d3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE); // disables texturing + _CurTexBlendMode = TextureApplyProperty::M_modulate; + SetTextureBlendMode(_CurTexBlendMode,FALSE); + _d3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE); // disables texturing - // Init more Texture State - _CurTexMagFilter=_CurTexMinFilter=Texture::FT_nearest; - _CurTexWrapModeU=_CurTexWrapModeV=Texture::WM_clamp; - _CurTexAnisoDegree=1; + // Init more Texture State + _CurTexMagFilter=_CurTexMinFilter=Texture::FT_nearest; + _CurTexWrapModeU=_CurTexWrapModeV=Texture::WM_clamp; + _CurTexAnisoDegree=1; - // this code must match apply_texture() code for states above - // so DX TSS renderstate matches dxgsg state + // this code must match apply_texture() code for states above + // so DX TSS renderstate matches dxgsg state - _d3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_POINT); - _d3dDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFP_POINT); - _d3dDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_NONE); - _d3dDevice->SetTextureStageState(0, D3DTSS_MAXANISOTROPY,_CurTexAnisoDegree); - _d3dDevice->SetTextureStageState(0,D3DTSS_ADDRESSU,get_texture_wrap_mode(_CurTexWrapModeU)); - _d3dDevice->SetTextureStageState(0,D3DTSS_ADDRESSV,get_texture_wrap_mode(_CurTexWrapModeV)); + _d3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_POINT); + _d3dDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFP_POINT); + _d3dDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_NONE); + _d3dDevice->SetTextureStageState(0, D3DTSS_MAXANISOTROPY,_CurTexAnisoDegree); + _d3dDevice->SetTextureStageState(0,D3DTSS_ADDRESSU,get_texture_wrap_mode(_CurTexWrapModeU)); + _d3dDevice->SetTextureStageState(0,D3DTSS_ADDRESSV,get_texture_wrap_mode(_CurTexWrapModeV)); - ta->issue(this); // no curtextcontext, this does nothing. dx should already be properly inited above anyway + ta->issue(this); // no curtextcontext, this does nothing. dx should already be properly inited above anyway #ifdef _DEBUG - if((_D3DDevDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_MIPMAPLODBIAS) && - (dx_global_miplevel_bias!=0.0)) { - _d3dDevice->SetTextureStageState(0, D3DTSS_MIPMAPLODBIAS, *((LPDWORD) (&dx_global_miplevel_bias)) ); - } + if ((_D3DDevDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_MIPMAPLODBIAS) && + (dx_global_miplevel_bias!=0.0)) { + _d3dDevice->SetTextureStageState(0, D3DTSS_MIPMAPLODBIAS, *((LPDWORD) (&dx_global_miplevel_bias)) ); + } #endif - _d3dDevice->SetRenderState(D3DRENDERSTATE_SHADEMODE, _CurShadeMode); + _d3dDevice->SetRenderState(D3DRENDERSTATE_SHADEMODE, _CurShadeMode); } //////////////////////////////////////////////////////////////////// @@ -459,34 +460,34 @@ init_dx( LPDIRECTDRAW7 context, void DXGraphicsStateGuardian:: clear(const RenderBuffer &buffer) { - activate(); + activate(); - nassertv(buffer._gsg == this); - int buffer_type = buffer._buffer_type; + nassertv(buffer._gsg == this); + int buffer_type = buffer._buffer_type; - int flags = 0; + int flags = 0; - if (buffer_type & RenderBuffer::T_depth) - flags |= D3DCLEAR_ZBUFFER; - if (buffer_type & RenderBuffer::T_back) //set appropriate flags - flags |= D3DCLEAR_TARGET; - if (buffer_type & RenderBuffer::T_stencil) - flags |= D3DCLEAR_STENCIL; + if (buffer_type & RenderBuffer::T_depth) + flags |= D3DCLEAR_ZBUFFER; + if (buffer_type & RenderBuffer::T_back) //set appropriate flags + flags |= D3DCLEAR_TARGET; + if (buffer_type & RenderBuffer::T_stencil) + flags |= D3DCLEAR_STENCIL; - D3DCOLOR clear_colr = D3DRGBA(_color_clear_value[0],_color_clear_value[1], - _color_clear_value[2], /*1.0*/_color_clear_value[3]); + D3DCOLOR clear_colr = D3DRGBA(_color_clear_value[0],_color_clear_value[1], + _color_clear_value[2], /*1.0*/_color_clear_value[3]); - HRESULT hr = _d3dDevice->Clear(0, NULL, flags, clear_colr, - (D3DVALUE) _depth_clear_value, (DWORD)_stencil_clear_value); - if (hr != DD_OK) - dxgsg_cat.error() - << "dxGSG::clear_buffer failed: Clear returned " << ConvD3DErrorToString(hr) << endl; - /* The following line will cause the background to always clear to a medium red - _color_clear_value[0] = .5; - /* The following lines will cause the background color to cycle from black to red. - _color_clear_value[0] += .001; - if (_color_clear_value[0] > 1.0) _color_clear_value[0] = 0.0; - */ + HRESULT hr = _d3dDevice->Clear(0, NULL, flags, clear_colr, + (D3DVALUE) _depth_clear_value, (DWORD)_stencil_clear_value); + if (hr != DD_OK) + dxgsg_cat.error() + << "dxGSG::clear_buffer failed: Clear returned " << ConvD3DErrorToString(hr) << endl; + /* The following line will cause the background to always clear to a medium red + _color_clear_value[0] = .5; + /* The following lines will cause the background color to cycle from black to red. + _color_clear_value[0] += .001; + if (_color_clear_value[0] > 1.0) _color_clear_value[0] = 0.0; + */ } //////////////////////////////////////////////////////////////////// @@ -497,10 +498,10 @@ clear(const RenderBuffer &buffer) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: clear(const RenderBuffer &buffer, const DisplayRegion *region) { - DisplayRegionStack old_dr = push_display_region(region); - prepare_display_region(); - clear(buffer); - pop_display_region(old_dr); + DisplayRegionStack old_dr = push_display_region(region); + prepare_display_region(); + clear(buffer); + pop_display_region(old_dr); } //////////////////////////////////////////////////////////////////// @@ -509,21 +510,19 @@ clear(const RenderBuffer &buffer, const DisplayRegion *region) { // Description: //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian:: -enable_light(int light, bool val) -{ - if ( _light_enabled[light] != val ) - { - _light_enabled[light] = val; - HRESULT res = _d3dDevice->LightEnable( light, val ); +enable_light(int light, bool val) { + if (_light_enabled[light] != val) { + _light_enabled[light] = val; + HRESULT res = _d3dDevice->LightEnable( light, val ); #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "LightEnable(" << light << "=" << val << ")" << endl; + dxgsg_cat.debug() + << "LightEnable(" << light << "=" << val << ")" << endl; #endif - return (res == DD_OK); - } - return TRUE; + return(res == DD_OK); + } + return TRUE; } @@ -536,35 +535,35 @@ enable_light(int light, bool val) //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: prepare_display_region() { - if (_current_display_region == (DisplayRegion*)0L) { - dxgsg_cat.error() - << "Invalid NULL display region in prepare_display_region()\n"; + if (_current_display_region == (DisplayRegion*)0L) { + dxgsg_cat.error() + << "Invalid NULL display region in prepare_display_region()\n"; - } else if (_current_display_region != _actual_display_region) { - _actual_display_region = _current_display_region; + } else if (_current_display_region != _actual_display_region) { + _actual_display_region = _current_display_region; /* - int l, b, w, h; - _actual_display_region->get_region_pixels(l, b, w, h); - GLint x = GLint(l); - GLint y = GLint(b); - GLsizei width = GLsizei(w); - GLsizei height = GLsizei(h); + int l, b, w, h; + _actual_display_region->get_region_pixels(l, b, w, h); + GLint x = GLint(l); + GLint y = GLint(b); + GLsizei width = GLsizei(w); + GLsizei height = GLsizei(h); #ifdef WBD_GL_MODE - call_glScissor( x, y, width, height ); - call_glViewport( x, y, width, height ); + call_glScissor( x, y, width, height ); + call_glViewport( x, y, width, height ); #else - if ( _scissor_x != x || _scissor_y != y || - _scissor_width != width || _scissor_height != height ) - { - _scissor_x = x; _scissor_y = y; - _scissor_width = width; _scissor_height = height; - RECT cliprect; - SetRect(&cliprect, x, y, x+width, y+height ); - set_clipper(cliprect); - } + if ( _scissor_x != x || _scissor_y != y || + _scissor_width != width || _scissor_height != height ) + { + _scissor_x = x; _scissor_y = y; + _scissor_width = width; _scissor_height = height; + RECT cliprect; + SetRect(&cliprect, x, y, x+width, y+height ); + set_clipper(cliprect); + } #endif //WBD_GL_MODE */ - } + } } @@ -575,45 +574,45 @@ prepare_display_region() { // Description: Useless in DX at the present time //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian::set_clipper(RECT cliprect) { - LPDIRECTDRAWCLIPPER Clipper; - HRESULT result; - - // For windowed mode, the clip region is associated with the window, - // and DirectX does not allow you to create clip regions. - if (dx_full_screen) return; +#if 0 + LPDIRECTDRAWCLIPPER Clipper; + HRESULT result; - /* The cliprect we receive is normalized so that (0,0) means the upper left of - the client portion of the window. - At least, I think that's true, and the following code assumes that. - So we must adjust the clip region by offsetting it to the origin of the - view rectangle. - */ - clip_rect = cliprect; // store the normalized clip rect - cliprect.left += _view_rect.left; - cliprect.right += _view_rect.left; - cliprect.top += _view_rect.top; - cliprect.bottom += _view_rect.top; - RGNDATA *rgn_data = (RGNDATA *)malloc(sizeof(RGNDATAHEADER) + sizeof(RECT)); - HRGN hrgn = CreateRectRgn(cliprect.left, cliprect.top, cliprect.right, cliprect.bottom); - GetRegionData(hrgn, sizeof(RGNDATAHEADER) + sizeof(RECT), rgn_data); + // For windowed mode, the clip region is associated with the window, + // and DirectX does not allow you to create clip regions. + if (dx_full_screen) return; - if (_pri->GetClipper(&Clipper) != DD_OK) - { - result = _pDD->CreateClipper(0, &Clipper, NULL); - result = Clipper->SetClipList(rgn_data, 0); - result = _pri->SetClipper(Clipper); - } - else { - result = Clipper->SetClipList(rgn_data, 0 ); - if (result == DDERR_CLIPPERISUSINGHWND) - { - result = _pri->SetClipper(NULL); - result = _pDD->CreateClipper(0, &Clipper, NULL); - result = Clipper->SetClipList(rgn_data, 0 ) ; - result = _pri->SetClipper(Clipper); - } - } + /* The cliprect we receive is normalized so that (0,0) means the upper left of + the client portion of the window. + At least, I think that's true, and the following code assumes that. + So we must adjust the clip region by offsetting it to the origin of the + view rectangle. + */ + clip_rect = cliprect; // store the normalized clip rect + cliprect.left += _view_rect.left; + cliprect.right += _view_rect.left; + cliprect.top += _view_rect.top; + cliprect.bottom += _view_rect.top; + RGNDATA *rgn_data = (RGNDATA *)malloc(sizeof(RGNDATAHEADER) + sizeof(RECT)); + HRGN hrgn = CreateRectRgn(cliprect.left, cliprect.top, cliprect.right, cliprect.bottom); + GetRegionData(hrgn, sizeof(RGNDATAHEADER) + sizeof(RECT), rgn_data); + if (_pri->GetClipper(&Clipper) != DD_OK) { + result = _pDD->CreateClipper(0, &Clipper, NULL); + result = Clipper->SetClipList(rgn_data, 0); + result = _pri->SetClipper(Clipper); + } else { + result = Clipper->SetClipList(rgn_data, 0 ); + if (result == DDERR_CLIPPERISUSINGHWND) { + result = _pri->SetClipper(NULL); + result = _pDD->CreateClipper(0, &Clipper, NULL); + result = Clipper->SetClipList(rgn_data, 0 ) ; + result = _pri->SetClipper(Clipper); + } + } + free(rgn_data); + DeleteObject(hrgn); +#endif } //////////////////////////////////////////////////////////////////// @@ -625,152 +624,144 @@ void DXGraphicsStateGuardian::set_clipper(RECT cliprect) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: render_frame(const AllAttributesWrapper &initial_state) { - if (!_dx_ready) return; + if (!_dx_ready) return; - _win->begin_frame(); - _d3dDevice->BeginScene(); + _win->begin_frame(); + _d3dDevice->BeginScene(); /* _d3dDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &matIdentity); */ #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "begin frame --------------------------------------------" << endl; + dxgsg_cat.debug() + << "begin frame --------------------------------------------" << endl; #endif - _decal_level = 0; + _decal_level = 0; - // First, clear the entire window. - PT(DisplayRegion) win_dr = - _win->make_scratch_display_region(_win->get_width(), _win->get_height()); - clear(get_render_buffer(RenderBuffer::T_back | RenderBuffer::T_depth), win_dr); + // First, clear the entire window. + PT(DisplayRegion) win_dr = + _win->make_scratch_display_region(_win->get_width(), _win->get_height()); + clear(get_render_buffer(RenderBuffer::T_back | RenderBuffer::T_depth), win_dr); - // Now render each of our layers in order. - int max_channel_index = _win->get_max_channel_index(); - for (int c = 0; c < max_channel_index; c++) - { - if (_win->is_channel_defined(c)) - { - GraphicsChannel *chan = _win->get_channel(c); - if (chan->is_active()) - { - int num_layers = chan->get_num_layers(); - for (int l = 0; l < num_layers; l++) - { - GraphicsLayer *layer = chan->get_layer(l); - if (layer->is_active()) - { - int num_drs = layer->get_num_drs(); - for (int d = 0; d < num_drs; d++) - { - DisplayRegion *dr = layer->get_dr(d); - Camera *cam = dr->get_camera(); - - // For each display region, render from the camera's view. - if (dr->is_active() && cam != (Camera *)NULL && - cam->is_active() && cam->get_scene() != (Node *)NULL) - { - DisplayRegionStack old_dr = push_display_region(dr); - prepare_display_region(); - render_scene(cam->get_scene(), cam, initial_state); - pop_display_region(old_dr); - } - } - } // if (layer->is_active()) - } - } // if (chan->is_active()) - } - } // for (int c = 0; c < max_channel_index; c++) + // Now render each of our layers in order. + int max_channel_index = _win->get_max_channel_index(); + for (int c = 0; c < max_channel_index; c++) { + if (_win->is_channel_defined(c)) { + GraphicsChannel *chan = _win->get_channel(c); + if (chan->is_active()) { + int num_layers = chan->get_num_layers(); + for (int l = 0; l < num_layers; l++) { + GraphicsLayer *layer = chan->get_layer(l); + if (layer->is_active()) { + int num_drs = layer->get_num_drs(); + for (int d = 0; d < num_drs; d++) { + DisplayRegion *dr = layer->get_dr(d); + Camera *cam = dr->get_camera(); - // Now we're done with the frame processing. Clean up. + // For each display region, render from the camera's view. + if (dr->is_active() && cam != (Camera *)NULL && + cam->is_active() && cam->get_scene() != (Node *)NULL) { + DisplayRegionStack old_dr = push_display_region(dr); + prepare_display_region(); + render_scene(cam->get_scene(), cam, initial_state); + pop_display_region(old_dr); + } + } + } // if (layer->is_active()) + } + } // if (chan->is_active()) + } + } // for (int c = 0; c < max_channel_index; c++) - // Let's turn off all the lights we had on, and clear the light - // cache--to force the lights to be reissued next frame, in case - // their parameters or positions have changed between frames. - - for (int i = 0; i < _max_lights; i++) - { - enable_light(i, false); - _available_light_ids[i] = NULL; - } + // Now we're done with the frame processing. Clean up. - // Also force the lighting state to unlit, so that issue_light() - // will be guaranteed to be called next frame even if we have the - // same set of light pointers we had this frame. - NodeAttributes state; - state.set_attribute(LightTransition::get_class_type(), new LightAttribute); - state.set_attribute(TextureTransition::get_class_type(), new TextureAttribute); - set_state(state, false); + // Let's turn off all the lights we had on, and clear the light + // cache--to force the lights to be reissued next frame, in case + // their parameters or positions have changed between frames. - // All this work to undo the lighting state each frame doesn't seem - // ideal--there may be a better way. Maybe if the lights were just - // more aware of whether their parameters or positions have changed - // at all? + for (int i = 0; i < _max_lights; i++) { + enable_light(i, false); + _available_light_ids[i] = NULL; + } - _d3dDevice->EndScene(); - - _win->end_frame(); - show_frame(); + // Also force the lighting state to unlit, so that issue_light() + // will be guaranteed to be called next frame even if we have the + // same set of light pointers we had this frame. + NodeAttributes state; + state.set_attribute(LightTransition::get_class_type(), new LightAttribute); + state.set_attribute(TextureTransition::get_class_type(), new TextureAttribute); + set_state(state, false); + + // All this work to undo the lighting state each frame doesn't seem + // ideal--there may be a better way. Maybe if the lights were just + // more aware of whether their parameters or positions have changed + // at all? + + _d3dDevice->EndScene(); + + _win->end_frame(); + show_frame(); #ifdef PRINT_TEXSTATS -{ - - #define TICKSPERINFO (3*1000) - static DWORD LastTickCount=0; + { - DWORD CurTickCount=GetTickCount(); - - if(CurTickCount-LastTickCount > TICKSPERINFO ) { - LastTickCount=CurTickCount; - HRESULT hr; - - D3DDEVINFO_TEXTUREMANAGER tminfo; - ZeroMemory(&tminfo,sizeof( D3DDEVINFO_TEXTUREMANAGER)); - hr = _d3dDevice->GetInfo(D3DDEVINFOID_TEXTUREMANAGER,&tminfo,sizeof(D3DDEVINFO_TEXTUREMANAGER)); - if(hr!=D3D_OK) { - if(hr==S_FALSE) - dxgsg_cat.error() << "GetInfo requires debug DX7 DLLs to be installed!!\n"; - else dxgsg_cat.error() << "GetInfo appinfo failed : result = " << ConvD3DErrorToString(hr) << endl; - } else - dxgsg_cat.spam() - << "\n bThrashing:\t" << tminfo.bThrashing - << "\n NumEvicts:\t" << tminfo.dwNumEvicts - << "\n NumVidCreates:\t" << tminfo.dwNumVidCreates - << "\n NumTexturesUsed:\t" << tminfo.dwNumTexturesUsed - << "\n NumUsedTexInVid:\t" << tminfo.dwNumUsedTexInVid - << "\n WorkingSet:\t" << tminfo.dwWorkingSet - << "\n WorkingSetBytes:\t" << tminfo.dwWorkingSetBytes - << "\n TotalManaged:\t" << tminfo.dwTotalManaged - << "\n TotalBytes:\t" << tminfo.dwTotalBytes - << "\n LastPri:\t" << tminfo.dwLastPri << endl; - - - D3DDEVINFO_TEXTURING texappinfo; - ZeroMemory(&texappinfo,sizeof( D3DDEVINFO_TEXTURING)); - hr = _d3dDevice->GetInfo(D3DDEVINFOID_TEXTURING,&texappinfo,sizeof(D3DDEVINFO_TEXTURING)); - if(hr!=D3D_OK) { - if(hr==S_FALSE) - dxgsg_cat.error() << "GetInfo requires debug DX7 DLLs to be installed!!\n"; - else dxgsg_cat.error() << "GetInfo appinfo failed : result = " << ConvD3DErrorToString(hr) << endl; - } else - dxgsg_cat.spam() - << "\n NumLoads:\t" << texappinfo.dwNumLoads - << "\n ApproxBytesLoaded:\t" << texappinfo.dwApproxBytesLoaded - << "\n NumPreLoads:\t" << texappinfo.dwNumPreLoads - << "\n NumSet:\t" << texappinfo.dwNumSet - << "\n NumCreates:\t" << texappinfo.dwNumCreates - << "\n NumDestroys:\t" << texappinfo.dwNumDestroys - << "\n NumSetPriorities:\t" << texappinfo.dwNumSetPriorities - << "\n NumSetLODs:\t" << texappinfo.dwNumSetLODs - << "\n NumLocks:\t" << texappinfo.dwNumLocks - << "\n NumGetDCs:\t" << texappinfo.dwNumGetDCs << endl; - } +#define TICKSPERINFO (3*1000) + static DWORD LastTickCount=0; -} + DWORD CurTickCount=GetTickCount(); + + if (CurTickCount-LastTickCount > TICKSPERINFO) { + LastTickCount=CurTickCount; + HRESULT hr; + + D3DDEVINFO_TEXTUREMANAGER tminfo; + ZeroMemory(&tminfo,sizeof( D3DDEVINFO_TEXTUREMANAGER)); + hr = _d3dDevice->GetInfo(D3DDEVINFOID_TEXTUREMANAGER,&tminfo,sizeof(D3DDEVINFO_TEXTUREMANAGER)); + if (hr!=D3D_OK) { + if (hr==S_FALSE) + dxgsg_cat.error() << "GetInfo requires debug DX7 DLLs to be installed!!\n"; + else dxgsg_cat.error() << "GetInfo appinfo failed : result = " << ConvD3DErrorToString(hr) << endl; + } else + dxgsg_cat.spam() + << "\n bThrashing:\t" << tminfo.bThrashing + << "\n NumEvicts:\t" << tminfo.dwNumEvicts + << "\n NumVidCreates:\t" << tminfo.dwNumVidCreates + << "\n NumTexturesUsed:\t" << tminfo.dwNumTexturesUsed + << "\n NumUsedTexInVid:\t" << tminfo.dwNumUsedTexInVid + << "\n WorkingSet:\t" << tminfo.dwWorkingSet + << "\n WorkingSetBytes:\t" << tminfo.dwWorkingSetBytes + << "\n TotalManaged:\t" << tminfo.dwTotalManaged + << "\n TotalBytes:\t" << tminfo.dwTotalBytes + << "\n LastPri:\t" << tminfo.dwLastPri << endl; + + + D3DDEVINFO_TEXTURING texappinfo; + ZeroMemory(&texappinfo,sizeof( D3DDEVINFO_TEXTURING)); + hr = _d3dDevice->GetInfo(D3DDEVINFOID_TEXTURING,&texappinfo,sizeof(D3DDEVINFO_TEXTURING)); + if (hr!=D3D_OK) { + if (hr==S_FALSE) + dxgsg_cat.error() << "GetInfo requires debug DX7 DLLs to be installed!!\n"; + else dxgsg_cat.error() << "GetInfo appinfo failed : result = " << ConvD3DErrorToString(hr) << endl; + } else + dxgsg_cat.spam() + << "\n NumLoads:\t" << texappinfo.dwNumLoads + << "\n ApproxBytesLoaded:\t" << texappinfo.dwApproxBytesLoaded + << "\n NumPreLoads:\t" << texappinfo.dwNumPreLoads + << "\n NumSet:\t" << texappinfo.dwNumSet + << "\n NumCreates:\t" << texappinfo.dwNumCreates + << "\n NumDestroys:\t" << texappinfo.dwNumDestroys + << "\n NumSetPriorities:\t" << texappinfo.dwNumSetPriorities + << "\n NumSetLODs:\t" << texappinfo.dwNumSetLODs + << "\n NumLocks:\t" << texappinfo.dwNumLocks + << "\n NumGetDCs:\t" << texappinfo.dwNumGetDCs << endl; + } + + } #endif #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "end frame ----------------------------------------------" << endl; + dxgsg_cat.debug() + << "end frame ----------------------------------------------" << endl; #endif } @@ -785,22 +776,22 @@ render_frame(const AllAttributesWrapper &initial_state) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: render_scene(Node *root, ProjectionNode *projnode, - const AllAttributesWrapper &initial_state) { + const AllAttributesWrapper &initial_state) { #ifdef GSG_VERBOSE - _pass_number = 0; - dxgsg_cat.debug() - << "begin scene - - - - - - - - - - - - - - - - - - - - - - - - -" - << endl; + _pass_number = 0; + dxgsg_cat.debug() + << "begin scene - - - - - - - - - - - - - - - - - - - - - - - - -" + << endl; #endif - _current_root_node = root; + _current_root_node = root; - render_subgraph(_render_traverser, root, projnode, initial_state, - AllTransitionsWrapper()); + render_subgraph(_render_traverser, root, projnode, initial_state, + AllTransitionsWrapper()); #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "done scene - - - - - - - - - - - - - - - - - - - - - - - - -" - << endl; + dxgsg_cat.debug() + << "done scene - - - - - - - - - - - - - - - - - - - - - - - - -" + << endl; #endif } @@ -814,64 +805,64 @@ render_scene(Node *root, ProjectionNode *projnode, //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: render_subgraph(RenderTraverser *traverser, - Node *subgraph, ProjectionNode *projnode, - const AllAttributesWrapper &initial_state, - const AllTransitionsWrapper &net_trans) { + Node *subgraph, ProjectionNode *projnode, + const AllAttributesWrapper &initial_state, + const AllTransitionsWrapper &net_trans) { // activate(); doesnt do anything right now - ProjectionNode *old_projection_node = _current_projection_node; - _current_projection_node = projnode; - LMatrix4f old_projection_mat = _current_projection_mat; + ProjectionNode *old_projection_node = _current_projection_node; + _current_projection_node = projnode; + LMatrix4f old_projection_mat = _current_projection_mat; - // d3d is left-handed coord system - LMatrix4f projection_mat = - projnode->get_projection()->get_projection_mat(CS_yup_left); + // d3d is left-handed coord system + LMatrix4f projection_mat = + projnode->get_projection()->get_projection_mat(CS_yup_left); - #if 0 - dxgsg_cat.spam() << "cur projection matrix: " << projection_mat <<"\n"; - #endif +#if 0 + dxgsg_cat.spam() << "cur projection matrix: " << projection_mat <<"\n"; +#endif - _current_projection_mat = projection_mat; - _projection_mat_stack_count++; + _current_projection_mat = projection_mat; + _projection_mat_stack_count++; - // We load the projection matrix directly. - HRESULT res = - _d3dDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, - (LPD3DMATRIX) _current_projection_mat.get_data()); + // We load the projection matrix directly. + HRESULT res = + _d3dDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, + (LPD3DMATRIX) _current_projection_mat.get_data()); - // We infer the modelview matrix by doing a wrt on the projection - // node. - LMatrix4f modelview_mat; - get_rel_mat(subgraph, _current_projection_node, modelview_mat); // reversed from GL + // We infer the modelview matrix by doing a wrt on the projection + // node. + LMatrix4f modelview_mat; + get_rel_mat(subgraph, _current_projection_node, modelview_mat); // reversed from GL // get_rel_mat(_current_projection_node, subgraph, modelview_mat); - if (_coordinate_system != CS_yup_left) { - // Now we build the coordinate system conversion into the - // modelview matrix (as described in the paragraph above). - modelview_mat = modelview_mat * - LMatrix4f::convert_mat(_coordinate_system, CS_yup_left); - } + if (_coordinate_system != CS_yup_left) { + // Now we build the coordinate system conversion into the + // modelview matrix (as described in the paragraph above). + modelview_mat = modelview_mat * + LMatrix4f::convert_mat(_coordinate_system, CS_yup_left); + } - // The modelview matrix will be loaded as each geometry is - // encountered. So we set the supplied modelview matrix as an - // initial value instead of loading it now. - AllTransitionsWrapper sub_trans = net_trans; - sub_trans.set_transition(new TransformTransition(modelview_mat)); + // The modelview matrix will be loaded as each geometry is + // encountered. So we set the supplied modelview matrix as an + // initial value instead of loading it now. + AllTransitionsWrapper sub_trans = net_trans; + sub_trans.set_transition(new TransformTransition(modelview_mat)); - render_subgraph(traverser, subgraph, initial_state, sub_trans); + render_subgraph(traverser, subgraph, initial_state, sub_trans); - _current_projection_node = old_projection_node; - _current_projection_mat = old_projection_mat; - _projection_mat_stack_count--; + _current_projection_node = old_projection_node; + _current_projection_mat = old_projection_mat; + _projection_mat_stack_count--; - // We must now restore the projection matrix from before. We could - // do a push/pop matrix, but OpenGL doesn't promise more than 2 - // levels in the projection matrix stack, so we'd better do it in - // the CPU. - if (_projection_mat_stack_count > 0) - _d3dDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, - (LPD3DMATRIX) _current_projection_mat.get_data()); - + // We must now restore the projection matrix from before. We could + // do a push/pop matrix, but OpenGL doesn't promise more than 2 + // levels in the projection matrix stack, so we'd better do it in + // the CPU. + if (_projection_mat_stack_count > 0) + _d3dDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, + (LPD3DMATRIX) _current_projection_mat.get_data()); + } //////////////////////////////////////////////////////////////////// @@ -884,23 +875,23 @@ render_subgraph(RenderTraverser *traverser, //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: render_subgraph(RenderTraverser *traverser, Node *subgraph, - const AllAttributesWrapper &initial_state, - const AllTransitionsWrapper &net_trans) { + const AllAttributesWrapper &initial_state, + const AllTransitionsWrapper &net_trans) { #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "begin subgraph (pass " << ++_pass_number - << ") - - - - - - - - - - - - - - - - - - - - - - - - -" << endl; + dxgsg_cat.debug() + << "begin subgraph (pass " << ++_pass_number + << ") - - - - - - - - - - - - - - - - - - - - - - - - -" << endl; #endif - activate(); - - nassertv(traverser != (RenderTraverser *)NULL); - traverser->traverse(subgraph, initial_state, net_trans); + activate(); + + nassertv(traverser != (RenderTraverser *)NULL); + traverser->traverse(subgraph, initial_state, net_trans); #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "end subgraph (pass " << _pass_number - << ") - - - - - - - - - - - - - - - - - - - - - - - - -" - << endl; + dxgsg_cat.debug() + << "end subgraph (pass " << _pass_number + << ") - - - - - - - - - - - - - - - - - - - - - - - - -" + << endl; #endif } @@ -910,17 +901,18 @@ render_subgraph(RenderTraverser *traverser, Node *subgraph, // Description: This adds data to the flexible vertex format //////////////////////////////////////////////////////////////////// INLINE void DXGraphicsStateGuardian:: -add_to_FVFBuf(void *data, size_t bytes) -{ - memcpy(_pCurFvfBufPtr, data, bytes); - _pCurFvfBufPtr += bytes; +add_to_FVFBuf(void *data, size_t bytes) { + memcpy(_pCurFvfBufPtr, data, bytes); + _pCurFvfBufPtr += bytes; } // generates slightly fewer instrs #define add_DWORD_to_FVFBuf(data) { *((DWORD *)_pCurFvfBufPtr) = (DWORD) data; _pCurFvfBufPtr += sizeof(DWORD);} -typedef enum {FlatVerts,IndexedVerts,MixedFmtVerts} GeomVertFormat; +typedef enum { + FlatVerts,IndexedVerts,MixedFmtVerts +} GeomVertFormat; //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::draw_point @@ -929,119 +921,119 @@ typedef enum {FlatVerts,IndexedVerts,MixedFmtVerts} GeomVertFormat; //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: draw_point(const GeomPoint *geom) { - activate(); + activate(); #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_point()" << endl; + dxgsg_cat.debug() << "draw_point()" << endl; #endif - // The DX Way + // The DX Way - int nPrims = geom->get_num_prims(); + int nPrims = geom->get_num_prims(); - if(nPrims==0) { - dxgsg_cat.warning() << "draw_point() called with ZERO vertices!!" << endl; - return; - } + if (nPrims==0) { + dxgsg_cat.warning() << "draw_point() called with ZERO vertices!!" << endl; + return; + } #ifdef _DEBUG - static BOOL bPrintedMsg=FALSE; + static BOOL bPrintedMsg=FALSE; - if(!bPrintedMsg && (geom->get_size()!=1.0f)) { - bPrintedMsg=TRUE; - dxgsg_cat.warning() << "D3D does not support drawing points of non-unit size, setting point size to 1.0!\n"; - } + if (!bPrintedMsg && (geom->get_size()!=1.0f)) { + bPrintedMsg=TRUE; + dxgsg_cat.warning() << "D3D does not support drawing points of non-unit size, setting point size to 1.0!\n"; + } #endif - nassertv(nPrims < D3DMAXNUMVERTICES ); + nassertv(nPrims < D3DMAXNUMVERTICES ); - PTA_Vertexf coords; - PTA_Normalf norms; - PTA_Colorf colors; - PTA_TexCoordf texcoords; - GeomBindType bind; - PTA_ushort vindexes,nindexes,tindexes,cindexes; + PTA_Vertexf coords; + PTA_Normalf norms; + PTA_Colorf colors; + PTA_TexCoordf texcoords; + GeomBindType bind; + PTA_ushort vindexes,nindexes,tindexes,cindexes; - geom->get_coords(coords,bind,vindexes); - geom->get_normals(norms,bind,nindexes); - geom->get_colors(colors,bind,cindexes); - geom->get_texcoords(texcoords,bind,tindexes); + geom->get_coords(coords,bind,vindexes); + geom->get_normals(norms,bind,nindexes); + geom->get_colors(colors,bind,cindexes); + geom->get_texcoords(texcoords,bind,tindexes); - GeomVertFormat GeomVrtFmt=FlatVerts; + GeomVertFormat GeomVrtFmt=FlatVerts; - // first determine if we're indexed or non-indexed + // first determine if we're indexed or non-indexed - if((vindexes!=NULL)&&(cindexes!=NULL)&&(tindexes!=NULL)&&(nindexes!=NULL)) { - GeomVrtFmt=IndexedVerts; - } else if(!((vindexes==NULL)&&(cindexes==NULL)&&(tindexes==NULL)&&(nindexes==NULL))) - GeomVrtFmt=MixedFmtVerts; + if ((vindexes!=NULL)&&(cindexes!=NULL)&&(tindexes!=NULL)&&(nindexes!=NULL)) { + GeomVrtFmt=IndexedVerts; + } else if (!((vindexes==NULL)&&(cindexes==NULL)&&(tindexes==NULL)&&(nindexes==NULL))) + GeomVrtFmt=MixedFmtVerts; #ifdef DONT_USE_DRAWPRIMSTRIDED - GeomVrtFmt=MixedFmtVerts; + GeomVrtFmt=MixedFmtVerts; #endif - // for Indexed Prims and mixed indexed/non-indexed prims, we will use old pipeline for now - // need to add code to handle fully indexed mode (and handle cases with index arrays of different lengths, - // values (may only be possible to handle certain cases without reverting to old pipeline) - if(GeomVrtFmt!=FlatVerts) { - - perVertex = PerCoord; - perPrim = 0; - if (geom->get_binding(G_COORD) == G_PER_VERTEX) perVertex |= PerCoord; - if (geom->get_binding(G_NORMAL) == G_PER_VERTEX) perVertex |= PerNormal; - if (geom->get_binding(G_COLOR) == G_PER_VERTEX) perVertex |= PerColor; - - size_t vertex_size = draw_prim_setup(geom); - - nassertv(_pCurFvfBufPtr == NULL); // make sure the storage pointer is clean. - nassertv(nPrims * vertex_size < VERT_BUFFER_SIZE); - _pCurFvfBufPtr = _pFvfBufBasePtr; // _pCurFvfBufPtr changes, _pFvfBufBasePtr doesn't - + // for Indexed Prims and mixed indexed/non-indexed prims, we will use old pipeline for now + // need to add code to handle fully indexed mode (and handle cases with index arrays of different lengths, + // values (may only be possible to handle certain cases without reverting to old pipeline) + if (GeomVrtFmt!=FlatVerts) { + + perVertex = PerCoord; + perPrim = 0; + if (geom->get_binding(G_COORD) == G_PER_VERTEX) perVertex |= PerCoord; + if (geom->get_binding(G_NORMAL) == G_PER_VERTEX) perVertex |= PerNormal; + if (geom->get_binding(G_COLOR) == G_PER_VERTEX) perVertex |= PerColor; + + size_t vertex_size = draw_prim_setup(geom); + + nassertv(_pCurFvfBufPtr == NULL); // make sure the storage pointer is clean. + nassertv(nPrims * vertex_size < VERT_BUFFER_SIZE); + _pCurFvfBufPtr = _pFvfBufBasePtr; // _pCurFvfBufPtr changes, _pFvfBufBasePtr doesn't + // iterate through the point - draw_prim_inner_loop2(nPrims, geom, perPrim); - - _d3dDevice->DrawPrimitive(D3DPT_POINTLIST, p_flags, _pFvfBufBasePtr, nPrims, NULL); - } else { + draw_prim_inner_loop2(nPrims, geom, perPrim); - size_t vertex_size = draw_prim_setup(geom); + _d3dDevice->DrawPrimitive(D3DPT_POINTLIST, p_flags, _pFvfBufBasePtr, nPrims, NULL); + } else { - // new code only handles non-indexed pointlists (is this enough?) - nassertv((vindexes==NULL)&&(cindexes==NULL)&&(tindexes==NULL)&&(nindexes==NULL)); + size_t vertex_size = draw_prim_setup(geom); - D3DDRAWPRIMITIVESTRIDEDDATA dps_data; - memset(&dps_data,0,sizeof(D3DDRAWPRIMITIVESTRIDEDDATA)); - - dps_data.position.lpvData = (VOID*)coords; - dps_data.position.dwStride = sizeof(D3DVECTOR); + // new code only handles non-indexed pointlists (is this enough?) + nassertv((vindexes==NULL)&&(cindexes==NULL)&&(tindexes==NULL)&&(nindexes==NULL)); - if (p_flags & D3DFVF_NORMAL) { - dps_data.normal.lpvData = (VOID*)norms; - dps_data.normal.dwStride = sizeof(D3DVECTOR); - } + D3DDRAWPRIMITIVESTRIDEDDATA dps_data; + memset(&dps_data,0,sizeof(D3DDRAWPRIMITIVESTRIDEDDATA)); - if (p_flags & D3DFVF_DIFFUSE) { - // Geom nodes store floats for colors, drawprim requires ARGB dwords - // BUGBUG: eventually this hack conversion needs to be done only once as part of a vertex buffer - _pCurFvfBufPtr=_pFvfBufBasePtr; + dps_data.position.lpvData = (VOID*)coords; + dps_data.position.dwStride = sizeof(D3DVECTOR); - for(int i=0;iDrawPrimitiveStrided(D3DPT_POINTLIST, p_flags, &dps_data, nPrims, NULL); - } + dps_data.diffuse.lpvData = (VOID*)_pFvfBufBasePtr; + dps_data.diffuse.dwStride = sizeof(D3DCOLOR); + } - _pCurFvfBufPtr = NULL; + if (p_flags & D3DFVF_TEXCOUNT_MASK) { + dps_data.textureCoords[0].lpvData = (VOID*)texcoords; + dps_data.textureCoords[0].dwStride = sizeof(TexCoordf); + } + + _d3dDevice->DrawPrimitiveStrided(D3DPT_POINTLIST, p_flags, &dps_data, nPrims, NULL); + } + + _pCurFvfBufPtr = NULL; } //////////////////////////////////////////////////////////////////// @@ -1051,107 +1043,103 @@ draw_point(const GeomPoint *geom) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: draw_line(const GeomLine* geom) { - activate(); - + activate(); + #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_line()" << endl; + dxgsg_cat.debug() << "draw_line()" << endl; #endif #ifdef _DEBUG - static BOOL bPrintedMsg=FALSE; + static BOOL bPrintedMsg=FALSE; - if(!bPrintedMsg && (geom->get_width()!=1.0f)) { - bPrintedMsg=TRUE; - dxgsg_cat.warning() << "DX does not support drawing lines with a non-1.0 pixel width, setting width to 1.0!\n"; - } + if (!bPrintedMsg && (geom->get_width()!=1.0f)) { + bPrintedMsg=TRUE; + dxgsg_cat.warning() << "DX does not support drawing lines with a non-1.0 pixel width, setting width to 1.0!\n"; + } #endif #ifdef WBD_GL_MODE - call_glLineWidth(geom->get_width()); - - int nprims = geom->get_num_prims(); - Geom::VertexIterator vi = geom->make_vertex_iterator(); - Geom::ColorIterator ci = geom->make_color_iterator(); + call_glLineWidth(geom->get_width()); - GeomIssuer issuer(geom, this, - issue_vertex_gl, - issue_normal_gl, - issue_texcoord_gl, - issue_color_gl); + int nprims = geom->get_num_prims(); + Geom::VertexIterator vi = geom->make_vertex_iterator(); + Geom::ColorIterator ci = geom->make_color_iterator(); - if (geom->get_binding(G_COLOR) == G_PER_VERTEX) { - call_glShadeModel(GL_SMOOTH); - } else { - call_glShadeModel(GL_FLAT); - } + GeomIssuer issuer(geom, this, + issue_vertex_gl, + issue_normal_gl, + issue_texcoord_gl, + issue_color_gl); - // Draw overall - issuer.issue_color(G_OVERALL, ci); - - glBegin(GL_LINES); + if (geom->get_binding(G_COLOR) == G_PER_VERTEX) { + call_glShadeModel(GL_SMOOTH); + } else { + call_glShadeModel(GL_FLAT); + } - for (int i = 0; i < nprims; i++) { - // Draw per primitive - issuer.issue_color(G_PER_PRIM, ci); + // Draw overall + issuer.issue_color(G_OVERALL, ci); - for (int j = 0; j < 2; j++) { - // Draw per vertex - issuer.issue_color(G_PER_VERTEX, ci); - issuer.issue_vertex(G_PER_VERTEX, vi); - } - } + glBegin(GL_LINES); - glEnd(); + for (int i = 0; i < nprims; i++) { + // Draw per primitive + issuer.issue_color(G_PER_PRIM, ci); + + for (int j = 0; j < 2; j++) { + // Draw per vertex + issuer.issue_color(G_PER_VERTEX, ci); + issuer.issue_vertex(G_PER_VERTEX, vi); + } + } + + glEnd(); #else // the DX way - int nPrims = geom->get_num_prims(); + int nPrims = geom->get_num_prims(); - if(nPrims==0) { - dxgsg_cat.warning() << "draw_line() called with ZERO vertices!!" << endl; - return; - } + if (nPrims==0) { + dxgsg_cat.warning() << "draw_line() called with ZERO vertices!!" << endl; + return; + } - perVertex = 0; - if (geom->get_binding(G_COORD) == G_PER_VERTEX) perVertex |= PerCoord; - if (geom->get_binding(G_NORMAL) == G_PER_VERTEX) perVertex |= PerNormal; - if (geom->get_binding(G_COLOR) == G_PER_VERTEX) perVertex |= PerColor; + perVertex = 0; + if (geom->get_binding(G_COORD) == G_PER_VERTEX) perVertex |= PerCoord; + if (geom->get_binding(G_NORMAL) == G_PER_VERTEX) perVertex |= PerNormal; + if (geom->get_binding(G_COLOR) == G_PER_VERTEX) perVertex |= PerColor; - perPrim = 0; - if (geom->get_binding(G_NORMAL) == G_PER_PRIM) perPrim |= PerNormal; - if (geom->get_binding(G_COLOR) == G_PER_PRIM) perPrim |= PerColor; + perPrim = 0; + if (geom->get_binding(G_NORMAL) == G_PER_PRIM) perPrim |= PerNormal; + if (geom->get_binding(G_COLOR) == G_PER_PRIM) perPrim |= PerColor; - size_t vertex_size = draw_prim_setup(geom); + size_t vertex_size = draw_prim_setup(geom); - char *_tmp_fvf = NULL; - nassertv(_pCurFvfBufPtr == NULL); // make sure the storage pointer is clean. + char *_tmp_fvf = NULL; + nassertv(_pCurFvfBufPtr == NULL); // make sure the storage pointer is clean. // nassertv(nPrims * 2 * vertex_size < VERT_BUFFER_SIZE); - - if (nPrims * 2 * vertex_size > VERT_BUFFER_SIZE) - { - _pCurFvfBufPtr = _tmp_fvf = new char[nPrims * 2 * vertex_size]; - } - else _pCurFvfBufPtr = _pFvfBufBasePtr; // _pCurFvfBufPtr changes, _pFvfBufBasePtr doesn't - - for (int i = 0; i < nPrims; i++) - { - if (perPrim & PerColor) - { - p_color = geom->get_next_color(ci); // set primitive color if there is one. - p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); - } - if (perPrim & PerNormal) - p_normal = geom->get_next_normal(ni); // set primitive normal if there is one. - draw_prim_inner_loop(2, geom); - } - if (_tmp_fvf == NULL) - _d3dDevice->DrawPrimitive(D3DPT_LINELIST, p_flags, _pFvfBufBasePtr, nPrims*2, NULL); - else { - _d3dDevice->DrawPrimitive(D3DPT_LINELIST, p_flags, _tmp_fvf, nPrims*2, NULL); - delete [] _tmp_fvf; - } + if (nPrims * 2 * vertex_size > VERT_BUFFER_SIZE) { + _pCurFvfBufPtr = _tmp_fvf = new char[nPrims * 2 * vertex_size]; + } else _pCurFvfBufPtr = _pFvfBufBasePtr; // _pCurFvfBufPtr changes, _pFvfBufBasePtr doesn't - _pCurFvfBufPtr = NULL; + for (int i = 0; i < nPrims; i++) { + if (perPrim & PerColor) { + p_color = geom->get_next_color(ci); // set primitive color if there is one. + p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); + } + if (perPrim & PerNormal) + p_normal = geom->get_next_normal(ni); // set primitive normal if there is one. + draw_prim_inner_loop(2, geom); + } + + if (_tmp_fvf == NULL) + _d3dDevice->DrawPrimitive(D3DPT_LINELIST, p_flags, _pFvfBufBasePtr, nPrims*2, NULL); + else { + _d3dDevice->DrawPrimitive(D3DPT_LINELIST, p_flags, _tmp_fvf, nPrims*2, NULL); + delete [] _tmp_fvf; + } + + _pCurFvfBufPtr = NULL; #endif // WBD_GL_MODE } @@ -1163,120 +1151,118 @@ draw_line(const GeomLine* geom) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: draw_linestrip(const GeomLinestrip* geom) { - activate(); + activate(); #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_linestrip()" << endl; + dxgsg_cat.debug() << "draw_linestrip()" << endl; #endif #ifdef _DEBUG - static BOOL bPrintedMsg=FALSE; + static BOOL bPrintedMsg=FALSE; - if(!bPrintedMsg && (geom->get_width()!=1.0f)) { - bPrintedMsg=TRUE; - dxgsg_cat.warning() << "DX does not support drawing lines with a non-1.0 pixel width, setting width to 1.0!\n"; - } + if (!bPrintedMsg && (geom->get_width()!=1.0f)) { + bPrintedMsg=TRUE; + dxgsg_cat.warning() << "DX does not support drawing lines with a non-1.0 pixel width, setting width to 1.0!\n"; + } #endif #ifdef WBD_GL_MODE - call_glLineWidth(geom->get_width()); + call_glLineWidth(geom->get_width()); - int nprims = geom->get_num_prims(); - const int *plen = geom->get_lengths(); - Geom::VertexIterator vi = geom->make_vertex_iterator(); - Geom::ColorIterator ci = geom->make_color_iterator(); + int nprims = geom->get_num_prims(); + const int *plen = geom->get_lengths(); + Geom::VertexIterator vi = geom->make_vertex_iterator(); + Geom::ColorIterator ci = geom->make_color_iterator(); - GeomIssuer issuer(geom, this, - issue_vertex_gl, - issue_normal_gl, - issue_texcoord_gl, - issue_color_gl); + GeomIssuer issuer(geom, this, + issue_vertex_gl, + issue_normal_gl, + issue_texcoord_gl, + issue_color_gl); - if (geom->get_binding(G_COLOR) == G_PER_VERTEX) { - call_glShadeModel(GL_SMOOTH); - } else { - call_glShadeModel(GL_FLAT); - } + if (geom->get_binding(G_COLOR) == G_PER_VERTEX) { + call_glShadeModel(GL_SMOOTH); + } else { + call_glShadeModel(GL_FLAT); + } - // Draw overall - issuer.issue_color(G_OVERALL, ci); + // Draw overall + issuer.issue_color(G_OVERALL, ci); - for (int i = 0; i < nprims; i++) { - // Draw per primitive - issuer.issue_color(G_PER_PRIM, ci); + for (int i = 0; i < nprims; i++) { + // Draw per primitive + issuer.issue_color(G_PER_PRIM, ci); - int num_verts = *(plen++); - nassertv(num_verts >= 2); - - glBegin(GL_LINE_STRIP); + int num_verts = *(plen++); + nassertv(num_verts >= 2); - // Per-component attributes for the first line segment? - issuer.issue_color(G_PER_COMPONENT, ci); + glBegin(GL_LINE_STRIP); - // Draw the first 2 vertices - int v; - for (v = 0; v < 2; v++) { - issuer.issue_color(G_PER_VERTEX, ci); - issuer.issue_vertex(G_PER_VERTEX, vi); - } + // Per-component attributes for the first line segment? + issuer.issue_color(G_PER_COMPONENT, ci); - // Now draw each of the remaining vertices. Each vertex from - // this point on defines a new line segment. - for (v = 2; v < num_verts; v++) { - // Per-component attributes? - issuer.issue_color(G_PER_COMPONENT, ci); + // Draw the first 2 vertices + int v; + for (v = 0; v < 2; v++) { + issuer.issue_color(G_PER_VERTEX, ci); + issuer.issue_vertex(G_PER_VERTEX, vi); + } - // Per-vertex attributes - issuer.issue_color(G_PER_VERTEX, ci); - issuer.issue_vertex(G_PER_VERTEX, vi); - } - glEnd(); - } + // Now draw each of the remaining vertices. Each vertex from + // this point on defines a new line segment. + for (v = 2; v < num_verts; v++) { + // Per-component attributes? + issuer.issue_color(G_PER_COMPONENT, ci); + + // Per-vertex attributes + issuer.issue_color(G_PER_VERTEX, ci); + issuer.issue_vertex(G_PER_VERTEX, vi); + } + glEnd(); + } #else - int nPrims = geom->get_num_prims(); - const int *plen = geom->get_lengths(); + int nPrims = geom->get_num_prims(); + const int *plen = geom->get_lengths(); - if(nPrims==0) { - dxgsg_cat.warning() << "draw_linestrip() called with ZERO vertices!!" << endl; - return; - } + if (nPrims==0) { + dxgsg_cat.warning() << "draw_linestrip() called with ZERO vertices!!" << endl; + return; + } - perVertex = 0; - if (geom->get_binding(G_COORD) == G_PER_VERTEX) perVertex |= PerCoord; - if (geom->get_binding(G_NORMAL) == G_PER_VERTEX) perVertex |= PerNormal; - if (geom->get_binding(G_COLOR) == G_PER_VERTEX) perVertex |= PerColor; + perVertex = 0; + if (geom->get_binding(G_COORD) == G_PER_VERTEX) perVertex |= PerCoord; + if (geom->get_binding(G_NORMAL) == G_PER_VERTEX) perVertex |= PerNormal; + if (geom->get_binding(G_COLOR) == G_PER_VERTEX) perVertex |= PerColor; - perComp = 0; - if (geom->get_binding(G_NORMAL) == G_PER_COMPONENT) perComp |= PerNormal; - if (geom->get_binding(G_COLOR) == G_PER_COMPONENT) perComp |= PerColor; + perComp = 0; + if (geom->get_binding(G_NORMAL) == G_PER_COMPONENT) perComp |= PerNormal; + if (geom->get_binding(G_COLOR) == G_PER_COMPONENT) perComp |= PerColor; - perPrim = 0; - if (geom->get_binding(G_NORMAL) == G_PER_PRIM) perPrim |= PerNormal; - if (geom->get_binding(G_COLOR) == G_PER_PRIM) perPrim |= PerColor; + perPrim = 0; + if (geom->get_binding(G_NORMAL) == G_PER_PRIM) perPrim |= PerNormal; + if (geom->get_binding(G_COLOR) == G_PER_PRIM) perPrim |= PerColor; - size_t vertex_size = draw_prim_setup(geom); + size_t vertex_size = draw_prim_setup(geom); - for (int i = 0; i < nPrims; i++) - { - if (perPrim & PerColor) - { - p_color = geom->get_next_color(ci); // set primitive color if there is one. - p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); - } + for (int i = 0; i < nPrims; i++) { + if (perPrim & PerColor) { + p_color = geom->get_next_color(ci); // set primitive color if there is one. + p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); + } - int nVerts = *(plen++); - nassertv(nVerts >= 2); + int nVerts = *(plen++); + nassertv(nVerts >= 2); - nassertv(_pCurFvfBufPtr == NULL); // make sure the storage pointer is clean. - nassertv(nVerts * vertex_size < VERT_BUFFER_SIZE); - _pCurFvfBufPtr = _pFvfBufBasePtr; // _pCurFvfBufPtr changes, _pFvfBufBasePtr doesn't - - draw_prim_inner_loop2(nVerts, geom, perComp); + nassertv(_pCurFvfBufPtr == NULL); // make sure the storage pointer is clean. + nassertv(nVerts * vertex_size < VERT_BUFFER_SIZE); + _pCurFvfBufPtr = _pFvfBufBasePtr; // _pCurFvfBufPtr changes, _pFvfBufBasePtr doesn't - _d3dDevice->DrawPrimitive(D3DPT_LINESTRIP, p_flags, _pFvfBufBasePtr, nVerts, NULL); + draw_prim_inner_loop2(nVerts, geom, perComp); - _pCurFvfBufPtr = NULL; - } + _d3dDevice->DrawPrimitive(D3DPT_LINESTRIP, p_flags, _pFvfBufBasePtr, nVerts, NULL); + + _pCurFvfBufPtr = NULL; + } #endif // WBD_GL_MODE @@ -1288,31 +1274,31 @@ draw_linestrip(const GeomLinestrip* geom) { // each vertex may or may not have corresponding information in the // x/y texel-world-ratio and rotation arrays. typedef struct { - Vertexf _v; - D3DCOLOR _c; - float _x_ratio; - float _y_ratio; - float _theta; + Vertexf _v; + D3DCOLOR _c; + float _x_ratio; + float _y_ratio; + float _theta; } WrappedSprite; class WrappedSpriteSortPtr { public: - float z; - WrappedSprite *pSpr; + float z; + WrappedSprite *pSpr; }; // this struct exists because the STL can sort faster than i can. struct draw_sprite_vertex_less { - INLINE bool operator ()(const WrappedSpriteSortPtr& v0, - const WrappedSpriteSortPtr& v1) const { - return v0.z > v1.z; // reversed from gl - } + INLINE bool operator ()(const WrappedSpriteSortPtr& v0, + const WrappedSpriteSortPtr& v1) const { + return v0.z > v1.z; // reversed from gl + } }; /* struct draw_sprite_vertex_less { INLINE bool operator ()(const WrappedSprite& v0, - const WrappedSprite& v1) const { - return v0._v[2] > v1._v[2]; // reversed from gl + const WrappedSprite& v1) const { + return v0._v[2] > v1._v[2]; // reversed from gl } }; */ @@ -1325,316 +1311,316 @@ struct draw_sprite_vertex_less { void DXGraphicsStateGuardian:: draw_sprite(const GeomSprite *geom) { - // this is a little bit of a mess, but it's ok. Here's the deal: - // we want to draw, and draw quickly, an arbitrarily large number - // of sprites all facing the screen. Performing the billboard math - // for ~1000 sprites is way too slow. Ideally, we want one - // matrix transformation that will handle everything, and this is - // just about what ends up happening. We're getting the front-facing - // effect by setting up a new frustum (of the same z-depth as the - // current one) that is very small in x and y. This way regularly - // rendered triangles that might not be EXACTLY facing the camera - // will certainly look close enough. Then, we transform to camera-space - // by hand and apply the inverse frustum to the transformed point. - // For some cracked out reason, this actually works. + // this is a little bit of a mess, but it's ok. Here's the deal: + // we want to draw, and draw quickly, an arbitrarily large number + // of sprites all facing the screen. Performing the billboard math + // for ~1000 sprites is way too slow. Ideally, we want one + // matrix transformation that will handle everything, and this is + // just about what ends up happening. We're getting the front-facing + // effect by setting up a new frustum (of the same z-depth as the + // current one) that is very small in x and y. This way regularly + // rendered triangles that might not be EXACTLY facing the camera + // will certainly look close enough. Then, we transform to camera-space + // by hand and apply the inverse frustum to the transformed point. + // For some cracked out reason, this actually works. - // Note: for DX8, try to use the PointSprite primitive instead of doing all the stuff below + // Note: for DX8, try to use the PointSprite primitive instead of doing all the stuff below #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_sprite()" << endl; + dxgsg_cat.debug() << "draw_sprite()" << endl; #endif - Texture *tex = geom->get_texture(); - nassertv(tex != (Texture *) NULL); + Texture *tex = geom->get_texture(); + nassertv(tex != (Texture *) NULL); - // get the array traversal set up. - int nprims = geom->get_num_prims(); + // get the array traversal set up. + int nprims = geom->get_num_prims(); - if(nprims==0) { - dxgsg_cat.warning() << "draw_sprite() called with ZERO vertices!!" << endl; - return; - } - - D3DMATRIX OldD3DWorldMatrix; - _d3dDevice->GetTransform(D3DTRANSFORMSTATE_WORLD, &OldD3DWorldMatrix); - - Geom::VertexIterator vi = geom->make_vertex_iterator(); - Geom::ColorIterator ci = geom->make_color_iterator(); - - // save the modelview matrix - LMatrix4f modelview_mat; - - const TransformAttribute *ctatt; - if (!get_attribute_into(ctatt, _state, TransformTransition::get_class_type())) - modelview_mat = LMatrix4f::ident_mat(); - else - modelview_mat = ctatt->get_matrix(); - - // get the camera information - float aspect_ratio; - aspect_ratio = _actual_display_region->get_camera()->get_aspect(); - - // null the world xform, so sprites are orthog to scrn (but not necessarily camera pntm unless they lie along z-axis) - _d3dDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matIdentity); - // only need to change _WORLD xform, _VIEW xform is Identity - - // precomputation stuff - float half_width = 0.5f * (float) tex->_pbuffer->get_xsize(); - float half_height = 0.5f * (float) tex->_pbuffer->get_ysize(); - float scaled_width, scaled_height; - - // set up the texture-rendering state - NodeAttributes state; - - // this sets up texturing. Could just set the renderstates directly, but this is a little cleaner - TextureAttribute *ta = new TextureAttribute; - ta->set_on(tex); - state.set_attribute(TextureTransition::get_class_type(), ta); - - TextureApplyAttribute *taa = new TextureApplyAttribute; - taa->set_mode(TextureApplyProperty::M_modulate); - state.set_attribute(TextureApplyTransition::get_class_type(), taa); - - set_state(state, false); - - // the user can override alpha sorting if they want - bool alpha = false; - - if (geom->get_alpha_disable() == false) { - // figure out if alpha's enabled (if not, no reason to sort) - const TransparencyAttribute *ctratt; - if (get_attribute_into(ctratt, _state, TransparencyTransition::get_class_type())) - alpha = true; - } - - // inner loop vars - int i; - Vertexf source_vert, cameraspace_vert; - float *x_walk, *y_walk, *theta_walk; - float theta; - - nassertv(geom->get_x_bind_type() != G_PER_VERTEX); - nassertv(geom->get_y_bind_type() != G_PER_VERTEX); - - // set up the non-built-in bindings - bool x_overall = (geom->get_x_bind_type() == G_OVERALL); - bool y_overall = (geom->get_y_bind_type() == G_OVERALL); - bool theta_overall = (geom->get_theta_bind_type() == G_OVERALL); - bool color_overall = (geom->get_binding(G_COLOR) == G_OVERALL); - bool theta_on = !(geom->get_theta_bind_type() == G_OFF); - - // x direction - if (x_overall == true) - scaled_width = geom->_x_texel_ratio[0] * half_width; - else { - nassertv(((int)geom->_x_texel_ratio.size() >= geom->get_num_prims())); - x_walk = &geom->_x_texel_ratio[0]; - } - - // y direction - if (y_overall == true) - scaled_height = geom->_y_texel_ratio[0] * half_height * aspect_ratio; - else { - nassertv(((int)geom->_y_texel_ratio.size() >= geom->get_num_prims())); - y_walk = &geom->_y_texel_ratio[0]; - } - - // theta - if (theta_on) { - if (theta_overall == true) - theta = geom->_theta[0]; - else { - nassertv(((int)geom->_theta.size() >= geom->get_num_prims())); - theta_walk = &geom->_theta[0]; - } - } - - ///////////////////////////////////////////////////////////////////// - // INNER LOOP PART 1 STARTS HERE - // Here we transform each point to cameraspace and fill our sort - // vector with the final geometric information. - ///////////////////////////////////////////////////////////////////// - - Colorf v_color; - - // sort container and iterator - vector< WrappedSpriteSortPtr > sorted_sprite_vector; - vector< WrappedSpriteSortPtr >::iterator sorted_vec_iter; - - WrappedSprite *SpriteArray = new WrappedSprite[nprims]; - - //BUGBUG: could we use _fvfbuf for this to avoid perframe alloc? - // alternately, alloc once when retained mode becomes available - - if(SpriteArray==NULL) { - dxgsg_cat.fatal() << "draw_sprite() out of memory!!" << endl; - return; - } - - // the state is set, start running the prims - - WrappedSprite *pSpr; - - for (pSpr=SpriteArray,i = 0; i < nprims; i++,pSpr++) { - - source_vert = geom->get_next_vertex(vi); - cameraspace_vert = modelview_mat * source_vert; - - pSpr->_v.set(cameraspace_vert[0],cameraspace_vert[1],cameraspace_vert[2]); - - if (color_overall == false) { - v_color = geom->get_next_color(ci); - pSpr->_c = D3DRGBA(v_color[0], v_color[1], v_color[2], v_color[3]); + if (nprims==0) { + dxgsg_cat.warning() << "draw_sprite() called with ZERO vertices!!" << endl; + return; } - if (x_overall == false) - pSpr->_x_ratio = *x_walk++; - if (y_overall == false) - pSpr->_y_ratio = *y_walk++; // go along array of ratio values stored in geom - if (theta_on && (theta_overall == false)) - pSpr->_theta = *theta_walk++; - } - if(alpha) { - sorted_sprite_vector.reserve(nprims); //pre-alloc space for nprims + D3DMATRIX OldD3DWorldMatrix; + _d3dDevice->GetTransform(D3DTRANSFORMSTATE_WORLD, &OldD3DWorldMatrix); - for (pSpr=SpriteArray,i = 0; i < nprims; i++,pSpr++) { // build STL-sortable array - WrappedSpriteSortPtr ws_ptr; - ws_ptr.z=pSpr->_v[2]; - ws_ptr.pSpr=pSpr; - sorted_sprite_vector.push_back(ws_ptr); - } + Geom::VertexIterator vi = geom->make_vertex_iterator(); + Geom::ColorIterator ci = geom->make_color_iterator(); - // sort the verts properly by alpha (if necessary). Of course, - // the sort is only local, not scene-global, so if you look closely you'll - // notice that alphas may be screwy. It's ok though, because this is fast. - // if you want accuracy, use billboards and take the speed hit. + // save the modelview matrix + LMatrix4f modelview_mat; - sort(sorted_sprite_vector.begin(), sorted_sprite_vector.end(), draw_sprite_vertex_less()); + const TransformAttribute *ctatt; + if (!get_attribute_into(ctatt, _state, TransformTransition::get_class_type())) + modelview_mat = LMatrix4f::ident_mat(); + else + modelview_mat = ctatt->get_matrix(); - sorted_vec_iter = sorted_sprite_vector.begin(); - } + // get the camera information + float aspect_ratio; + aspect_ratio = _actual_display_region->get_camera()->get_aspect(); - Vertexf ul, ur, ll, lr; + // null the world xform, so sprites are orthog to scrn (but not necessarily camera pntm unless they lie along z-axis) + _d3dDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matIdentity); + // only need to change _WORLD xform, _VIEW xform is Identity - //////////////////////////////////////////////////////////////////////////// - // INNER LOOP PART 2 STARTS HERE - // Now we run through the cameraspace vector and compute the geometry for each - // tristrip. This includes scaling as per the ratio arrays, as well as - // rotating in the z. - //////////////////////////////////////////////////////////////////////////// + // precomputation stuff + float half_width = 0.5f * (float) tex->_pbuffer->get_xsize(); + float half_height = 0.5f * (float) tex->_pbuffer->get_ysize(); + float scaled_width, scaled_height; - p_flags = D3DFVF_XYZ | (D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0)) ; - DWORD vertex_size = sizeof(float) * 2 + sizeof(D3DVALUE) * 3; + // set up the texture-rendering state + NodeAttributes state; - D3DCOLOR CurColor; - bool bDoColor=TRUE; - if(color_overall == true) { - v_color = geom->get_next_color(ci); - CurColor = D3DRGBA(v_color[0], v_color[1], v_color[2], v_color[3]); - bDoColor = (CurColor != ~0); - } + // this sets up texturing. Could just set the renderstates directly, but this is a little cleaner + TextureAttribute *ta = new TextureAttribute; + ta->set_on(tex); + state.set_attribute(TextureTransition::get_class_type(), ta); - if(bDoColor) { - p_flags |= D3DFVF_DIFFUSE; - vertex_size+=sizeof(D3DCOLOR); - } - - nassertv(_pCurFvfBufPtr == NULL); // make sure the storage pointer is clean. - nassertv(nprims * 4 * vertex_size < VERT_BUFFER_SIZE); - nassertv(nprims * 6 < D3DMAXNUMVERTICES ); + TextureApplyAttribute *taa = new TextureApplyAttribute; + taa->set_mode(TextureApplyProperty::M_modulate); + state.set_attribute(TextureApplyTransition::get_class_type(), taa); - _pCurFvfBufPtr = _pFvfBufBasePtr; // _pCurFvfBufPtr changes, _pFvfBufBasePtr doesn't - const float TexCrdSets[4][2] = {{0.0,0.0},{1.0,0.0},{0.0,1.0},{1.0,1.0}}; + set_state(state, false); + + // the user can override alpha sorting if they want + bool alpha = false; + + if (geom->get_alpha_disable() == false) { + // figure out if alpha's enabled (if not, no reason to sort) + const TransparencyAttribute *ctratt; + if (get_attribute_into(ctratt, _state, TransparencyTransition::get_class_type())) + alpha = true; + } + + // inner loop vars + int i; + Vertexf source_vert, cameraspace_vert; + float *x_walk, *y_walk, *theta_walk; + float theta; + + nassertv(geom->get_x_bind_type() != G_PER_VERTEX); + nassertv(geom->get_y_bind_type() != G_PER_VERTEX); + + // set up the non-built-in bindings + bool x_overall = (geom->get_x_bind_type() == G_OVERALL); + bool y_overall = (geom->get_y_bind_type() == G_OVERALL); + bool theta_overall = (geom->get_theta_bind_type() == G_OVERALL); + bool color_overall = (geom->get_binding(G_COLOR) == G_OVERALL); + bool theta_on = !(geom->get_theta_bind_type() == G_OFF); + + // x direction + if (x_overall == true) + scaled_width = geom->_x_texel_ratio[0] * half_width; + else { + nassertv(((int)geom->_x_texel_ratio.size() >= geom->get_num_prims())); + x_walk = &geom->_x_texel_ratio[0]; + } + + // y direction + if (y_overall == true) + scaled_height = geom->_y_texel_ratio[0] * half_height * aspect_ratio; + else { + nassertv(((int)geom->_y_texel_ratio.size() >= geom->get_num_prims())); + y_walk = &geom->_y_texel_ratio[0]; + } + + // theta + if (theta_on) { + if (theta_overall == true) + theta = geom->_theta[0]; + else { + nassertv(((int)geom->_theta.size() >= geom->get_num_prims())); + theta_walk = &geom->_theta[0]; + } + } + + ///////////////////////////////////////////////////////////////////// + // INNER LOOP PART 1 STARTS HERE + // Here we transform each point to cameraspace and fill our sort + // vector with the final geometric information. + ///////////////////////////////////////////////////////////////////// + + Colorf v_color; + + // sort container and iterator + vector< WrappedSpriteSortPtr > sorted_sprite_vector; + vector< WrappedSpriteSortPtr >::iterator sorted_vec_iter; + + WrappedSprite *SpriteArray = new WrappedSprite[nprims]; + + //BUGBUG: could we use _fvfbuf for this to avoid perframe alloc? + // alternately, alloc once when retained mode becomes available + + if (SpriteArray==NULL) { + dxgsg_cat.fatal() << "draw_sprite() out of memory!!" << endl; + return; + } + + // the state is set, start running the prims + + WrappedSprite *pSpr; + + for (pSpr=SpriteArray,i = 0; i < nprims; i++,pSpr++) { + + source_vert = geom->get_next_vertex(vi); + cameraspace_vert = modelview_mat * source_vert; + + pSpr->_v.set(cameraspace_vert[0],cameraspace_vert[1],cameraspace_vert[2]); + + if (color_overall == false) { + v_color = geom->get_next_color(ci); + pSpr->_c = D3DRGBA(v_color[0], v_color[1], v_color[2], v_color[3]); + } + if (x_overall == false) + pSpr->_x_ratio = *x_walk++; + if (y_overall == false) + pSpr->_y_ratio = *y_walk++; // go along array of ratio values stored in geom + if (theta_on && (theta_overall == false)) + pSpr->_theta = *theta_walk++; + } + + if (alpha) { + sorted_sprite_vector.reserve(nprims); //pre-alloc space for nprims + + for (pSpr=SpriteArray,i = 0; i < nprims; i++,pSpr++) { // build STL-sortable array + WrappedSpriteSortPtr ws_ptr; + ws_ptr.z=pSpr->_v[2]; + ws_ptr.pSpr=pSpr; + sorted_sprite_vector.push_back(ws_ptr); + } + + // sort the verts properly by alpha (if necessary). Of course, + // the sort is only local, not scene-global, so if you look closely you'll + // notice that alphas may be screwy. It's ok though, because this is fast. + // if you want accuracy, use billboards and take the speed hit. + + sort(sorted_sprite_vector.begin(), sorted_sprite_vector.end(), draw_sprite_vertex_less()); + + sorted_vec_iter = sorted_sprite_vector.begin(); + } + + Vertexf ul, ur, ll, lr; + + //////////////////////////////////////////////////////////////////////////// + // INNER LOOP PART 2 STARTS HERE + // Now we run through the cameraspace vector and compute the geometry for each + // tristrip. This includes scaling as per the ratio arrays, as well as + // rotating in the z. + //////////////////////////////////////////////////////////////////////////// + + p_flags = D3DFVF_XYZ | (D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0)) ; + DWORD vertex_size = sizeof(float) * 2 + sizeof(D3DVALUE) * 3; + + D3DCOLOR CurColor; + bool bDoColor=TRUE; + if (color_overall == true) { + v_color = geom->get_next_color(ci); + CurColor = D3DRGBA(v_color[0], v_color[1], v_color[2], v_color[3]); + bDoColor = (CurColor != ~0); + } + + if (bDoColor) { + p_flags |= D3DFVF_DIFFUSE; + vertex_size+=sizeof(D3DCOLOR); + } + + nassertv(_pCurFvfBufPtr == NULL); // make sure the storage pointer is clean. + nassertv(nprims * 4 * vertex_size < VERT_BUFFER_SIZE); + nassertv(nprims * 6 < D3DMAXNUMVERTICES ); + + _pCurFvfBufPtr = _pFvfBufBasePtr; // _pCurFvfBufPtr changes, _pFvfBufBasePtr doesn't + const float TexCrdSets[4][2] = {{0.0,0.0},{1.0,0.0},{0.0,1.0},{1.0,1.0}}; #define QUADVERTLISTLEN 6 - DWORD QuadVertIndexList[QUADVERTLISTLEN] = { 0, 1, 2, 3, 2, 1 }; - DWORD CurDPIndexArrLength=0,CurVertCount=0; + DWORD QuadVertIndexList[QUADVERTLISTLEN] = { 0, 1, 2, 3, 2, 1}; + DWORD CurDPIndexArrLength=0,CurVertCount=0; - for (pSpr=SpriteArray,i = 0; i < nprims; i++,pSpr++) { // build STL-sortable array + for (pSpr=SpriteArray,i = 0; i < nprims; i++,pSpr++) { // build STL-sortable array - if(alpha) { - pSpr = sorted_vec_iter->pSpr; - sorted_vec_iter++; + if (alpha) { + pSpr = sorted_vec_iter->pSpr; + sorted_vec_iter++; + } + + // if not G_OVERALL, calculate the scale factors //huh?? + if (x_overall == false) + scaled_width = pSpr->_x_ratio * half_width; + + if (y_overall == false) + scaled_height = pSpr->_y_ratio * half_height * aspect_ratio; + + // if not G_OVERALL, do some trig for this z rotate //what is the theta angle?? + if (theta_on) { + if (!theta_overall) + theta = pSpr->_theta; + + // create the rotated points. BUGBUG: this matmult will be slow if we dont get inlining + // rotate_mat calls sin() on an unbounded val, possible to make it faster with lookup table (modulate to 0-360 range?) + LMatrix3f xform_mat = LMatrix3f::rotate_mat(theta) * + LMatrix3f::scale_mat(scaled_width, scaled_height); + + ur = (xform_mat * LVector3f(1, 1, 0)) + pSpr->_v; + ul = (xform_mat * LVector3f(-1, 1, 0)) + pSpr->_v; + lr = (xform_mat * LVector3f(1, -1, 0)) + pSpr->_v; + ll = (xform_mat * LVector3f(-1, -1, 0)) + pSpr->_v; + } else { + // create points for unrotated rect sprites + float x,y,negx,negy,z; + + x = pSpr->_v[0] + scaled_width; + y = pSpr->_v[1] + scaled_height; + negx = pSpr->_v[0] - scaled_width; + negy = pSpr->_v[1] - scaled_height; + z = pSpr->_v[2]; + + ur.set(x, y, z); + ul.set(negx, y, z); + lr.set(x, negy, z); + ll.set(negx, negy, z); + } + + add_to_FVFBuf((void *)ll.get_data(), sizeof(D3DVECTOR)); + if (bDoColor) { + if (!color_overall) // otherwise its already been set globally + CurColor = pSpr->_c; + add_DWORD_to_FVFBuf(CurColor); // only need to cpy color on 1st vert, others are just empty ignored space + } + add_to_FVFBuf((void *)TexCrdSets[0], sizeof(float)*2); + + add_to_FVFBuf((void *)lr.get_data(), sizeof(D3DVECTOR)); + if (bDoColor) + _pCurFvfBufPtr += sizeof(D3DCOLOR); // flat shading, dont need to write color, just incr ptr + add_to_FVFBuf((void *)TexCrdSets[1], sizeof(float)*2); + + add_to_FVFBuf((void *)ul.get_data(), sizeof(D3DVECTOR)); + if (bDoColor) + _pCurFvfBufPtr += sizeof(D3DCOLOR); // flat shading, dont need to write color, just incr ptr + add_to_FVFBuf((void *)TexCrdSets[2], sizeof(float)*2); + + add_to_FVFBuf((void *)ur.get_data(), sizeof(D3DVECTOR)); + if (bDoColor) + add_DWORD_to_FVFBuf(CurColor); + add_to_FVFBuf((void *)TexCrdSets[3], sizeof(float)*2); + + for (int ii=0;ii_x_ratio * half_width; + // cant do tristrip/fan since it would require 1 call want to make 1 call for multiple quads which arent connected + // best we can do is indexed primitive, which sends 2 redundant indices instead of sending 2 redundant full verts + _d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, p_flags, _pFvfBufBasePtr, 4*nprims, _index_buf,QUADVERTLISTLEN*nprims,NULL); - if (y_overall == false) - scaled_height = pSpr->_y_ratio * half_height * aspect_ratio; + _pCurFvfBufPtr = NULL; + delete SpriteArray; - // if not G_OVERALL, do some trig for this z rotate //what is the theta angle?? - if (theta_on) { - if(!theta_overall) - theta = pSpr->_theta; - - // create the rotated points. BUGBUG: this matmult will be slow if we dont get inlining - // rotate_mat calls sin() on an unbounded val, possible to make it faster with lookup table (modulate to 0-360 range?) - LMatrix3f xform_mat = LMatrix3f::rotate_mat(theta) * - LMatrix3f::scale_mat(scaled_width, scaled_height); - - ur = (xform_mat * LVector3f(1, 1, 0)) + pSpr->_v; - ul = (xform_mat * LVector3f(-1, 1, 0)) + pSpr->_v; - lr = (xform_mat * LVector3f(1, -1, 0)) + pSpr->_v; - ll = (xform_mat * LVector3f(-1, -1, 0)) + pSpr->_v; - } else { - // create points for unrotated rect sprites - float x,y,negx,negy,z; - - x = pSpr->_v[0] + scaled_width; - y = pSpr->_v[1] + scaled_height; - negx = pSpr->_v[0] - scaled_width; - negy = pSpr->_v[1] - scaled_height; - z = pSpr->_v[2]; - - ur.set(x, y, z); - ul.set(negx, y, z); - lr.set(x, negy, z); - ll.set(negx, negy, z); - } - - add_to_FVFBuf((void *)ll.get_data(), sizeof(D3DVECTOR)); - if(bDoColor) { - if(!color_overall) // otherwise its already been set globally - CurColor = pSpr->_c; - add_DWORD_to_FVFBuf(CurColor); // only need to cpy color on 1st vert, others are just empty ignored space - } - add_to_FVFBuf((void *)TexCrdSets[0], sizeof(float)*2); - - add_to_FVFBuf((void *)lr.get_data(), sizeof(D3DVECTOR)); - if(bDoColor) - _pCurFvfBufPtr += sizeof(D3DCOLOR); // flat shading, dont need to write color, just incr ptr - add_to_FVFBuf((void *)TexCrdSets[1], sizeof(float)*2); - - add_to_FVFBuf((void *)ul.get_data(), sizeof(D3DVECTOR)); - if(bDoColor) - _pCurFvfBufPtr += sizeof(D3DCOLOR); // flat shading, dont need to write color, just incr ptr - add_to_FVFBuf((void *)TexCrdSets[2], sizeof(float)*2); - - add_to_FVFBuf((void *)ur.get_data(), sizeof(D3DVECTOR)); - if(bDoColor) - add_DWORD_to_FVFBuf(CurColor); - add_to_FVFBuf((void *)TexCrdSets[3], sizeof(float)*2); - - for (int ii=0;iiDrawIndexedPrimitive(D3DPT_TRIANGLELIST, p_flags, _pFvfBufBasePtr, 4*nprims, _index_buf,QUADVERTLISTLEN*nprims,NULL); - - _pCurFvfBufPtr = NULL; - delete SpriteArray; - - // restore the matrices - _d3dDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &OldD3DWorldMatrix); + // restore the matrices + _d3dDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &OldD3DWorldMatrix); } //////////////////////////////////////////////////////////////////// @@ -1644,74 +1630,74 @@ draw_sprite(const GeomSprite *geom) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: draw_polygon(const GeomPolygon *geom) { - activate(); + activate(); #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_polygon()" << endl; + dxgsg_cat.debug() << "draw_polygon()" << endl; #endif /* wireframe polygon will be drawn as multi-tri trifan until I get this casting issue straightened out DWORD rstate; _d3dDevice->GetRenderState(D3DRENDERSTATE_FILLMODE, &rstate); if(rstate!=D3DFILL_WIREFRAME) { - draw_multitri(geom, D3DPT_TRIANGLEFAN); + draw_multitri(geom, D3DPT_TRIANGLEFAN); } else { - Geom *gp=dynamic_cast(geom); doesnt work - draw_linestrip(gp); + Geom *gp=dynamic_cast(geom); doesnt work + draw_linestrip(gp); } */ - draw_multitri(geom, D3DPT_TRIANGLEFAN); + draw_multitri(geom, D3DPT_TRIANGLEFAN); #ifdef WBD_GL_MODE - int nprims = geom->get_num_prims(); - const int *plen = geom->get_lengths(); - Geom::VertexIterator vi = geom->make_vertex_iterator(); - Geom::NormalIterator ni = geom->make_normal_iterator(); - Geom::TexCoordIterator ti = geom->make_texcoord_iterator(); - Geom::ColorIterator ci = geom->make_color_iterator(); + int nprims = geom->get_num_prims(); + const int *plen = geom->get_lengths(); + Geom::VertexIterator vi = geom->make_vertex_iterator(); + Geom::NormalIterator ni = geom->make_normal_iterator(); + Geom::TexCoordIterator ti = geom->make_texcoord_iterator(); + Geom::ColorIterator ci = geom->make_color_iterator(); - GeomIssuer issuer(geom, this, - issue_vertex_gl, - issue_normal_gl, - issue_texcoord_gl, - issue_color_gl); + GeomIssuer issuer(geom, this, + issue_vertex_gl, + issue_normal_gl, + issue_texcoord_gl, + issue_color_gl); - // If we have per-vertex colors or normals, we need smooth shading. - // Otherwise we want flat shading for performance reasons. - if (geom->get_binding(G_COLOR) == G_PER_VERTEX || - geom->get_binding(G_NORMAL) == G_PER_VERTEX) { - call_glShadeModel(GL_SMOOTH); - } else { - call_glShadeModel(GL_FLAT); - } + // If we have per-vertex colors or normals, we need smooth shading. + // Otherwise we want flat shading for performance reasons. + if (geom->get_binding(G_COLOR) == G_PER_VERTEX || + geom->get_binding(G_NORMAL) == G_PER_VERTEX) { + call_glShadeModel(GL_SMOOTH); + } else { + call_glShadeModel(GL_FLAT); + } - // Draw overall - issuer.issue_color(G_OVERALL, ci); - issuer.issue_normal(G_OVERALL, ni); + // Draw overall + issuer.issue_color(G_OVERALL, ci); + issuer.issue_normal(G_OVERALL, ni); - for (int i = 0; i < nprims; i++) { - // Draw per primitive - issuer.issue_color(G_PER_PRIM, ci); - issuer.issue_normal(G_PER_PRIM, ni); + for (int i = 0; i < nprims; i++) { + // Draw per primitive + issuer.issue_color(G_PER_PRIM, ci); + issuer.issue_normal(G_PER_PRIM, ni); - int num_verts = *(plen++); - nassertv(num_verts >= 3); + int num_verts = *(plen++); + nassertv(num_verts >= 3); - glBegin(GL_POLYGON); - - // Draw the vertices. - int v; - for (v = 0; v < num_verts; v++) { - // Per-vertex attributes. - issuer.issue_color(G_PER_VERTEX, ci); - issuer.issue_normal(G_PER_VERTEX, ni); - issuer.issue_texcoord(G_PER_VERTEX, ti); - issuer.issue_vertex(G_PER_VERTEX, vi); - } - glEnd(); - } + glBegin(GL_POLYGON); + + // Draw the vertices. + int v; + for (v = 0; v < num_verts; v++) { + // Per-vertex attributes. + issuer.issue_color(G_PER_VERTEX, ci); + issuer.issue_normal(G_PER_VERTEX, ni); + issuer.issue_texcoord(G_PER_VERTEX, ti); + issuer.issue_vertex(G_PER_VERTEX, vi); + } + glEnd(); + } #endif // WBD_GL_MODE } @@ -1724,55 +1710,54 @@ draw_polygon(const GeomPolygon *geom) { size_t DXGraphicsStateGuardian:: draw_prim_setup(const Geom *geom) { - // Set the flags for the flexible vertex format and compute the bytes - // required to store a single vertex. - p_flags = 0; - size_t vertex_size = 0; + // Set the flags for the flexible vertex format and compute the bytes + // required to store a single vertex. + p_flags = 0; + size_t vertex_size = 0; - if (geom->get_binding(G_COLOR) != G_OFF || _issued_color_enabled) { + if (geom->get_binding(G_COLOR) != G_OFF || _issued_color_enabled) { ci = geom->make_color_iterator(); - p_flags |= D3DFVF_DIFFUSE; + p_flags |= D3DFVF_DIFFUSE; vertex_size += sizeof(D3DCOLOR); - } - if (geom->get_binding(G_COORD) != G_OFF) { - vi = geom->make_vertex_iterator(); - p_flags |= D3DFVF_XYZ; - vertex_size += sizeof(D3DVALUE) * 3; - } - if (geom->get_binding(G_NORMAL) != G_OFF) { - ni = geom->make_normal_iterator(); - p_flags |= D3DFVF_NORMAL; - vertex_size += sizeof(D3DVALUE) * 3; - } - if (geom->get_binding(G_TEXCOORD) != G_OFF) { - ti = geom->make_texcoord_iterator(); - p_flags |= D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0); - vertex_size += sizeof(float) * 2; - } + } + if (geom->get_binding(G_COORD) != G_OFF) { + vi = geom->make_vertex_iterator(); + p_flags |= D3DFVF_XYZ; + vertex_size += sizeof(D3DVALUE) * 3; + } + if (geom->get_binding(G_NORMAL) != G_OFF) { + ni = geom->make_normal_iterator(); + p_flags |= D3DFVF_NORMAL; + vertex_size += sizeof(D3DVALUE) * 3; + } + if (geom->get_binding(G_TEXCOORD) != G_OFF) { + ti = geom->make_texcoord_iterator(); + p_flags |= D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0); + vertex_size += sizeof(float) * 2; + } - if (geom->get_binding(G_COLOR) == G_OVERALL) - { - p_color = geom->get_next_color(ci); // set overall color if there is one - p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); - } + if (geom->get_binding(G_COLOR) == G_OVERALL) { + p_color = geom->get_next_color(ci); // set overall color if there is one + p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); + } - if (geom->get_binding(G_NORMAL) == G_OVERALL) - p_normal = geom->get_next_normal(ni); // set overall normal if there is one + if (geom->get_binding(G_NORMAL) == G_OVERALL) + p_normal = geom->get_next_normal(ni); // set overall normal if there is one - if (_issued_color_enabled) { - p_colr = _issued_color; // set primitive color if there is one. - perVertex &= ~PerColor; - perPrim &= ~PerColor; - perComp &= ~PerColor; - } + if (_issued_color_enabled) { + p_colr = _issued_color; // set primitive color if there is one. + perVertex &= ~PerColor; + perPrim &= ~PerColor; + perComp &= ~PerColor; + } - // If we have per-vertex colors or normals, we need smooth shading. - // Otherwise we want flat shading for performance reasons. - if (perVertex & ((wants_colors() ? PerColor : 0) | (wants_normals() ? PerNormal : 0))) - set_shademode(D3DSHADE_GOURAUD); - else set_shademode(D3DSHADE_FLAT); + // If we have per-vertex colors or normals, we need smooth shading. + // Otherwise we want flat shading for performance reasons. + if (perVertex & ((wants_colors() ? PerColor : 0) | (wants_normals() ? PerNormal : 0))) + set_shademode(D3DSHADE_GOURAUD); + else set_shademode(D3DSHADE_FLAT); - return vertex_size; + return vertex_size; } //////////////////////////////////////////////////////////////////// @@ -1781,68 +1766,66 @@ draw_prim_setup(const Geom *geom) { // Description: This adds data to the flexible vertex format //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: -draw_prim_inner_loop(int loops, const Geom *geom) { +draw_prim_inner_loop(int loops, const Geom *geom) { - while (--loops >= 0) - { - switch(perVertex) - { - case 0x3: - p_normal = geom->get_next_normal(ni); - case 0x1: - p_vertex = geom->get_next_vertex(vi); - break; - case 0x5: - p_vertex = geom->get_next_vertex(vi); - case 0x4: - p_color = geom->get_next_color(ci); - p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); - break; - case 0x7: - p_vertex = geom->get_next_vertex(vi); - case 0x6: - p_color = geom->get_next_color(ci); - p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); - case 0x2: - p_normal = geom->get_next_normal(ni); - break; - case 0x9: - p_vertex = geom->get_next_vertex(vi); - case 0x8: - p_texcoord = geom->get_next_texcoord(ti); - break; - case 0xB: - p_vertex = geom->get_next_vertex(vi); - case 0xA: - p_normal = geom->get_next_normal(ni); - p_texcoord = geom->get_next_texcoord(ti); - break; - case 0xD: - p_vertex = geom->get_next_vertex(vi); - case 0xC: - p_color = geom->get_next_color(ci); - p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); - p_texcoord = geom->get_next_texcoord(ti); - break; - case 0xF: - p_vertex = geom->get_next_vertex(vi); - case 0xE: - p_normal = geom->get_next_normal(ni); - p_color = geom->get_next_color(ci); - p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); - p_texcoord = geom->get_next_texcoord(ti); - break; - } + while (--loops >= 0) { + switch (perVertex) { + case 0x3: + p_normal = geom->get_next_normal(ni); + case 0x1: + p_vertex = geom->get_next_vertex(vi); + break; + case 0x5: + p_vertex = geom->get_next_vertex(vi); + case 0x4: + p_color = geom->get_next_color(ci); + p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); + break; + case 0x7: + p_vertex = geom->get_next_vertex(vi); + case 0x6: + p_color = geom->get_next_color(ci); + p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); + case 0x2: + p_normal = geom->get_next_normal(ni); + break; + case 0x9: + p_vertex = geom->get_next_vertex(vi); + case 0x8: + p_texcoord = geom->get_next_texcoord(ti); + break; + case 0xB: + p_vertex = geom->get_next_vertex(vi); + case 0xA: + p_normal = geom->get_next_normal(ni); + p_texcoord = geom->get_next_texcoord(ti); + break; + case 0xD: + p_vertex = geom->get_next_vertex(vi); + case 0xC: + p_color = geom->get_next_color(ci); + p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); + p_texcoord = geom->get_next_texcoord(ti); + break; + case 0xF: + p_vertex = geom->get_next_vertex(vi); + case 0xE: + p_normal = geom->get_next_normal(ni); + p_color = geom->get_next_color(ci); + p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); + p_texcoord = geom->get_next_texcoord(ti); + break; + } - add_to_FVFBuf((void *)&p_vertex, sizeof(D3DVECTOR)); + add_to_FVFBuf((void *)&p_vertex, sizeof(D3DVECTOR)); - if (p_flags & D3DFVF_NORMAL) - add_to_FVFBuf((void *)&p_normal, sizeof(D3DVECTOR)); - if (p_flags & D3DFVF_DIFFUSE) - add_DWORD_to_FVFBuf(p_colr); - if (p_flags & D3DFVF_TEXCOUNT_MASK) - add_to_FVFBuf((void *)&p_texcoord, sizeof(TexCoordf)); - } + if (p_flags & D3DFVF_NORMAL) + add_to_FVFBuf((void *)&p_normal, sizeof(D3DVECTOR)); + if (p_flags & D3DFVF_DIFFUSE) + add_DWORD_to_FVFBuf(p_colr); + if (p_flags & D3DFVF_TEXCOUNT_MASK) + add_to_FVFBuf((void *)&p_texcoord, sizeof(TexCoordf)); + } } //////////////////////////////////////////////////////////////////// @@ -1867,52 +1850,52 @@ draw_prim_inner_loop2(int loops, const Geom *geom, short& per ) { #define GET_NEXT_TEXCOORD() { \ p_texcoord = geom->get_next_texcoord(ti); } - while (--loops >= 0) { + while (--loops >= 0) { - GET_NEXT_VERTEX(); // coord info will always be perVertex + GET_NEXT_VERTEX(); // coord info will always be perVertex - switch(perVertex | (DWORD)per) { - case 0x3: - GET_NEXT_NORMAL(); - case 0x1: - break; - case 0x5: - case 0x4: - GET_NEXT_COLOR(); - break; - case 0x7: - case 0x6: - GET_NEXT_COLOR(); - case 0x2: - GET_NEXT_NORMAL(); - break; - case 0x9: - case 0x8: + switch (perVertex | (DWORD)per) { + case 0x3: + GET_NEXT_NORMAL(); + case 0x1: + break; + case 0x5: + case 0x4: + GET_NEXT_COLOR(); + break; + case 0x7: + case 0x6: + GET_NEXT_COLOR(); + case 0x2: + GET_NEXT_NORMAL(); + break; + case 0x9: + case 0x8: GET_NEXT_TEXCOORD(); - break; - case 0xB: - case 0xA: - GET_NEXT_NORMAL(); + break; + case 0xB: + case 0xA: + GET_NEXT_NORMAL(); GET_NEXT_TEXCOORD(); - break; - case 0xD: - case 0xC: - GET_NEXT_COLOR(); + break; + case 0xD: + case 0xC: + GET_NEXT_COLOR(); GET_NEXT_TEXCOORD(); - break; - case 0xF: - case 0xE: - GET_NEXT_NORMAL(); - GET_NEXT_COLOR(); + break; + case 0xF: + case 0xE: + GET_NEXT_NORMAL(); + GET_NEXT_COLOR(); GET_NEXT_TEXCOORD(); - break; - } + break; + } - add_to_FVFBuf((void *)&p_vertex, sizeof(D3DVECTOR)); + add_to_FVFBuf((void *)&p_vertex, sizeof(D3DVECTOR)); - if (p_flags & D3DFVF_NORMAL) - add_to_FVFBuf((void *)&p_normal, sizeof(D3DVECTOR)); - if (p_flags & D3DFVF_DIFFUSE) + if (p_flags & D3DFVF_NORMAL) + add_to_FVFBuf((void *)&p_normal, sizeof(D3DVECTOR)); + if (p_flags & D3DFVF_DIFFUSE) add_DWORD_to_FVFBuf(p_colr); if (p_flags & D3DFVF_TEXCOUNT_MASK) add_to_FVFBuf((void *)&p_texcoord, sizeof(TexCoordf)); @@ -1926,265 +1909,264 @@ draw_prim_inner_loop2(int loops, const Geom *geom, short& per ) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: draw_tri(const GeomTri *geom) { - // activate(); + // activate(); #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_tri()" << endl; + dxgsg_cat.debug() << "draw_tri()" << endl; #endif #ifdef _DEBUG - if(_pCurTexContext!=NULL) { + if (_pCurTexContext!=NULL) { // dxgsg_cat.spam() << "Cur active DX texture: " << _pCurTexContext->_tex->get_name() << "\n"; - } + } #endif - int nPrims = geom->get_num_prims(); - HRESULT hr; + int nPrims = geom->get_num_prims(); + HRESULT hr; - PTA_Vertexf coords; - PTA_Normalf norms; - PTA_Colorf colors; - PTA_TexCoordf texcoords; - GeomBindType TexCoordBinding,ColorBinding,NormalBinding,junk1; - PTA_ushort vindexes,nindexes,tindexes,cindexes; - - geom->get_coords(coords,junk1,vindexes); - geom->get_normals(norms,NormalBinding,nindexes); - geom->get_colors(colors,ColorBinding,cindexes); - geom->get_texcoords(texcoords,TexCoordBinding,tindexes); + PTA_Vertexf coords; + PTA_Normalf norms; + PTA_Colorf colors; + PTA_TexCoordf texcoords; + GeomBindType TexCoordBinding,ColorBinding,NormalBinding,junk1; + PTA_ushort vindexes,nindexes,tindexes,cindexes; - GeomVertFormat GeomVrtFmt=FlatVerts; + geom->get_coords(coords,junk1,vindexes); + geom->get_normals(norms,NormalBinding,nindexes); + geom->get_colors(colors,ColorBinding,cindexes); + geom->get_texcoords(texcoords,TexCoordBinding,tindexes); - // first determine if we're indexed or non-indexed + GeomVertFormat GeomVrtFmt=FlatVerts; - if((vindexes!=NULL)&&(cindexes!=NULL)&&(tindexes!=NULL)&&(nindexes!=NULL)) { - GeomVrtFmt=IndexedVerts; - //make sure array sizes are consistent, we can only pass 1 size to DrawIPrm + // first determine if we're indexed or non-indexed + + if ((vindexes!=NULL)&&(cindexes!=NULL)&&(tindexes!=NULL)&&(nindexes!=NULL)) { + GeomVrtFmt=IndexedVerts; + //make sure array sizes are consistent, we can only pass 1 size to DrawIPrm // nassertv(coords.size==norms.size); nassertv(coords.size==colors.size); nassertv(coords.size==texcoords.size); need to assert only if we have this w/same binding - // indexed mode requires all used norms,colors,texcoords,coords array be the same - // length, or 0 or 1 (dwStride==0), also requires all elements to use the same index array - } else if(!((vindexes==NULL)&&(cindexes==NULL)&&(tindexes==NULL)&&(nindexes==NULL))) - GeomVrtFmt=MixedFmtVerts; + // indexed mode requires all used norms,colors,texcoords,coords array be the same + // length, or 0 or 1 (dwStride==0), also requires all elements to use the same index array + } else if (!((vindexes==NULL)&&(cindexes==NULL)&&(tindexes==NULL)&&(nindexes==NULL))) + GeomVrtFmt=MixedFmtVerts; #ifdef DONT_USE_DRAWPRIMSTRIDED - GeomVrtFmt=MixedFmtVerts; + GeomVrtFmt=MixedFmtVerts; #endif - // for Indexed Prims and mixed indexed/non-indexed prims, we will use old pipeline for now - // need to add code to handle fully indexed mode (and handle cases with index arrays of different lengths, - // values (may only be possible to handle certain cases without reverting to old pipeline) - if(GeomVrtFmt!=FlatVerts) { - // this is the old geom setup, it reformats every vtx into an output array passed to d3d - - perVertex = PerCoord; - - if(NormalBinding == G_PER_VERTEX) perVertex |= PerNormal; - if(ColorBinding == G_PER_VERTEX) perVertex |= PerColor; - if(TexCoordBinding == G_PER_VERTEX) perVertex |= PerTexcoord; - - perPrim = 0; - if (NormalBinding == G_PER_PRIM) perPrim |= PerNormal; - if (ColorBinding == G_PER_PRIM) perPrim |= PerColor; - - size_t vertex_size = draw_prim_setup(geom); - - nassertv(_pCurFvfBufPtr == NULL); // make sure the storage pointer is clean. - nassertv(nPrims * 3 * vertex_size < VERT_BUFFER_SIZE); - _pCurFvfBufPtr = _pFvfBufBasePtr; // _pCurFvfBufPtr changes, _pFvfBufBasePtr doesn't - - // iterate through the triangle primitive - - for (int i = 0; i < nPrims; i++) { - if (perPrim & PerColor) - { - p_color = geom->get_next_color(ci); // set primitive color if there is one. - p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); + // for Indexed Prims and mixed indexed/non-indexed prims, we will use old pipeline for now + // need to add code to handle fully indexed mode (and handle cases with index arrays of different lengths, + // values (may only be possible to handle certain cases without reverting to old pipeline) + if (GeomVrtFmt!=FlatVerts) { + // this is the old geom setup, it reformats every vtx into an output array passed to d3d + + perVertex = PerCoord; + + if (NormalBinding == G_PER_VERTEX) perVertex |= PerNormal; + if (ColorBinding == G_PER_VERTEX) perVertex |= PerColor; + if (TexCoordBinding == G_PER_VERTEX) perVertex |= PerTexcoord; + + perPrim = 0; + if (NormalBinding == G_PER_PRIM) perPrim |= PerNormal; + if (ColorBinding == G_PER_PRIM) perPrim |= PerColor; + + size_t vertex_size = draw_prim_setup(geom); + + nassertv(_pCurFvfBufPtr == NULL); // make sure the storage pointer is clean. + nassertv(nPrims * 3 * vertex_size < VERT_BUFFER_SIZE); + _pCurFvfBufPtr = _pFvfBufBasePtr; // _pCurFvfBufPtr changes, _pFvfBufBasePtr doesn't + + // iterate through the triangle primitive + + for (int i = 0; i < nPrims; i++) { + if (perPrim & PerColor) { + p_color = geom->get_next_color(ci); // set primitive color if there is one. + p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); } - - if (perPrim & PerNormal) - p_normal = geom->get_next_normal(ni); // set primitive normal if there is one. - - draw_prim_inner_loop(3, geom); - } - - hr = _d3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, p_flags, _pFvfBufBasePtr, nPrims*3, NULL); - _pCurFvfBufPtr = NULL; - } else { + if (perPrim & PerNormal) + p_normal = geom->get_next_normal(ni); // set primitive normal if there is one. - // new geom setup that uses strided DP calls to avoid making an extra pass over the data + draw_prim_inner_loop(3, geom); + } + + hr = _d3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, p_flags, _pFvfBufBasePtr, nPrims*3, NULL); + + _pCurFvfBufPtr = NULL; + } else { + + // new geom setup that uses strided DP calls to avoid making an extra pass over the data + + D3DDRAWPRIMITIVESTRIDEDDATA dps_data; + memset(&dps_data,0,sizeof(D3DDRAWPRIMITIVESTRIDEDDATA)); - D3DDRAWPRIMITIVESTRIDEDDATA dps_data; - memset(&dps_data,0,sizeof(D3DDRAWPRIMITIVESTRIDEDDATA)); - #ifdef _DEBUG - nassertv(!geom->uses_components()); // code ignores lengths array - nassertv(geom->get_binding(G_COORD) == G_PER_VERTEX); + nassertv(!geom->uses_components()); // code ignores lengths array + nassertv(geom->get_binding(G_COORD) == G_PER_VERTEX); #endif - D3DPRIMITIVETYPE primtype=D3DPT_TRIANGLELIST; - - DWORD fvf_flags = D3DFVF_XYZ; - dps_data.position.lpvData = (VOID*)coords; - dps_data.position.dwStride = sizeof(D3DVECTOR); + D3DPRIMITIVETYPE primtype=D3DPT_TRIANGLELIST; - D3DSHADEMODE NeededShadeMode = D3DSHADE_FLAT; + DWORD fvf_flags = D3DFVF_XYZ; + dps_data.position.lpvData = (VOID*)coords; + dps_data.position.dwStride = sizeof(D3DVECTOR); - DWORD dwVertsPerPrim=geom->get_num_vertices_per_prim(); + D3DSHADEMODE NeededShadeMode = D3DSHADE_FLAT; - if((NormalBinding != G_OFF) && wants_normals()) { + DWORD dwVertsPerPrim=geom->get_num_vertices_per_prim(); - dps_data.normal.lpvData = (VOID*)norms; - dps_data.normal.dwStride = sizeof(D3DVECTOR); + if ((NormalBinding != G_OFF) && wants_normals()) { - #ifdef _DEBUG - nassertv( nPrims*dwVertsPerPrim*sizeof(D3DVECTOR) <= D3DMAXNUMVERTICES*sizeof(WORD)); - if(NormalBinding==G_PER_VERTEX) - nassertv(norms.size()>=nPrims*dwVertsPerPrim); - #endif + dps_data.normal.lpvData = (VOID*)norms; + dps_data.normal.dwStride = sizeof(D3DVECTOR); - fvf_flags |= D3DFVF_NORMAL; +#ifdef _DEBUG + nassertv( nPrims*dwVertsPerPrim*sizeof(D3DVECTOR) <= D3DMAXNUMVERTICES*sizeof(WORD)); + if (NormalBinding==G_PER_VERTEX) + nassertv(norms.size()>=nPrims*dwVertsPerPrim); +#endif - NeededShadeMode = D3DSHADE_GOURAUD; + fvf_flags |= D3DFVF_NORMAL; - Normalf *pExpandedNormalArray = (Normalf *)_index_buf; // BUGBUG: need to use real permanent buffers for this conversion - if(NormalBinding==G_PER_PRIM) { - // must use tmp array to duplicate-expand per-prim norms to per-vert norms - Normalf *pOutVec = pExpandedNormalArray; - Normalf *pInVec=norms; + NeededShadeMode = D3DSHADE_GOURAUD; - nassertv(norms.size()>=nPrims); + Normalf *pExpandedNormalArray = (Normalf *)_index_buf; // BUGBUG: need to use real permanent buffers for this conversion + if (NormalBinding==G_PER_PRIM) { + // must use tmp array to duplicate-expand per-prim norms to per-vert norms + Normalf *pOutVec = pExpandedNormalArray; + Normalf *pInVec=norms; - for(int i=0;i=nPrims); - dps_data.normal.lpvData = (VOID*)pExpandedNormalArray; + for (int i=0;iis_off()) { - if(!catt->is_real()) - bDoColor=FALSE; // this turns off any Geom colors - else { - ColorBinding=G_OVERALL; - bDoGlobalSceneGraphColor=TRUE; - } - } + ColorAttribute *catt=NULL; + bool bDoGlobalSceneGraphColor=FALSE,bDoColor=(ColorBinding != G_OFF); - if(bDoColor || bDoGlobalSceneGraphColor) { - D3DCOLOR *pOutColor,*pConvertedColorArray; - Colorf *pInColor=colors; - pOutColor = pConvertedColorArray = (D3DCOLOR *)_pFvfBufBasePtr; + // We should issue geometry colors only if the scene graph color is off. + if (get_attribute_into(catt, _state, ColorTransition::get_class_type()) && !catt->is_off()) { + if (!catt->is_real()) + bDoColor=FALSE; // this turns off any Geom colors + else { + ColorBinding=G_OVERALL; + bDoGlobalSceneGraphColor=TRUE; + } + } - #ifdef _DEBUG - nassertv( nPrims*dwVertsPerPrim*sizeof(D3DCOLOR) <= VERT_BUFFER_SIZE); - #endif + if (bDoColor || bDoGlobalSceneGraphColor) { + D3DCOLOR *pOutColor,*pConvertedColorArray; + Colorf *pInColor=colors; + pOutColor = pConvertedColorArray = (D3DCOLOR *)_pFvfBufBasePtr; - fvf_flags |= D3DFVF_DIFFUSE; +#ifdef _DEBUG + nassertv( nPrims*dwVertsPerPrim*sizeof(D3DCOLOR) <= VERT_BUFFER_SIZE); +#endif - dps_data.diffuse.lpvData = (VOID*)pConvertedColorArray; - dps_data.diffuse.dwStride = sizeof(D3DCOLOR); + fvf_flags |= D3DFVF_DIFFUSE; - if(ColorBinding==G_PER_PRIM) { - // must use tmp array to expand per-prim info to per-vert info + dps_data.diffuse.lpvData = (VOID*)pConvertedColorArray; + dps_data.diffuse.dwStride = sizeof(D3DCOLOR); - // eventually want to do this conversion once in retained mode - if(NeededShadeMode!=D3DSHADE_FLAT) { - D3DCOLOR newcolr; - // but if lighting enabled, we need to color every vert since shading will be GOURAUD - for(int i=0;iget_color(); - *pConvertedColorArray=D3DRGBA(colr[0],colr[1],colr[2],colr[3]); - } else { - *pConvertedColorArray=D3DRGBA((*pInColor)[0],(*pInColor)[1],(*pInColor)[2],(*pInColor)[3]); - } + // copy the one global color in, set stride to 0 - dps_data.diffuse.dwStride = 0; - } - } + if (bDoGlobalSceneGraphColor) { + Colorf colr = catt->get_color(); + *pConvertedColorArray=D3DRGBA(colr[0],colr[1],colr[2],colr[3]); + } else { + *pConvertedColorArray=D3DRGBA((*pInColor)[0],(*pInColor)[1],(*pInColor)[2],(*pInColor)[3]); + } - if((TexCoordBinding != G_OFF) && _texturing_enabled) { + dps_data.diffuse.dwStride = 0; + } + } - #ifdef _DEBUG - nassertv(TexCoordBinding == G_PER_VERTEX); // only sensible choice for a tri - #endif + if ((TexCoordBinding != G_OFF) && _texturing_enabled) { - dps_data.textureCoords[0].lpvData = (VOID*)texcoords; - dps_data.textureCoords[0].dwStride = sizeof(TexCoordf); - fvf_flags |= (D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0)); - } +#ifdef _DEBUG + nassertv(TexCoordBinding == G_PER_VERTEX); // only sensible choice for a tri +#endif - set_shademode(NeededShadeMode); + dps_data.textureCoords[0].lpvData = (VOID*)texcoords; + dps_data.textureCoords[0].dwStride = sizeof(TexCoordf); + fvf_flags |= (D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0)); + } - hr = _d3dDevice->DrawPrimitiveStrided(primtype, fvf_flags, &dps_data, nPrims*dwVertsPerPrim, NULL); + set_shademode(NeededShadeMode); - if(FAILED(hr)) { - dxgsg_cat.fatal() << "DrawPrimStrided failed: result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } + hr = _d3dDevice->DrawPrimitiveStrided(primtype, fvf_flags, &dps_data, nPrims*dwVertsPerPrim, NULL); - _pCurFvfBufPtr = NULL; - } + if (FAILED(hr)) { + dxgsg_cat.fatal() << "DrawPrimStrided failed: result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + _pCurFvfBufPtr = NULL; + } /////////////////////////// #if 0 - // test triangle for me to dbg experiments only - float vert_buf[15] = { - 0.0, 0.0, 0.0, 0.0, 0.0, - 33.0, 0.0, 0.0, 0.0, 2.0, - 0.0, 0.0, 33.0, 2.0, 0.0 - }; + // test triangle for me to dbg experiments only + float vert_buf[15] = { + 0.0, 0.0, 0.0, 0.0, 0.0, + 33.0, 0.0, 0.0, 0.0, 2.0, + 0.0, 0.0, 33.0, 2.0, 0.0 + }; - _d3dDevice->SetTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_BORDER); - _d3dDevice->SetTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_BORDER); - _d3dDevice->SetTextureStageState(0,D3DTSS_BORDERCOLOR,D3DRGBA(0,0,0,0)); + _d3dDevice->SetTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_BORDER); + _d3dDevice->SetTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_BORDER); + _d3dDevice->SetTextureStageState(0,D3DTSS_BORDERCOLOR,D3DRGBA(0,0,0,0)); - p_flags = D3DFVF_XYZ | (D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0)) ; - _d3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, p_flags, vert_buf, nPrims*3, NULL); + p_flags = D3DFVF_XYZ | (D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0)) ; + _d3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, p_flags, vert_buf, nPrims*3, NULL); #endif } @@ -2195,64 +2177,64 @@ draw_tri(const GeomTri *geom) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: draw_quad(const GeomQuad *geom) { - activate(); + activate(); #if 1 - static BOOL bPrintedMsg=FALSE; + static BOOL bPrintedMsg=FALSE; - if(!bPrintedMsg) { - bPrintedMsg=TRUE; - dxgsg_cat.error() << "dxgsg draw_quad drawing not implemented yet!\n"; - } + if (!bPrintedMsg) { + bPrintedMsg=TRUE; + dxgsg_cat.error() << "dxgsg draw_quad drawing not implemented yet!\n"; + } #endif #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_quad()" << endl; + dxgsg_cat.debug() << "draw_quad()" << endl; #endif #ifdef WBD_GL_MODE - int nprims = geom->get_num_prims(); - Geom::VertexIterator vi = geom->make_vertex_iterator(); - Geom::NormalIterator ni = geom->make_normal_iterator(); - Geom::TexCoordIterator ti = geom->make_texcoord_iterator(); - Geom::ColorIterator ci = geom->make_color_iterator(); + int nprims = geom->get_num_prims(); + Geom::VertexIterator vi = geom->make_vertex_iterator(); + Geom::NormalIterator ni = geom->make_normal_iterator(); + Geom::TexCoordIterator ti = geom->make_texcoord_iterator(); + Geom::ColorIterator ci = geom->make_color_iterator(); - GeomIssuer issuer(geom, this, - issue_vertex_gl, - issue_normal_gl, - issue_texcoord_gl, - issue_color_gl); + GeomIssuer issuer(geom, this, + issue_vertex_gl, + issue_normal_gl, + issue_texcoord_gl, + issue_color_gl); - // If we have per-vertex colors or normals, we need smooth shading. - // Otherwise we want flat shading for performance reasons. - if (geom->get_binding(G_COLOR) == G_PER_VERTEX || - geom->get_binding(G_NORMAL) == G_PER_VERTEX) { - call_glShadeModel(GL_SMOOTH); - } else { - call_glShadeModel(GL_FLAT); - } + // If we have per-vertex colors or normals, we need smooth shading. + // Otherwise we want flat shading for performance reasons. + if (geom->get_binding(G_COLOR) == G_PER_VERTEX || + geom->get_binding(G_NORMAL) == G_PER_VERTEX) { + call_glShadeModel(GL_SMOOTH); + } else { + call_glShadeModel(GL_FLAT); + } - // Draw overall - issuer.issue_color(G_OVERALL, ci); - issuer.issue_normal(G_OVERALL, ni); - - glBegin(GL_QUADS); - - for (int i = 0; i < nprims; i++) { - // Draw per primitive - issuer.issue_color(G_PER_PRIM, ci); - issuer.issue_normal(G_PER_PRIM, ni); - - for (int j = 0; j < 4; j++) { - // Draw per vertex - issuer.issue_color(G_PER_VERTEX, ci); - issuer.issue_normal(G_PER_VERTEX, ni); - issuer.issue_texcoord(G_PER_VERTEX, ti); - issuer.issue_vertex(G_PER_VERTEX, vi); - } - } + // Draw overall + issuer.issue_color(G_OVERALL, ci); + issuer.issue_normal(G_OVERALL, ni); - glEnd(); + glBegin(GL_QUADS); + + for (int i = 0; i < nprims; i++) { + // Draw per primitive + issuer.issue_color(G_PER_PRIM, ci); + issuer.issue_normal(G_PER_PRIM, ni); + + for (int j = 0; j < 4; j++) { + // Draw per vertex + issuer.issue_color(G_PER_VERTEX, ci); + issuer.issue_normal(G_PER_VERTEX, ni); + issuer.issue_texcoord(G_PER_VERTEX, ti); + issuer.issue_vertex(G_PER_VERTEX, vi); + } + } + + glEnd(); #endif // WBD_GL_MODE } @@ -2266,10 +2248,10 @@ draw_tristrip(const GeomTristrip *geom) { // activate(); #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_tristrip()" << endl; + dxgsg_cat.debug() << "draw_tristrip()" << endl; #endif - draw_multitri(geom, D3DPT_TRIANGLESTRIP); + draw_multitri(geom, D3DPT_TRIANGLESTRIP); } //////////////////////////////////////////////////////////////////// @@ -2282,10 +2264,10 @@ draw_trifan(const GeomTrifan *geom) { // activate(); #ifdef GSG_VERBOSE - dxgsg_cat.debug() << "draw_trifan()" << endl; + dxgsg_cat.debug() << "draw_trifan()" << endl; #endif - draw_multitri(geom, D3DPT_TRIANGLEFAN); + draw_multitri(geom, D3DPT_TRIANGLEFAN); } //////////////////////////////////////////////////////////////////// @@ -2297,12 +2279,12 @@ void DXGraphicsStateGuardian:: draw_multitri(const Geom *geom, D3DPRIMITIVETYPE trilisttype) { int nPrims = geom->get_num_prims(); - const int *pLengthArr = geom->get_lengths(); + const int *pLengthArr = geom->get_lengths(); HRESULT hr; - - if(nPrims==0) { - dxgsg_cat.warning() << "draw_multitri() called with ZERO vertices!!" << endl; - return; + + if (nPrims==0) { + dxgsg_cat.warning() << "draw_multitri() called with ZERO vertices!!" << endl; + return; } PTA_Vertexf coords; @@ -2311,317 +2293,315 @@ draw_multitri(const Geom *geom, D3DPRIMITIVETYPE trilisttype) { PTA_TexCoordf texcoords; GeomBindType TexCoordBinding,ColorBinding,NormalBinding,junk1; PTA_ushort vindexes,nindexes,tindexes,cindexes; - + geom->get_coords(coords,junk1,vindexes); geom->get_normals(norms,NormalBinding,nindexes); geom->get_colors(colors,ColorBinding,cindexes); geom->get_texcoords(texcoords,TexCoordBinding,tindexes); GeomVertFormat GeomVrtFmt=FlatVerts; - + // first determine if we're indexed or non-indexed - - if((vindexes!=NULL)&&(cindexes!=NULL)&&(tindexes!=NULL)&&(nindexes!=NULL)) { + + if ((vindexes!=NULL)&&(cindexes!=NULL)&&(tindexes!=NULL)&&(nindexes!=NULL)) { GeomVrtFmt=IndexedVerts; //make sure array sizes are consistent, we can only pass 1 size to DrawIPrm - // nassertv(coords.size==norms.size); nassertv(coords.size==colors.size); nassertv(coords.size==texcoords.size); need to assert only if we have this w/same binding - // indexed mode requires all used norms,colors,texcoords,coords array be the same - // length, or 0 or 1 (dwStride==0), also requires all elements to use the same index array - } else if(!((vindexes==NULL)&&(cindexes==NULL)&&(tindexes==NULL)&&(nindexes==NULL))) - GeomVrtFmt=MixedFmtVerts; + // nassertv(coords.size==norms.size); nassertv(coords.size==colors.size); nassertv(coords.size==texcoords.size); need to assert only if we have this w/same binding + // indexed mode requires all used norms,colors,texcoords,coords array be the same + // length, or 0 or 1 (dwStride==0), also requires all elements to use the same index array + } else if (!((vindexes==NULL)&&(cindexes==NULL)&&(tindexes==NULL)&&(nindexes==NULL))) + GeomVrtFmt=MixedFmtVerts; #ifdef DONT_USE_DRAWPRIMSTRIDED - GeomVrtFmt=MixedFmtVerts; + GeomVrtFmt=MixedFmtVerts; #endif - + // for Indexed Prims and mixed indexed/non-indexed prims, we will use old pipeline // cant handle indexed prims because usually have different index arrays for different components, // and DrIdxPrmStrd only accepts 1 index array for all components - if(GeomVrtFmt!=FlatVerts) { + if (GeomVrtFmt!=FlatVerts) { - // this is the old geom setup, it reformats every vtx into an output array passed to d3d - perVertex = PerCoord; - perPrim = perComp = 0; + // this is the old geom setup, it reformats every vtx into an output array passed to d3d + perVertex = PerCoord; + perPrim = perComp = 0; - switch(geom->get_binding(G_NORMAL)) { - case G_PER_VERTEX: - perVertex |= PerNormal; - break; - case G_PER_PRIM: - perPrim |= PerNormal; - break; - case G_PER_COMPONENT: - perComp |= PerNormal; - break; - } + switch (geom->get_binding(G_NORMAL)) { + case G_PER_VERTEX: + perVertex |= PerNormal; + break; + case G_PER_PRIM: + perPrim |= PerNormal; + break; + case G_PER_COMPONENT: + perComp |= PerNormal; + break; + } - switch(geom->get_binding(G_COLOR)) { - case G_PER_VERTEX: - perVertex |= PerColor; - break; - case G_PER_PRIM: - perPrim |= PerColor; - break; - case G_PER_COMPONENT: - perComp |= PerColor; - break; - } - - if (geom->get_binding(G_TEXCOORD) == G_PER_VERTEX) - perVertex |= PerTexcoord; - - size_t vertex_size = draw_prim_setup(geom); - - // iterate through the triangle primitives - - for (int i = 0; i < nPrims; i++) { - - if (perPrim & PerColor) - { - p_color = geom->get_next_color(ci); // set primitive color if there is one. - p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); + switch (geom->get_binding(G_COLOR)) { + case G_PER_VERTEX: + perVertex |= PerColor; + break; + case G_PER_PRIM: + perPrim |= PerColor; + break; + case G_PER_COMPONENT: + perComp |= PerColor; + break; + } + + if (geom->get_binding(G_TEXCOORD) == G_PER_VERTEX) + perVertex |= PerTexcoord; + + size_t vertex_size = draw_prim_setup(geom); + + // iterate through the triangle primitives + + for (int i = 0; i < nPrims; i++) { + + if (perPrim & PerColor) { + p_color = geom->get_next_color(ci); // set primitive color if there is one. + p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); } - - if (perPrim & PerNormal) - p_normal = geom->get_next_normal(ni); // set primitive normal if there is one. - - int nVerts = *(pLengthArr++); - nassertv(nVerts >= 3); - - nassertv(_pCurFvfBufPtr == NULL); // make sure the storage pointer is clean. - nassertv(nVerts * vertex_size < VERT_BUFFER_SIZE); - _pCurFvfBufPtr = _pFvfBufBasePtr; // _pCurFvfBufPtr changes, _pFvfBufBasePtr doesn't - - if (perComp & PerColor) - { - p_color = geom->get_next_color(ci); // set overall color if there is one - p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); - } - if (perComp & PerNormal) - p_normal = geom->get_next_normal(ni); // set primitive normal if there is one. - - // Store first triangle - draw_prim_inner_loop(3, geom); - - // Store remaining vertices - draw_prim_inner_loop2(nVerts-3, geom, perComp); - - _d3dDevice->DrawPrimitive(trilisttype, p_flags, _pFvfBufBasePtr, nVerts, NULL); - - _pCurFvfBufPtr = NULL; - } + + if (perPrim & PerNormal) + p_normal = geom->get_next_normal(ni); // set primitive normal if there is one. + + int nVerts = *(pLengthArr++); + nassertv(nVerts >= 3); + + nassertv(_pCurFvfBufPtr == NULL); // make sure the storage pointer is clean. + nassertv(nVerts * vertex_size < VERT_BUFFER_SIZE); + _pCurFvfBufPtr = _pFvfBufBasePtr; // _pCurFvfBufPtr changes, _pFvfBufBasePtr doesn't + + if (perComp & PerColor) { + p_color = geom->get_next_color(ci); // set overall color if there is one + p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); + } + if (perComp & PerNormal) + p_normal = geom->get_next_normal(ni); // set primitive normal if there is one. + + // Store first triangle + draw_prim_inner_loop(3, geom); + + // Store remaining vertices + draw_prim_inner_loop2(nVerts-3, geom, perComp); + + _d3dDevice->DrawPrimitive(trilisttype, p_flags, _pFvfBufBasePtr, nVerts, NULL); + + _pCurFvfBufPtr = NULL; + } } else { - // new geom setup that uses strided DP calls to avoid making an extra pass over the data + // new geom setup that uses strided DP calls to avoid making an extra pass over the data + + D3DDRAWPRIMITIVESTRIDEDDATA dps_data; + memset(&dps_data,0,sizeof(D3DDRAWPRIMITIVESTRIDEDDATA)); - D3DDRAWPRIMITIVESTRIDEDDATA dps_data; - memset(&dps_data,0,sizeof(D3DDRAWPRIMITIVESTRIDEDDATA)); - #ifdef _DEBUG - nassertv(geom->uses_components()); - nassertv(geom->get_binding(G_COORD) == G_PER_VERTEX); + nassertv(geom->uses_components()); + nassertv(geom->get_binding(G_COORD) == G_PER_VERTEX); #endif - DWORD fvf_flags = D3DFVF_XYZ; - dps_data.position.lpvData = (VOID*)coords; - dps_data.position.dwStride = sizeof(D3DVECTOR); + DWORD fvf_flags = D3DFVF_XYZ; + dps_data.position.lpvData = (VOID*)coords; + dps_data.position.dwStride = sizeof(D3DVECTOR); - D3DSHADEMODE NeededShadeMode = D3DSHADE_FLAT; + D3DSHADEMODE NeededShadeMode = D3DSHADE_FLAT; - DWORD cTotalVerts=0; + DWORD cTotalVerts=0; - for(int i=0;iget_num_more_vertices_than_components(); + DWORD cNumMoreVertsthanTris=geom->get_num_more_vertices_than_components(); - if((NormalBinding != G_OFF) && wants_normals()) { + if ((NormalBinding != G_OFF) && wants_normals()) { - dps_data.normal.lpvData = (VOID*)norms; - dps_data.normal.dwStride = sizeof(D3DVECTOR); + dps_data.normal.lpvData = (VOID*)norms; + dps_data.normal.dwStride = sizeof(D3DVECTOR); - #ifdef _DEBUG - nassertv(NormalBinding!=G_PER_COMPONENT); // makes no sense, unimplementable for strips since normals always shared across tris - nassertv( cTotalVerts*sizeof(D3DVECTOR) <= D3DMAXNUMVERTICES*sizeof(WORD)); - if(NormalBinding==G_PER_VERTEX) - nassertv(norms.size()>=cTotalVerts); - #endif +#ifdef _DEBUG + nassertv(NormalBinding!=G_PER_COMPONENT); // makes no sense, unimplementable for strips since normals always shared across tris + nassertv( cTotalVerts*sizeof(D3DVECTOR) <= D3DMAXNUMVERTICES*sizeof(WORD)); + if (NormalBinding==G_PER_VERTEX) + nassertv(norms.size()>=cTotalVerts); +#endif - fvf_flags |= D3DFVF_NORMAL; + fvf_flags |= D3DFVF_NORMAL; - NeededShadeMode = D3DSHADE_GOURAUD; + NeededShadeMode = D3DSHADE_GOURAUD; - Normalf *pExpandedNormalArray = (Normalf *)_index_buf; // BUGBUG: need to use real permanent buffers for this conversion + Normalf *pExpandedNormalArray = (Normalf *)_index_buf; // BUGBUG: need to use real permanent buffers for this conversion - if(NormalBinding==G_PER_PRIM) { - // we have 1 normal per strip - // must use tmp array to duplicate-expand per-prim norms to per-vert norms - Normalf *pOutVec = pExpandedNormalArray; - Normalf *pInVec=norms; - const int *pLengths=pLengthArr; + if (NormalBinding==G_PER_PRIM) { + // we have 1 normal per strip + // must use tmp array to duplicate-expand per-prim norms to per-vert norms + Normalf *pOutVec = pExpandedNormalArray; + Normalf *pInVec=norms; + const int *pLengths=pLengthArr; - nassertv(norms.size()>=nPrims); + nassertv(norms.size()>=nPrims); - for(int i=0;iis_off()) { - if(!catt->is_real()) - bDoColor=FALSE; // this turns off any Geom colors - else { - ColorBinding=G_OVERALL; - bDoGlobalSceneGraphColor=TRUE; - } - } + // We should issue geometry colors only if the scene graph color is off. + if (get_attribute_into(catt, _state, ColorTransition::get_class_type()) && !catt->is_off()) { + if (!catt->is_real()) + bDoColor=FALSE; // this turns off any Geom colors + else { + ColorBinding=G_OVERALL; + bDoGlobalSceneGraphColor=TRUE; + } + } - if(bDoColor || bDoGlobalSceneGraphColor) { - D3DCOLOR *pOutColor,*pConvertedColorArray; - Colorf *pInColor=colors; - pOutColor = pConvertedColorArray = (D3DCOLOR *)_pFvfBufBasePtr; + if (bDoColor || bDoGlobalSceneGraphColor) { + D3DCOLOR *pOutColor,*pConvertedColorArray; + Colorf *pInColor=colors; + pOutColor = pConvertedColorArray = (D3DCOLOR *)_pFvfBufBasePtr; - #ifdef _DEBUG - nassertv( cTotalVerts*sizeof(D3DCOLOR) <= VERT_BUFFER_SIZE); - #endif +#ifdef _DEBUG + nassertv( cTotalVerts*sizeof(D3DCOLOR) <= VERT_BUFFER_SIZE); +#endif - fvf_flags |= D3DFVF_DIFFUSE; + fvf_flags |= D3DFVF_DIFFUSE; - dps_data.diffuse.lpvData = (VOID*)pConvertedColorArray; - dps_data.diffuse.dwStride = sizeof(D3DCOLOR); + dps_data.diffuse.lpvData = (VOID*)pConvertedColorArray; + dps_data.diffuse.dwStride = sizeof(D3DCOLOR); - if(ColorBinding==G_PER_VERTEX) { - NeededShadeMode = D3DSHADE_GOURAUD; + if (ColorBinding==G_PER_VERTEX) { + NeededShadeMode = D3DSHADE_GOURAUD; - for(int i=0;i= cTotalVerts-nPrims*cNumMoreVertsthanTris); + // could save 2 clr writes per strip/fan in flat shade mode but not going to bother here + for (int j=0;j= cTotalVerts-nPrims*cNumMoreVertsthanTris); - if(NeededShadeMode == D3DSHADE_FLAT) { - // FLAT shade mode. for tristrips, skip writing last 2 verts. for trifans, skip first and last verts - if(trilisttype==D3DPT_TRIANGLESTRIP) { - for(int j=0;jget_color(); - *pConvertedColorArray=D3DRGBA(colr[0],colr[1],colr[2],colr[3]); - } else { - *pConvertedColorArray=D3DRGBA((*pInColor)[0],(*pInColor)[1],(*pInColor)[2],(*pInColor)[3]); - } + // copy the one global color in, set stride to 0 - dps_data.diffuse.dwStride = 0; - } - } + if (bDoGlobalSceneGraphColor) { + Colorf colr = catt->get_color(); + *pConvertedColorArray=D3DRGBA(colr[0],colr[1],colr[2],colr[3]); + } else { + *pConvertedColorArray=D3DRGBA((*pInColor)[0],(*pInColor)[1],(*pInColor)[2],(*pInColor)[3]); + } - if((TexCoordBinding != G_OFF) && _texturing_enabled) { + dps_data.diffuse.dwStride = 0; + } + } - #ifdef _DEBUG - nassertv(TexCoordBinding == G_PER_VERTEX); // only sensible choice for a tri - #endif + if ((TexCoordBinding != G_OFF) && _texturing_enabled) { - dps_data.textureCoords[0].lpvData = (VOID*)texcoords; - dps_data.textureCoords[0].dwStride = sizeof(TexCoordf); - fvf_flags |= (D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0)); - } +#ifdef _DEBUG + nassertv(TexCoordBinding == G_PER_VERTEX); // only sensible choice for a tri +#endif - set_shademode(NeededShadeMode); + dps_data.textureCoords[0].lpvData = (VOID*)texcoords; + dps_data.textureCoords[0].dwStride = sizeof(TexCoordf); + fvf_flags |= (D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0)); + } - for(int j=0;jDrawPrimitiveStrided(trilisttype, fvf_flags, &dps_data, cCurNumStripVerts, NULL); + set_shademode(NeededShadeMode); - #ifdef _DEBUG - if(FAILED(hr)) { - dxgsg_cat.fatal() << "DrawPrimStrided failed: result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - #endif - dps_data.position.lpvData = (VOID*)(((char*) dps_data.position.lpvData) + cCurNumStripVerts*dps_data.position.dwStride); - dps_data.diffuse.lpvData = (VOID*)(((char*) dps_data.diffuse.lpvData) + cCurNumStripVerts*dps_data.diffuse.dwStride); - dps_data.normal.lpvData = (VOID*)(((char*) dps_data.normal.lpvData) + cCurNumStripVerts*dps_data.normal.dwStride); - dps_data.textureCoords[0].lpvData = (VOID*)(((char*) dps_data.textureCoords[0].lpvData) + cCurNumStripVerts*dps_data.textureCoords[0].dwStride); - } + for (int j=0;jDrawPrimitiveStrided(trilisttype, fvf_flags, &dps_data, cCurNumStripVerts, NULL); + +#ifdef _DEBUG + if (FAILED(hr)) { + dxgsg_cat.fatal() << "DrawPrimStrided failed: result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } +#endif + dps_data.position.lpvData = (VOID*)(((char*) dps_data.position.lpvData) + cCurNumStripVerts*dps_data.position.dwStride); + dps_data.diffuse.lpvData = (VOID*)(((char*) dps_data.diffuse.lpvData) + cCurNumStripVerts*dps_data.diffuse.dwStride); + dps_data.normal.lpvData = (VOID*)(((char*) dps_data.normal.lpvData) + cCurNumStripVerts*dps_data.normal.dwStride); + dps_data.textureCoords[0].lpvData = (VOID*)(((char*) dps_data.textureCoords[0].lpvData) + cCurNumStripVerts*dps_data.textureCoords[0].dwStride); + } + + _pCurFvfBufPtr = NULL; + } } //----------------------------------------------------------------------------- @@ -2629,7 +2609,7 @@ draw_multitri(const Geom *geom, D3DPRIMITIVETYPE trilisttype) { // Desc: Makes vertex and index data for ellipsoid w/scaling factors sx,sy,sz // tries to match gluSphere behavior //----------------------------------------------------------------------------- - + void DXGraphicsStateGuardian:: GenerateSphere(void *pVertexSpace,DWORD dwVertSpaceByteSize, void *pIndexSpace,DWORD dwIndexSpaceByteSize, @@ -2637,50 +2617,50 @@ GenerateSphere(void *pVertexSpace,DWORD dwVertSpaceByteSize, DWORD wNumRings, DWORD wNumSections, float sx, float sy, float sz, DWORD *pNumVertices,DWORD *pNumIndices,DWORD fvfFlags,DWORD dwVertSize) { - float x, y, z, rsintheta; - D3DVECTOR vPoint; + float x, y, z, rsintheta; + D3DVECTOR vPoint; //#define DBG_GENSPHERE #define M_PI 3.1415926f // probably should get this from mathNumbers.h instead - nassertv(wNumRings>=2 && wNumSections>=2); + nassertv(wNumRings>=2 && wNumSections>=2); wNumRings--; // wNumRings indicates number of vertex rings (not tri-rings). - // gluSphere 'stacks' arg for 1 vert ring is 2, so convert to our '1'. - wNumSections++; // to make us equiv to gluSphere + // gluSphere 'stacks' arg for 1 vert ring is 2, so convert to our '1'. + wNumSections++; // to make us equiv to gluSphere - //Figure out needed space for the triangles and vertices. + //Figure out needed space for the triangles and vertices. DWORD dwNumVertices,dwNumIndices,dwNumTriangles; - #define DOTEXTURING (fvfFlags & D3DFVF_TEXCOUNT_MASK) - #define DONORMAL (fvfFlags & D3DFVF_NORMAL) - #define DOCOLOR (fvfFlags & D3DFVF_DIFFUSE) +#define DOTEXTURING (fvfFlags & D3DFVF_TEXCOUNT_MASK) +#define DONORMAL (fvfFlags & D3DFVF_NORMAL) +#define DOCOLOR (fvfFlags & D3DFVF_DIFFUSE) - if(DOTEXTURING) { + if (DOTEXTURING) { // if texturing, we need full rings of identical position verts at poles to hold diff texture coords wNumRings+=2; - dwNumVertices = *pNumVertices = wNumRings * wNumSections; + dwNumVertices = *pNumVertices = wNumRings * wNumSections; dwNumTriangles = (wNumRings-1) * wNumSections * 2; } else { - dwNumVertices = *pNumVertices = wNumRings * wNumSections + 2; + dwNumVertices = *pNumVertices = wNumRings * wNumSections + 2; dwNumTriangles = wNumRings*wNumSections*2; } - dwNumIndices = *pNumIndices = dwNumTriangles*3; + dwNumIndices = *pNumIndices = dwNumTriangles*3; - D3DVERTEX* pvVertices = (D3DVERTEX*) pVertexSpace; + D3DVERTEX* pvVertices = (D3DVERTEX*) pVertexSpace; WORD *pwIndices = (WORD *) pIndexSpace; - nassertv(dwNumVertices*dwVertSize < VERT_BUFFER_SIZE); - nassertv(dwNumIndices < D3DMAXNUMVERTICES ); + nassertv(dwNumVertices*dwVertSize < VERT_BUFFER_SIZE); + nassertv(dwNumIndices < D3DMAXNUMVERTICES ); - // Generate vertex at the top point - D3DVECTOR vTopPoint = *pCenter + D3DVECTOR( 0.0f, +sy*fRadius, 0.0f); - D3DVECTOR vBotPoint = *pCenter + D3DVECTOR( 0.0f, -sy*fRadius, 0.0f); - D3DVECTOR vNormal = D3DVECTOR( 0.0f, 1.0f, 0.0f ); + // Generate vertex at the top point + D3DVECTOR vTopPoint = *pCenter + D3DVECTOR( 0.0f, +sy*fRadius, 0.0f); + D3DVECTOR vBotPoint = *pCenter + D3DVECTOR( 0.0f, -sy*fRadius, 0.0f); + D3DVECTOR vNormal = D3DVECTOR( 0.0f, 1.0f, 0.0f ); float texCoords[2]; - - nassertv(pVertexSpace==_pCurFvfBufPtr); // add_to_FVFBuf requires this - + + nassertv(pVertexSpace==_pCurFvfBufPtr); // add_to_FVFBuf requires this + #define ADD_GENSPHERE_VERTEX_TO_BUFFER(VERT) \ add_to_FVFBuf((void *)&(VERT), sizeof(D3DVECTOR)); \ if(fvfFlags & D3DFVF_NORMAL) \ @@ -2689,88 +2669,88 @@ GenerateSphere(void *pVertexSpace,DWORD dwVertSpaceByteSize, add_DWORD_to_FVFBuf(p_colr); \ if(fvfFlags & D3DFVF_TEXCOUNT_MASK) \ add_to_FVFBuf((void *)texCoords, sizeof(TexCoordf)); - + #ifdef DBG_GENSPHERE int nvs_written=0; - memset(pVertexSpace,0xFF,dwNumVertices*dwVertSize); + memset(pVertexSpace,0xFF,dwNumVertices*dwVertSize); #endif - if(! DOTEXTURING) { + if (! DOTEXTURING) { ADD_GENSPHERE_VERTEX_TO_BUFFER(vTopPoint); - #ifdef DBG_GENSPHERE - nvs_written++; - #endif +#ifdef DBG_GENSPHERE + nvs_written++; +#endif } - // Generate vertex points for rings + // Generate vertex points for rings float inv_radius = 1.0f/fRadius; const float reciprocal_PI=1.0f/M_PI; const float reciprocal_2PI=1.0f/(2.0*M_PI); DWORD i; - float theta,dtheta; + float theta,dtheta; - if(DOTEXTURING) { + if (DOTEXTURING) { // numRings already includes 1st and last rings for this case - dtheta = (float)(M_PI / (wNumRings-1)); //Angle between each ring (ignore 2 fake rings) + dtheta = (float)(M_PI / (wNumRings-1)); //Angle between each ring (ignore 2 fake rings) theta = 0.0; - } else { - dtheta = (float)(M_PI / (wNumRings + 1)); //Angle between each ring + } else { + dtheta = (float)(M_PI / (wNumRings + 1)); //Angle between each ring theta = dtheta; } - float phi,dphi = (float)(2*M_PI / (wNumSections-1)); //Angle between each section + float phi,dphi = (float)(2*M_PI / (wNumSections-1)); //Angle between each section - for(i = 0; i < wNumRings; i++ ) { + for (i = 0; i < wNumRings; i++) { float costheta,sintheta,cosphi,sinphi; - phi = 0.0; + phi = 0.0; - if(DOTEXTURING) { + if (DOTEXTURING) { texCoords[1] = theta * reciprocal_PI; // v is the same for each ring } // could optimize all this sin/cos stuff w/tables csincos(theta,&sintheta,&costheta); - y = fRadius * costheta; // y is the same for each ring + y = fRadius * costheta; // y is the same for each ring rsintheta = fRadius * sintheta; - for(DWORD j = 0; j < wNumSections; j++) { + for (DWORD j = 0; j < wNumSections; j++) { csincos(phi,&sinphi,&cosphi); - x = rsintheta * sinphi; - z = rsintheta * cosphi; + x = rsintheta * sinphi; + z = rsintheta * cosphi; #ifdef DBG_GENSPHERE nvs_written++; #endif - vPoint = *pCenter + D3DVECTOR( sx*x, sy*y, sz*z ); + vPoint = *pCenter + D3DVECTOR( sx*x, sy*y, sz*z ); add_to_FVFBuf((void *)&vPoint, sizeof(D3DVECTOR)); - if(DONORMAL) { + if (DONORMAL) { // this is wrong normal for the non-spherical case (i think you need to multiply by 1/scale factor per component) vNormal = Normalize(D3DVECTOR( x*inv_radius, y*inv_radius, z*inv_radius )); add_to_FVFBuf((void *)&vNormal, sizeof(D3DVECTOR)); } - if(DOCOLOR) + if (DOCOLOR) add_DWORD_to_FVFBuf(p_colr); - if(DOTEXTURING) { + if (DOTEXTURING) { texCoords[0] = 1.0 - phi*reciprocal_2PI; add_to_FVFBuf((void *)texCoords, sizeof(TexCoordf)); } - phi += dphi; - } - theta += dtheta; - } - - if(! DOTEXTURING) { + phi += dphi; + } + theta += dtheta; + } + + if (! DOTEXTURING) { // Generate bottom vertex vNormal = D3DVECTOR( 0.0f, -1.0f, 0.0f ); ADD_GENSPHERE_VERTEX_TO_BUFFER(vBotPoint); - #ifdef DBG_GENSPHERE - nvs_written++; - #endif +#ifdef DBG_GENSPHERE + nvs_written++; +#endif } #ifdef DBG_GENSPHERE @@ -2779,87 +2759,87 @@ GenerateSphere(void *pVertexSpace,DWORD dwVertSpaceByteSize, #ifdef DBG_GENSPHERE - memset(pwIndices,0xFF,dwNumIndices*sizeof(WORD)); + memset(pwIndices,0xFF,dwNumIndices*sizeof(WORD)); #endif // inited for textured case - DWORD cur_vertring_startidx=0; // first vertex in current ring - DWORD CurFinalTriIndex = 0; // index of next tri to be written + DWORD cur_vertring_startidx=0; // first vertex in current ring + DWORD CurFinalTriIndex = 0; // index of next tri to be written - if(! DOTEXTURING) { + if (! DOTEXTURING) { // Generate caps using unique the bot/top vert // for non-textured case, could render the caps as indexed trifans, // but should be no perf difference b/w indexed trilists and indexed trifans // and this has advantage of being aggregable into 1 big DPrim call for whole sphere - for(i = 0; i < wNumSections; i++ ) { - DWORD TopCapTriIndex=3*i; - DWORD BotCapTriIndex=3*(dwNumTriangles - wNumSections + i); - DWORD i_incd = ((i + 1) % wNumSections); - - pwIndices[TopCapTriIndex++] = 0; - pwIndices[TopCapTriIndex++] = i + 1; - pwIndices[TopCapTriIndex] = i_incd + 1; - - pwIndices[BotCapTriIndex++] = (WORD)( dwNumVertices - 1 ); - pwIndices[BotCapTriIndex++] = (WORD)( dwNumVertices - 2 - i ); - pwIndices[BotCapTriIndex] = (WORD)( dwNumVertices - 2 - i_incd); - } + for (i = 0; i < wNumSections; i++) { + DWORD TopCapTriIndex=3*i; + DWORD BotCapTriIndex=3*(dwNumTriangles - wNumSections + i); + DWORD i_incd = ((i + 1) % wNumSections); - cur_vertring_startidx = 1; // first vertex in current ring (skip top vert) - CurFinalTriIndex = wNumSections; // index of tri to be written, wNumSections to skip the top cap row - } + pwIndices[TopCapTriIndex++] = 0; + pwIndices[TopCapTriIndex++] = i + 1; + pwIndices[TopCapTriIndex] = i_incd + 1; + + pwIndices[BotCapTriIndex++] = (WORD)( dwNumVertices - 1 ); + pwIndices[BotCapTriIndex++] = (WORD)( dwNumVertices - 2 - i ); + pwIndices[BotCapTriIndex] = (WORD)( dwNumVertices - 2 - i_incd); + } + + cur_vertring_startidx = 1; // first vertex in current ring (skip top vert) + CurFinalTriIndex = wNumSections; // index of tri to be written, wNumSections to skip the top cap row + } DWORD j_incd,base_index; // technically we could break into a strip for every row (or 1 big strip connected w/degenerate tris) // but indexed trilists should actually be just as fast on HW - // Generate triangles for the rings - for(i = 0; i < wNumRings-1; i++ ) { - for(DWORD j = 0; j < wNumSections; j++ ) { + // Generate triangles for the rings + for (i = 0; i < wNumRings-1; i++) { + for (DWORD j = 0; j < wNumSections; j++) { - base_index=3*CurFinalTriIndex; // final vert index is 3*finaltriindex - j_incd=(j+1) % wNumSections; + base_index=3*CurFinalTriIndex; // final vert index is 3*finaltriindex + j_incd=(j+1) % wNumSections; - DWORD v1_row1_idx,v2_row1_idx,v1_row2_idx,v2_row2_idx; + DWORD v1_row1_idx,v2_row1_idx,v1_row2_idx,v2_row2_idx; - v1_row1_idx = cur_vertring_startidx + j; - v2_row1_idx = cur_vertring_startidx + j_incd; - v1_row2_idx = v1_row1_idx + wNumSections; - v2_row2_idx = v2_row1_idx + wNumSections; - - #ifdef DBG_GENSPHERE - assert(v2_row2_idxget_num_prims(); + int nprims = geom->get_num_prims(); - if(nprims==0) { - dxgsg_cat.warning() << "draw_sphere() called with ZERO vertices!!" << endl; - return; - } - - Geom::VertexIterator vi = geom->make_vertex_iterator(); - Geom::ColorIterator ci; - bool bPerPrimColor = (geom->get_binding(G_COLOR) == G_PER_PRIM); - if(bPerPrimColor) - ci = geom->make_color_iterator(); - - for (int i = 0; i < nprims; i++) { - - DWORD nVerts,nIndices; - Vertexf center = geom->get_next_vertex(vi); - Vertexf edge = geom->get_next_vertex(vi); - LVector3f v = edge - center; - float fRadius = sqrt(dot(v, v)); - - size_t vertex_size = draw_prim_setup(geom); - - _pCurFvfBufPtr = _pFvfBufBasePtr; - - if(bPerPrimColor) { - p_color = geom->get_next_color(ci); - p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); + if (nprims==0) { + dxgsg_cat.warning() << "draw_sphere() called with ZERO vertices!!" << endl; + return; } - GenerateSphere(_pCurFvfBufPtr, VERT_BUFFER_SIZE, - _index_buf, D3DMAXNUMVERTICES, - (D3DVECTOR *)¢er, fRadius, - SPHERE_NUMSTACKS, SPHERE_NUMSLICES, - 1.0f, 1.0f, 1.0f, // no scaling factors, do a sphere not ellipsoid - &nVerts,&nIndices,p_flags,vertex_size); + Geom::VertexIterator vi = geom->make_vertex_iterator(); + Geom::ColorIterator ci; + bool bPerPrimColor = (geom->get_binding(G_COLOR) == G_PER_PRIM); + if (bPerPrimColor) + ci = geom->make_color_iterator(); - // possible optimization: make DP 1 for all spheres call here, since trilist is independent tris. - // indexes couldnt start w/0 tho, need to pass offset to gensph - _d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, p_flags, _pFvfBufBasePtr, nVerts, _index_buf,nIndices,NULL); - } + for (int i = 0; i < nprims; i++) { - _pCurFvfBufPtr = NULL; + DWORD nVerts,nIndices; + Vertexf center = geom->get_next_vertex(vi); + Vertexf edge = geom->get_next_vertex(vi); + LVector3f v = edge - center; + float fRadius = sqrt(dot(v, v)); + + size_t vertex_size = draw_prim_setup(geom); + + _pCurFvfBufPtr = _pFvfBufBasePtr; + + if (bPerPrimColor) { + p_color = geom->get_next_color(ci); + p_colr = D3DRGBA(p_color[0], p_color[1], p_color[2], p_color[3]); + } + + GenerateSphere(_pCurFvfBufPtr, VERT_BUFFER_SIZE, + _index_buf, D3DMAXNUMVERTICES, + (D3DVECTOR *)¢er, fRadius, + SPHERE_NUMSTACKS, SPHERE_NUMSLICES, + 1.0f, 1.0f, 1.0f, // no scaling factors, do a sphere not ellipsoid + &nVerts,&nIndices,p_flags,vertex_size); + + // possible optimization: make DP 1 for all spheres call here, since trilist is independent tris. + // indexes couldnt start w/0 tho, need to pass offset to gensph + _d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, p_flags, _pFvfBufBasePtr, nVerts, _index_buf,nIndices,NULL); + } + + _pCurFvfBufPtr = NULL; } //////////////////////////////////////////////////////////////////// @@ -2931,14 +2911,13 @@ draw_sphere(const GeomSphere *geom) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_color_transform(const ColorMatrixAttribute *attrib) { - _current_color_mat = attrib->get_matrix(); + _current_color_mat = attrib->get_matrix(); - if (_current_color_mat == LMatrix4f::ident_mat()) { - _color_transform_enabled = false; - } - else { - _color_transform_enabled = true; - } + if (_current_color_mat == LMatrix4f::ident_mat()) { + _color_transform_enabled = false; + } else { + _color_transform_enabled = true; + } } //////////////////////////////////////////////////////////////////// @@ -2948,15 +2927,14 @@ issue_color_transform(const ColorMatrixAttribute *attrib) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_alpha_transform(const AlphaTransformAttribute *attrib) { - _current_alpha_offset= attrib->get_offset(); - _current_alpha_scale = attrib->get_scale(); + _current_alpha_offset= attrib->get_offset(); + _current_alpha_scale = attrib->get_scale(); - if (_current_alpha_offset == 0 && _current_alpha_scale == 1) { - _alpha_transform_enabled = false; - } - else { - _alpha_transform_enabled = true; - } + if (_current_alpha_offset == 0 && _current_alpha_scale == 1) { + _alpha_transform_enabled = false; + } else { + _alpha_transform_enabled = true; + } } @@ -2976,31 +2954,31 @@ issue_alpha_transform(const AlphaTransformAttribute *attrib) { //////////////////////////////////////////////////////////////////// TextureContext *DXGraphicsStateGuardian:: prepare_texture(Texture *tex) { - activate(); + activate(); - DXTextureContext *gtc = new DXTextureContext(tex); + DXTextureContext *gtc = new DXTextureContext(tex); #ifdef WBD_GL_MODE - glGenTextures(1, >c->_index); + glGenTextures(1, >c->_index); - bind_texture(gtc); - glPrioritizeTextures(1, >c->_index, >c->_priority); - specify_texture(tex); - apply_texture_immediate(tex); + bind_texture(gtc); + glPrioritizeTextures(1, >c->_index, >c->_priority); + specify_texture(tex); + apply_texture_immediate(tex); #else - if(gtc->CreateTexture(_hdc, _d3dDevice,_cNumTexPixFmts,_pTexPixFmts) == NULL) { - delete gtc; - return NULL; - } + if (gtc->CreateTexture(_hdc, _d3dDevice,_cNumTexPixFmts,_pTexPixFmts) == NULL) { + delete gtc; + return NULL; + } #endif // WBD_GL_MODE - bool inserted = mark_prepared_texture(gtc); + bool inserted = mark_prepared_texture(gtc); - // If this assertion fails, the same texture was prepared twice, - // which shouldn't be possible, since the texture itself should - // detect this. - nassertr(inserted, NULL); + // If this assertion fails, the same texture was prepared twice, + // which shouldn't be possible, since the texture itself should + // detect this. + nassertr(inserted, NULL); - return gtc; + return gtc; } //////////////////////////////////////////////////////////////////// @@ -3011,108 +2989,109 @@ prepare_texture(Texture *tex) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: apply_texture(TextureContext *tc) { - if(tc==NULL) { - return; // use enable_texturing to disable/enable - } + if (tc==NULL) { + return; // use enable_texturing to disable/enable + } // activate(); inactive #ifdef WBD_GL_MODE - bind_texture(tc); + bind_texture(tc); #else + // specify_texture(tc->_texture); - // Note: if this code changes, make sure to change initialization SetTSS code in init_dx as well - // so DX TSS renderstate matches dxgsg state + // Note: if this code changes, make sure to change initialization SetTSS code in init_dx as well + // so DX TSS renderstate matches dxgsg state - Texture *tex = tc->_texture; - Texture::WrapMode wrapU,wrapV; - wrapU=tex->get_wrapu(); - wrapV=tex->get_wrapu(); + Texture *tex = tc->_texture; + Texture::WrapMode wrapU,wrapV; + wrapU=tex->get_wrapu(); + wrapV=tex->get_wrapu(); - if(wrapU!=_CurTexWrapModeU) - _d3dDevice->SetTextureStageState(0,D3DTSS_ADDRESSU,get_texture_wrap_mode(wrapU)); - if(wrapV!=_CurTexWrapModeV) - _d3dDevice->SetTextureStageState(0,D3DTSS_ADDRESSV,get_texture_wrap_mode(wrapV)); + if (wrapU!=_CurTexWrapModeU) + _d3dDevice->SetTextureStageState(0,D3DTSS_ADDRESSU,get_texture_wrap_mode(wrapU)); + if (wrapV!=_CurTexWrapModeV) + _d3dDevice->SetTextureStageState(0,D3DTSS_ADDRESSV,get_texture_wrap_mode(wrapV)); - int aniso_degree=tex->get_anisotropic_degree(); - Texture::FilterType ft=tex->get_magfilter(); + int aniso_degree=tex->get_anisotropic_degree(); + Texture::FilterType ft=tex->get_magfilter(); - if(aniso_degree>1) { - if(aniso_degree!=_CurTexAnisoDegree) { - _d3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_ANISOTROPIC ); - _d3dDevice->SetTextureStageState(0, D3DTSS_MAXANISOTROPY,aniso_degree); - } - } else { - if(_CurTexMagFilter!=ft) - switch(ft) { - case Texture::FT_nearest: - _d3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_POINT); - break; - case Texture::FT_linear: - _d3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR); - break; - default: - dxgsg_cat.error() << "MipMap filter type setting for texture magfilter makes no sense, texture: " << tex->get_name() << "\n"; - break; - } - } - - ft=tex->get_minfilter(); + if (aniso_degree>1) { + if (aniso_degree!=_CurTexAnisoDegree) { + _d3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_ANISOTROPIC ); + _d3dDevice->SetTextureStageState(0, D3DTSS_MAXANISOTROPY,aniso_degree); + } + } else { + if (_CurTexMagFilter!=ft) + switch (ft) { + case Texture::FT_nearest: + _d3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_POINT); + break; + case Texture::FT_linear: + _d3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR); + break; + default: + dxgsg_cat.error() << "MipMap filter type setting for texture magfilter makes no sense, texture: " << tex->get_name() << "\n"; + break; + } + } - if((ft!=_CurTexMinFilter)||(aniso_degree!=_CurTexAnisoDegree)) { - D3DTEXTUREMIPFILTER mipfilter = D3DTFP_LINEAR; - D3DTEXTUREMINFILTER minfilter = D3DTFN_LINEAR; - - switch(ft) { - case Texture::FT_nearest: - minfilter = D3DTFN_POINT; - mipfilter = D3DTFP_NONE; - break; - case Texture::FT_linear: - minfilter = D3DTFN_LINEAR; - mipfilter = D3DTFP_NONE; - break; - case Texture::FT_nearest_mipmap_nearest: - minfilter = D3DTFN_POINT; - mipfilter = D3DTFP_POINT; - break; - case Texture::FT_linear_mipmap_nearest: - minfilter = D3DTFN_LINEAR; - mipfilter = D3DTFP_POINT; - break; - case Texture::FT_nearest_mipmap_linear: - minfilter = D3DTFN_POINT; - mipfilter = D3DTFP_LINEAR; - break; - case Texture::FT_linear_mipmap_linear: - minfilter = D3DTFN_LINEAR; - mipfilter = D3DTFP_LINEAR; - break; - default: - dxgsg_cat.error() << "Unknown tex filter type for tex: " << tex->get_name() << " filter: "<<(DWORD)ft<<"\n"; - } - - if(aniso_degree>1) { - minfilter=D3DTFN_ANISOTROPIC; - } - - _d3dDevice->SetTextureStageState(0, D3DTSS_MINFILTER, minfilter); - _d3dDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, mipfilter); - } + ft=tex->get_minfilter(); - DXTextureContext *dtc = DCAST(DXTextureContext, tc); + if ((ft!=_CurTexMinFilter)||(aniso_degree!=_CurTexAnisoDegree)) { + D3DTEXTUREMIPFILTER mipfilter = D3DTFP_LINEAR; + D3DTEXTUREMINFILTER minfilter = D3DTFN_LINEAR; - // bugbug: does this handle the case of untextured geometry? - // we dont see this bug cause we never mix textured/untextured + switch (ft) { + case Texture::FT_nearest: + minfilter = D3DTFN_POINT; + mipfilter = D3DTFP_NONE; + break; + case Texture::FT_linear: + minfilter = D3DTFN_LINEAR; + mipfilter = D3DTFP_NONE; + break; + case Texture::FT_nearest_mipmap_nearest: + minfilter = D3DTFN_POINT; + mipfilter = D3DTFP_POINT; + break; + case Texture::FT_linear_mipmap_nearest: + minfilter = D3DTFN_LINEAR; + mipfilter = D3DTFP_POINT; + break; + case Texture::FT_nearest_mipmap_linear: + minfilter = D3DTFN_POINT; + mipfilter = D3DTFP_LINEAR; + break; + case Texture::FT_linear_mipmap_linear: + minfilter = D3DTFN_LINEAR; + mipfilter = D3DTFP_LINEAR; + break; + default: + dxgsg_cat.error() << "Unknown tex filter type for tex: " << tex->get_name() << " filter: "<<(DWORD)ft<<"\n"; + } - _d3dDevice->SetTexture(0, dtc->_surface ); + if (aniso_degree>1) { + minfilter=D3DTFN_ANISOTROPIC; + } + + _d3dDevice->SetTextureStageState(0, D3DTSS_MINFILTER, minfilter); + _d3dDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, mipfilter); + } + + DXTextureContext *dtc = DCAST(DXTextureContext, tc); + + // bugbug: does this handle the case of untextured geometry? + // we dont see this bug cause we never mix textured/untextured + + _d3dDevice->SetTexture(0, dtc->_surface ); #if 0 - if(dtc!=NULL) { - dxgsg_cat.spam() << "Setting active DX texture: " << dtc->_tex->get_name() << "\n"; - } + if (dtc!=NULL) { + dxgsg_cat.spam() << "Setting active DX texture: " << dtc->_tex->get_name() << "\n"; + } #endif - _pCurTexContext = dtc; // enable_texturing needs this + _pCurTexContext = dtc; // enable_texturing needs this #endif } @@ -3127,38 +3106,38 @@ apply_texture(TextureContext *tc) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: release_texture(TextureContext *tc) { - activate(); - DXTextureContext *gtc = DCAST(DXTextureContext, tc); - Texture *tex = tc->_texture; + activate(); + DXTextureContext *gtc = DCAST(DXTextureContext, tc); + Texture *tex = tc->_texture; #ifdef WBD_GL_MODE - glDeleteTextures(1, >c->_index); - gtc->_index = 0; + glDeleteTextures(1, >c->_index); + gtc->_index = 0; #else - gtc->DeleteTexture(); + gtc->DeleteTexture(); #endif // WBD_GL_MODE - bool erased = unmark_prepared_texture(gtc); + bool erased = unmark_prepared_texture(gtc); - // If this assertion fails, a texture was released that hadn't been - // prepared (or a texture was released twice). - nassertv(erased); + // If this assertion fails, a texture was released that hadn't been + // prepared (or a texture was released twice). + nassertv(erased); - tex->clear_gsg(this); + tex->clear_gsg(this); - delete gtc; + delete gtc; } static int logs[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, - 4096, 0 }; + 4096, 0}; // This function returns the smallest power of two greater than or // equal to x. static int binary_log_cap(const int x) { - int i = 0; - for (; (x > logs[i]) && (logs[i] != 0); ++i); - if (logs[i] == 0) - return 4096; - return logs[i]; + int i = 0; + for (; (x > logs[i]) && (logs[i] != 0); ++i); + if (logs[i] == 0) + return 4096; + return logs[i]; } //////////////////////////////////////////////////////////////////// @@ -3169,42 +3148,42 @@ static int binary_log_cap(const int x) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: copy_texture(TextureContext *tc, const DisplayRegion *dr) { - dxgsg_cat.fatal() << "DX copy_texture unimplemented!!!"; - return; + dxgsg_cat.fatal() << "DX copy_texture unimplemented!!!"; + return; #if 0 - nassertv(tc != NULL && dr != NULL); - activate(); + nassertv(tc != NULL && dr != NULL); + activate(); - Texture *tex = tc->_texture; + Texture *tex = tc->_texture; - // Determine the size of the grab from the given display region - // If the requested region is not a power of two, grab a region that is - // a power of two that contains the requested region - int xo, yo, req_w, req_h; - dr->get_region_pixels(xo, yo, req_w, req_h); - int w = binary_log_cap(req_w); - int h = binary_log_cap(req_h); - if (w != req_w || h != req_h) { - tex->_requested_w = req_w; - tex->_requested_h = req_h; - tex->_has_requested_size = true; - } + // Determine the size of the grab from the given display region + // If the requested region is not a power of two, grab a region that is + // a power of two that contains the requested region + int xo, yo, req_w, req_h; + dr->get_region_pixels(xo, yo, req_w, req_h); + int w = binary_log_cap(req_w); + int h = binary_log_cap(req_h); + if (w != req_w || h != req_h) { + tex->_requested_w = req_w; + tex->_requested_h = req_h; + tex->_has_requested_size = true; + } - PixelBuffer *pb = tex->_pbuffer; + PixelBuffer *pb = tex->_pbuffer; - pb->set_xorg(xo); - pb->set_yorg(yo); - pb->set_xsize(w); - pb->set_ysize(h); + pb->set_xorg(xo); + pb->set_yorg(yo); + pb->set_xsize(w); + pb->set_ysize(h); //#ifdef WBD_GL_MODE - bind_texture(tc); - glCopyTexImage2D( GL_TEXTURE_2D, tex->get_level(), - get_internal_image_format(pb->get_format()), - pb->get_xorg(), pb->get_yorg(), - pb->get_xsize(), pb->get_ysize(), pb->get_border() ); + bind_texture(tc); + glCopyTexImage2D( GL_TEXTURE_2D, tex->get_level(), + get_internal_image_format(pb->get_format()), + pb->get_xorg(), pb->get_yorg(), + pb->get_xsize(), pb->get_ysize(), pb->get_border() ); #endif // WBD_GL_MODE } @@ -3215,12 +3194,12 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: copy_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb) { - dxgsg_cat.fatal() << "DX copy_texture unimplemented!!!"; - return; + dxgsg_cat.fatal() << "DX copy_texture unimplemented!!!"; + return; - activate(); - set_read_buffer(rb); - copy_texture(tc, dr); + activate(); + set_read_buffer(rb); + copy_texture(tc, dr); } //////////////////////////////////////////////////////////////////// @@ -3231,80 +3210,80 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb void DXGraphicsStateGuardian:: draw_texture(TextureContext *tc, const DisplayRegion *dr) { - dxgsg_cat.fatal() << "DXGSG draw_texture unimplemented!!!"; - return; + dxgsg_cat.fatal() << "DXGSG draw_texture unimplemented!!!"; + return; - nassertv(tc != NULL && dr != NULL); - activate(); + nassertv(tc != NULL && dr != NULL); + activate(); #ifdef WBD_GL_MODE - Texture *tex = tc->_texture; + Texture *tex = tc->_texture; - DisplayRegionStack old_dr = push_display_region(dr); - prepare_display_region(); + DisplayRegionStack old_dr = push_display_region(dr); + prepare_display_region(); - NodeAttributes state; - CullFaceAttribute *cfa = new CullFaceAttribute; - cfa->set_mode(CullFaceProperty::M_cull_none); - DepthTestAttribute *dta = new DepthTestAttribute; - dta->set_mode(DepthTestProperty::M_none); - DepthWriteAttribute *dwa = new DepthWriteAttribute; - dwa->set_off(); - TextureAttribute *ta = new TextureAttribute; - ta->set_on(tex); - TextureApplyAttribute *taa = new TextureApplyAttribute; - taa->set_mode(TextureApplyProperty::M_decal); + NodeAttributes state; + CullFaceAttribute *cfa = new CullFaceAttribute; + cfa->set_mode(CullFaceProperty::M_cull_none); + DepthTestAttribute *dta = new DepthTestAttribute; + dta->set_mode(DepthTestProperty::M_none); + DepthWriteAttribute *dwa = new DepthWriteAttribute; + dwa->set_off(); + TextureAttribute *ta = new TextureAttribute; + ta->set_on(tex); + TextureApplyAttribute *taa = new TextureApplyAttribute; + taa->set_mode(TextureApplyProperty::M_decal); - state.set_attribute(LightTransition::get_class_type(), - new LightAttribute); - state.set_attribute(ColorMaskTransition::get_class_type(), - new ColorMaskAttribute); - state.set_attribute(RenderModeTransition::get_class_type(), - new RenderModeAttribute); - state.set_attribute(TexMatrixTransition::get_class_type(), - new TexMatrixAttribute); - state.set_attribute(TransformTransition::get_class_type(), - new TransformAttribute); - state.set_attribute(ColorBlendTransition::get_class_type(), - new ColorBlendAttribute); - state.set_attribute(CullFaceTransition::get_class_type(), cfa); - state.set_attribute(DepthTestTransition::get_class_type(), dta); - state.set_attribute(DepthWriteTransition::get_class_type(), dwa); - state.set_attribute(TextureTransition::get_class_type(), ta); - state.set_attribute(TextureApplyTransition::get_class_type(), taa); - set_state(state, false); + state.set_attribute(LightTransition::get_class_type(), + new LightAttribute); + state.set_attribute(ColorMaskTransition::get_class_type(), + new ColorMaskAttribute); + state.set_attribute(RenderModeTransition::get_class_type(), + new RenderModeAttribute); + state.set_attribute(TexMatrixTransition::get_class_type(), + new TexMatrixAttribute); + state.set_attribute(TransformTransition::get_class_type(), + new TransformAttribute); + state.set_attribute(ColorBlendTransition::get_class_type(), + new ColorBlendAttribute); + state.set_attribute(CullFaceTransition::get_class_type(), cfa); + state.set_attribute(DepthTestTransition::get_class_type(), dta); + state.set_attribute(DepthWriteTransition::get_class_type(), dwa); + state.set_attribute(TextureTransition::get_class_type(), ta); + state.set_attribute(TextureApplyTransition::get_class_type(), taa); + set_state(state, false); - // We set up an orthographic projection that defines our entire - // viewport to the range [0..1] in both dimensions. Then, when we - // create a unit square polygon below, it will exactly fill the - // viewport (and thus exactly fill the display region). - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - gluOrtho2D(0, 1, 0, 1); + // We set up an orthographic projection that defines our entire + // viewport to the range [0..1] in both dimensions. Then, when we + // create a unit square polygon below, it will exactly fill the + // viewport (and thus exactly fill the display region). + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluOrtho2D(0, 1, 0, 1); - float txl, txr, tyt, tyb; - txl = tyb = 0.; - if (tex->_has_requested_size) { - txr = ((float)(tex->_requested_w)) / ((float)(tex->_pbuffer->get_xsize())); - tyt = ((float)(tex->_requested_h)) / ((float)(tex->_pbuffer->get_ysize())); - } else { - txr = tyt = 1.; - } + float txl, txr, tyt, tyb; + txl = tyb = 0.; + if (tex->_has_requested_size) { + txr = ((float)(tex->_requested_w)) / ((float)(tex->_pbuffer->get_xsize())); + tyt = ((float)(tex->_requested_h)) / ((float)(tex->_pbuffer->get_ysize())); + } else { + txr = tyt = 1.; + } - // This two-triangle strip is actually a quad. But it's usually - // better to render quads as tristrips anyway. - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(txl, tyb); glVertex2i(0, 0); - glTexCoord2f(txr, tyb); glVertex2i(1, 0); - glTexCoord2f(txl, tyt); glVertex2i(0, 1); - glTexCoord2f(txr, tyt); glVertex2i(1, 1); - glEnd(); + // This two-triangle strip is actually a quad. But it's usually + // better to render quads as tristrips anyway. + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(txl, tyb); glVertex2i(0, 0); + glTexCoord2f(txr, tyb); glVertex2i(1, 0); + glTexCoord2f(txl, tyt); glVertex2i(0, 1); + glTexCoord2f(txr, tyt); glVertex2i(1, 1); + glEnd(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); - pop_display_region(old_dr); + pop_display_region(old_dr); #endif // WBD_GL_MODE } @@ -3316,12 +3295,12 @@ draw_texture(TextureContext *tc, const DisplayRegion *dr) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: draw_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb) { - dxgsg_cat.fatal() << "DXGSG draw_texture unimplemented!!!"; - return; + dxgsg_cat.fatal() << "DXGSG draw_texture unimplemented!!!"; + return; - activate(); - set_draw_buffer(rb); - draw_texture(tc, dr); + activate(); + set_draw_buffer(rb); + draw_texture(tc, dr); } //////////////////////////////////////////////////////////////////// @@ -3331,23 +3310,23 @@ draw_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb) { - nassertv(tc != NULL && pb != NULL); - activate(); + nassertv(tc != NULL && pb != NULL); + activate(); - Texture *tex = tc->_texture; + Texture *tex = tc->_texture; - int w = tex->_pbuffer->get_xsize(); - int h = tex->_pbuffer->get_ysize(); + int w = tex->_pbuffer->get_xsize(); + int h = tex->_pbuffer->get_ysize(); - PT(DisplayRegion) dr = _win->make_scratch_display_region(w, h); + PT(DisplayRegion) dr = _win->make_scratch_display_region(w, h); - FrameBufferStack old_fb = push_frame_buffer - (get_render_buffer(RenderBuffer::T_back | RenderBuffer::T_depth), - dr); + FrameBufferStack old_fb = push_frame_buffer + (get_render_buffer(RenderBuffer::T_back | RenderBuffer::T_depth), + dr); - texture_to_pixel_buffer(tc, pb, dr); + texture_to_pixel_buffer(tc, pb, dr); - pop_frame_buffer(old_fb); + pop_frame_buffer(old_fb); } //////////////////////////////////////////////////////////////////// @@ -3357,24 +3336,24 @@ texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb, - const DisplayRegion *dr) { - nassertv(tc != NULL && pb != NULL && dr != NULL); - activate(); + const DisplayRegion *dr) { + nassertv(tc != NULL && pb != NULL && dr != NULL); + activate(); - Texture *tex = tc->_texture; - - // Do a deep copy to initialize the pixel buffer - pb->copy(tex->_pbuffer); + Texture *tex = tc->_texture; - // If the image was empty, we need to render the texture into the frame - // buffer and then copy the results into the pixel buffer's image - if (pb->_image.empty()) { - int w = pb->get_xsize(); - int h = pb->get_ysize(); - draw_texture(tc, dr); - pb->_image = PTA_uchar(w * h * pb->get_num_components()); - copy_pixel_buffer(pb, dr); - } + // Do a deep copy to initialize the pixel buffer + pb->copy(tex->_pbuffer); + + // If the image was empty, we need to render the texture into the frame + // buffer and then copy the results into the pixel buffer's image + if (pb->_image.empty()) { + int w = pb->get_xsize(); + int h = pb->get_ysize(); + draw_texture(tc, dr); + pb->_image = PTA_uchar(w * h * pb->get_num_components()); + copy_pixel_buffer(pb, dr); + } } //////////////////////////////////////////////////////////////////// @@ -3385,69 +3364,32 @@ texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb, void DXGraphicsStateGuardian:: copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) { - dxgsg_cat.fatal() << "DXGSG copy_pixel_buffer unimplemented!!!"; - return; + extern HRESULT ConvertDDSurftoPixBuf(PixelBuffer *pixbuf,LPDIRECTDRAWSURFACE7 pDDSurf); -#ifdef WBD_GL_MODE - nassertv(pb != NULL && dr != NULL); - activate(); - set_pack_alignment(1); + nassertv(pb != NULL && dr != NULL); - NodeAttributes state; + int xo, yo, w, h; + dr->get_region_pixels(xo, yo, w, h); - // Bug fix for RE, RE2, and VTX - need to disable texturing in order - // for glReadPixels() to work - // NOTE: reading the depth buffer is *much* slower than reading the - // color buffer - state.set_attribute(TextureTransition::get_class_type(), - new TextureAttribute); - set_state(state, false); + // only handled simple case + nassertv(xo==0); + nassertv(yo==0); + nassertv(w==pb->get_xsize()); + nassertv(h==pb->get_ysize()); - int xo, yo, w, h; - dr->get_region_pixels(xo, yo, w, h); +/* + set_pack_alignment(1); + glReadPixels( pb->get_xorg() + xo, pb->get_yorg() + yo, + pb->get_xsize(), pb->get_ysize(), + get_external_image_format(pb->get_format()), + get_image_type(pb->get_image_type()), + pb->_image.p() ); +*/ -#ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "glReadPixels(" << pb->get_xorg() << ", " << pb->get_yorg() - << ", " << pb->get_xsize() << ", " << pb->get_ysize() - << ", "; - switch (get_external_image_format(pb->get_format())) { - case GL_DEPTH_COMPONENT: - dxgsg_cat.debug(false) << "GL_DEPTH_COMPONENT, "; - break; - case GL_RGB: - dxgsg_cat.debug(false) << "GL_RGB, "; - break; - case GL_RGBA: - dxgsg_cat.debug(false) << "GL_RGBA, "; - break; - default: - dxgsg_cat.debug(false) << "unknown, "; - break; - } - switch (get_image_type(pb->get_image_type())) { - case GL_UNSIGNED_BYTE: - dxgsg_cat.debug(false) << "GL_UNSIGNED_BYTE, "; - break; - case GL_float: - dxgsg_cat.debug(false) << "GL_float, "; - break; - default: - dxgsg_cat.debug(false) << "unknown, "; - break; - } - dxgsg_cat.debug(false) - << (void *)pb->_image.p() << ")" << endl; -#endif - glReadPixels( pb->get_xorg() + xo, pb->get_yorg() + yo, - pb->get_xsize(), pb->get_ysize(), - get_external_image_format(pb->get_format()), - get_image_type(pb->get_image_type()), - pb->_image.p() ); + (void) ConvertDDSurftoPixBuf(pb,((_cur_read_pixel_buffer & RenderBuffer::T_back) ? _back : _pri)); - nassertv(!pb->_image.empty()); -#endif // WBD_GL_MODE + nassertv(!pb->_image.empty()); } //////////////////////////////////////////////////////////////////// @@ -3457,10 +3399,9 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, - const RenderBuffer &rb) { - activate(); - set_read_buffer(rb); - copy_pixel_buffer(pb, dr); + const RenderBuffer &rb) { + set_read_buffer(rb); + copy_pixel_buffer(pb, dr); } //////////////////////////////////////////////////////////////////// @@ -3470,126 +3411,126 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, - const NodeAttributes& na) { + const NodeAttributes& na) { - dxgsg_cat.fatal() << "DXGSG draw_pixel_buffer unimplemented!!!"; - return; + dxgsg_cat.fatal() << "DXGSG draw_pixel_buffer unimplemented!!!"; + return; #ifdef WBD_GL_MODE - nassertv(pb != NULL && dr != NULL); - nassertv(!pb->_image.empty()); - activate(); + nassertv(pb != NULL && dr != NULL); + nassertv(!pb->_image.empty()); + activate(); - DisplayRegionStack old_dr = push_display_region(dr); - prepare_display_region(); + DisplayRegionStack old_dr = push_display_region(dr); + prepare_display_region(); - NodeAttributes state(na); - state.set_attribute(LightTransition::get_class_type(), - new LightAttribute); - state.set_attribute(TextureTransition::get_class_type(), - new TextureAttribute); - state.set_attribute(TransformTransition::get_class_type(), - new TransformAttribute); - state.set_attribute(ColorBlendTransition::get_class_type(), - new ColorBlendAttribute); - state.set_attribute(StencilTransition::get_class_type(), - new StencilAttribute); + NodeAttributes state(na); + state.set_attribute(LightTransition::get_class_type(), + new LightAttribute); + state.set_attribute(TextureTransition::get_class_type(), + new TextureAttribute); + state.set_attribute(TransformTransition::get_class_type(), + new TransformAttribute); + state.set_attribute(ColorBlendTransition::get_class_type(), + new ColorBlendAttribute); + state.set_attribute(StencilTransition::get_class_type(), + new StencilAttribute); - switch (pb->get_format()) { - case PixelBuffer::F_depth_component: - { - ColorMaskAttribute *cma = new ColorMaskAttribute; - cma->set_mask(0); - DepthTestAttribute *dta = new DepthTestAttribute; - dta->set_mode(DepthTestProperty::M_always); - DepthWriteAttribute *dwa = new DepthWriteAttribute; - dwa->set_off(); - state.set_attribute(ColorMaskTransition::get_class_type(), cma); - state.set_attribute(DepthTestTransition::get_class_type(), dta); - state.set_attribute(DepthWriteTransition::get_class_type(), dwa); - } - break; - - case PixelBuffer::F_rgb: - case PixelBuffer::F_rgb5: - case PixelBuffer::F_rgb8: - case PixelBuffer::F_rgb12: - case PixelBuffer::F_rgba: - case PixelBuffer::F_rgba4: - case PixelBuffer::F_rgba8: - case PixelBuffer::F_rgba12: - { - ColorMaskAttribute *cma = new ColorMaskAttribute; - DepthTestAttribute *dta = new DepthTestAttribute; - dta->set_mode(DepthTestProperty::M_none); - DepthWriteAttribute *dwa = new DepthWriteAttribute; - dwa->set_off(); - state.set_attribute(ColorMaskTransition::get_class_type(), cma); - state.set_attribute(DepthTestTransition::get_class_type(), dta); - state.set_attribute(DepthWriteTransition::get_class_type(), dwa); - } - break; - default: - dxgsg_cat.error() - << "draw_pixel_buffer(): unknown buffer format" << endl; - break; - } + switch (pb->get_format()) { + case PixelBuffer::F_depth_component: + { + ColorMaskAttribute *cma = new ColorMaskAttribute; + cma->set_mask(0); + DepthTestAttribute *dta = new DepthTestAttribute; + dta->set_mode(DepthTestProperty::M_always); + DepthWriteAttribute *dwa = new DepthWriteAttribute; + dwa->set_off(); + state.set_attribute(ColorMaskTransition::get_class_type(), cma); + state.set_attribute(DepthTestTransition::get_class_type(), dta); + state.set_attribute(DepthWriteTransition::get_class_type(), dwa); + } + break; - set_state(state, false); + case PixelBuffer::F_rgb: + case PixelBuffer::F_rgb5: + case PixelBuffer::F_rgb8: + case PixelBuffer::F_rgb12: + case PixelBuffer::F_rgba: + case PixelBuffer::F_rgba4: + case PixelBuffer::F_rgba8: + case PixelBuffer::F_rgba12: + { + ColorMaskAttribute *cma = new ColorMaskAttribute; + DepthTestAttribute *dta = new DepthTestAttribute; + dta->set_mode(DepthTestProperty::M_none); + DepthWriteAttribute *dwa = new DepthWriteAttribute; + dwa->set_off(); + state.set_attribute(ColorMaskTransition::get_class_type(), cma); + state.set_attribute(DepthTestTransition::get_class_type(), dta); + state.set_attribute(DepthWriteTransition::get_class_type(), dwa); + } + break; + default: + dxgsg_cat.error() + << "draw_pixel_buffer(): unknown buffer format" << endl; + break; + } - enable_color_material(false); - set_unpack_alignment(1); + set_state(state, false); - glMatrixMode( GL_PROJECTION ); - glPushMatrix(); - glLoadIdentity(); - gluOrtho2D(0, _win->get_width(), - 0, _win->get_height()); + enable_color_material(false); + set_unpack_alignment(1); + + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glLoadIdentity(); + gluOrtho2D(0, _win->get_width(), + 0, _win->get_height()); #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "glDrawPixels(" << pb->get_xsize() << ", " << pb->get_ysize() - << ", "; - switch (get_external_image_format(pb->get_format())) { - case GL_DEPTH_COMPONENT: - dxgsg_cat.debug(false) << "GL_DEPTH_COMPONENT, "; - break; - case GL_RGB: - dxgsg_cat.debug(false) << "GL_RGB, "; - break; - case GL_RGBA: - dxgsg_cat.debug(false) << "GL_RGBA, "; - break; - default: - dxgsg_cat.debug(false) << "unknown, "; - break; - } - switch (get_image_type(pb->get_image_type())) { - case GL_UNSIGNED_BYTE: - dxgsg_cat.debug(false) << "GL_UNSIGNED_BYTE, "; - break; - case GL_float: - dxgsg_cat.debug(false) << "GL_float, "; - break; - default: - dxgsg_cat.debug(false) << "unknown, "; - break; - } - dxgsg_cat.debug(false) - << (void *)pb->_image.p() << ")" << endl; + dxgsg_cat.debug() + << "glDrawPixels(" << pb->get_xsize() << ", " << pb->get_ysize() + << ", "; + switch (get_external_image_format(pb->get_format())) { + case GL_DEPTH_COMPONENT: + dxgsg_cat.debug(false) << "GL_DEPTH_COMPONENT, "; + break; + case GL_RGB: + dxgsg_cat.debug(false) << "GL_RGB, "; + break; + case GL_RGBA: + dxgsg_cat.debug(false) << "GL_RGBA, "; + break; + default: + dxgsg_cat.debug(false) << "unknown, "; + break; + } + switch (get_image_type(pb->get_image_type())) { + case GL_UNSIGNED_BYTE: + dxgsg_cat.debug(false) << "GL_UNSIGNED_BYTE, "; + break; + case GL_float: + dxgsg_cat.debug(false) << "GL_float, "; + break; + default: + dxgsg_cat.debug(false) << "unknown, "; + break; + } + dxgsg_cat.debug(false) + << (void *)pb->_image.p() << ")" << endl; #endif - glRasterPos2i( pb->get_xorg(), pb->get_yorg() ); - glDrawPixels( pb->get_xsize(), pb->get_ysize(), - get_external_image_format(pb->get_format()), - get_image_type(pb->get_image_type()), - pb->_image.p() ); - - glMatrixMode( GL_PROJECTION ); - glPopMatrix(); + glRasterPos2i( pb->get_xorg(), pb->get_yorg() ); + glDrawPixels( pb->get_xsize(), pb->get_ysize(), + get_external_image_format(pb->get_format()), + get_image_type(pb->get_image_type()), + pb->_image.p() ); - pop_display_region(old_dr); + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + + pop_display_region(old_dr); #endif // WBD_GL_MODE } @@ -3600,10 +3541,10 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, - const RenderBuffer &rb, const NodeAttributes& na) { - activate(); - set_read_buffer(rb); - draw_pixel_buffer(pb, dr, na); + const RenderBuffer &rb, const NodeAttributes& na) { + activate(); + set_read_buffer(rb); + draw_pixel_buffer(pb, dr, na); } //////////////////////////////////////////////////////////////////// @@ -3611,15 +3552,14 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::apply_material( Material* material ) -{ - D3DMATERIAL7 cur_material; - cur_material.dcvDiffuse = *(D3DCOLORVALUE *)(material->get_diffuse().get_data()); - cur_material.dcvAmbient = *(D3DCOLORVALUE *)(material->get_ambient().get_data()); - cur_material.dcvSpecular = *(D3DCOLORVALUE *)(material->get_specular().get_data()); - cur_material.dcvEmissive = *(D3DCOLORVALUE *)(material->get_emission().get_data()); - cur_material.dvPower = material->get_shininess(); - _d3dDevice->SetMaterial(&cur_material); +void DXGraphicsStateGuardian::apply_material( Material* material ) { + D3DMATERIAL7 cur_material; + cur_material.dcvDiffuse = *(D3DCOLORVALUE *)(material->get_diffuse().get_data()); + cur_material.dcvAmbient = *(D3DCOLORVALUE *)(material->get_ambient().get_data()); + cur_material.dcvSpecular = *(D3DCOLORVALUE *)(material->get_specular().get_data()); + cur_material.dcvEmissive = *(D3DCOLORVALUE *)(material->get_emission().get_data()); + cur_material.dvPower = material->get_shininess(); + _d3dDevice->SetMaterial(&cur_material); } //////////////////////////////////////////////////////////////////// @@ -3629,38 +3569,37 @@ void DXGraphicsStateGuardian::apply_material( Material* material ) //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: apply_fog(Fog *fog) { - _d3dDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, - get_fog_mode_type(fog->get_mode())); - _d3dDevice->SetRenderState(D3DRENDERSTATE_FOGVERTEXMODE, - get_fog_mode_type(fog->get_mode())); + _d3dDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, + get_fog_mode_type(fog->get_mode())); + _d3dDevice->SetRenderState(D3DRENDERSTATE_FOGVERTEXMODE, + get_fog_mode_type(fog->get_mode())); - switch(fog->get_mode()) - { - case Fog::M_linear: - { - float fog_start = fog->get_start(); - float fog_end = fog->get_end(); - _d3dDevice->SetRenderState( D3DRENDERSTATE_FOGSTART, - *((LPDWORD) (&fog_start)) ); - _d3dDevice->SetRenderState( D3DRENDERSTATE_FOGEND, - *((LPDWORD) (&fog_end)) ); - } - break; - case Fog::M_exponential: - case Fog::M_super_exponential: - { - float fog_density = fog->get_density(); - _d3dDevice->SetRenderState( D3DRENDERSTATE_FOGDENSITY, - *((LPDWORD) (&fog_density)) ); - } - break; - case Fog::M_spline: - break; - } - - Colorf fog_colr = fog->get_color(); - _d3dDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, - D3DRGBA(fog_colr[0], fog_colr[1], fog_colr[2], 0.0)); + switch (fog->get_mode()) { + case Fog::M_linear: + { + float fog_start = fog->get_start(); + float fog_end = fog->get_end(); + _d3dDevice->SetRenderState( D3DRENDERSTATE_FOGSTART, + *((LPDWORD) (&fog_start)) ); + _d3dDevice->SetRenderState( D3DRENDERSTATE_FOGEND, + *((LPDWORD) (&fog_end)) ); + } + break; + case Fog::M_exponential: + case Fog::M_super_exponential: + { + float fog_density = fog->get_density(); + _d3dDevice->SetRenderState( D3DRENDERSTATE_FOGDENSITY, + *((LPDWORD) (&fog_density)) ); + } + break; + case Fog::M_spline: + break; + } + + Colorf fog_colr = fog->get_color(); + _d3dDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, + D3DRGBA(fog_colr[0], fog_colr[1], fog_colr[2], 0.0)); } //////////////////////////////////////////////////////////////////// @@ -3668,81 +3607,80 @@ apply_fog(Fog *fog) { // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::apply_light( PointLight* light ) -{ - // The light position will be relative to the current matrix, so - // we have to know what the current matrix is. Find a better - // solution later. +void DXGraphicsStateGuardian::apply_light( PointLight* light ) { + // The light position will be relative to the current matrix, so + // we have to know what the current matrix is. Find a better + // solution later. #ifdef WBD_GL_MODE #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "glMatrixMode(GL_MODELVIEW)" << endl; - dxgsg_cat.debug() - << "glPushMatrix()" << endl; - dxgsg_cat.debug() - << "glLoadIdentity()" << endl; + dxgsg_cat.debug() + << "glMatrixMode(GL_MODELVIEW)" << endl; + dxgsg_cat.debug() + << "glPushMatrix()" << endl; + dxgsg_cat.debug() + << "glLoadIdentity()" << endl; #endif - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); - glLoadMatrixf(LMatrix4f::convert_mat(_coordinate_system, CS_yup_left) - .get_data()); + glLoadMatrixf(LMatrix4f::convert_mat(_coordinate_system, CS_yup_left) + .get_data()); - GLenum id = get_light_id( _cur_light_id ); - Colorf black(0, 0, 0, 1); - glLightfv(id, GL_AMBIENT, black.get_data()); - glLightfv(id, GL_DIFFUSE, light->get_color().get_data()); - glLightfv(id, GL_SPECULAR, light->get_specular().get_data()); + GLenum id = get_light_id( _cur_light_id ); + Colorf black(0, 0, 0, 1); + glLightfv(id, GL_AMBIENT, black.get_data()); + glLightfv(id, GL_DIFFUSE, light->get_color().get_data()); + glLightfv(id, GL_SPECULAR, light->get_specular().get_data()); - // Position needs to specify x, y, z, and w - // w == 1 implies non-infinite position - LPoint3f pos = get_rel_pos( light, _current_projection_node ); - LPoint4f fpos( pos[0], pos[1], pos[2], 1 ); - glLightfv( id, GL_POSITION, fpos.get_data() ); + // Position needs to specify x, y, z, and w + // w == 1 implies non-infinite position + LPoint3f pos = get_rel_pos( light, _current_projection_node ); + LPoint4f fpos( pos[0], pos[1], pos[2], 1 ); + glLightfv( id, GL_POSITION, fpos.get_data() ); - // GL_SPOT_DIRECTION is not significant when cutoff == 180 + // GL_SPOT_DIRECTION is not significant when cutoff == 180 - // Exponent == 0 implies uniform light distribution - glLightf( id, GL_SPOT_EXPONENT, 0 ); + // Exponent == 0 implies uniform light distribution + glLightf( id, GL_SPOT_EXPONENT, 0 ); - // Cutoff == 180 means uniform point light source - glLightf( id, GL_SPOT_CUTOFF, 180.0 ); + // Cutoff == 180 means uniform point light source + glLightf( id, GL_SPOT_CUTOFF, 180.0 ); - glLightf( id, GL_CONSTANT_ATTENUATION, - light->get_constant_attenuation() ); - glLightf( id, GL_LINEAR_ATTENUATION, - light->get_linear_attenuation() ); - glLightf( id, GL_QUADRATIC_ATTENUATION, - light->get_quadratic_attenuation() ); + glLightf( id, GL_CONSTANT_ATTENUATION, + light->get_constant_attenuation() ); + glLightf( id, GL_LINEAR_ATTENUATION, + light->get_linear_attenuation() ); + glLightf( id, GL_QUADRATIC_ATTENUATION, + light->get_quadratic_attenuation() ); - glPopMatrix(); + glPopMatrix(); #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "glPopMatrix()" << endl; + dxgsg_cat.debug() + << "glPopMatrix()" << endl; #endif #else - D3DCOLORVALUE black; - black.r = black.g = black.b = black.a = 0.0f; - D3DLIGHT7 alight; - alight.dltType = D3DLIGHT_POINT; - alight.dcvDiffuse = *(D3DCOLORVALUE *)(light->get_color().get_data()); - alight.dcvAmbient = black ; - alight.dcvSpecular = *(D3DCOLORVALUE *)(light->get_specular().get_data()); + D3DCOLORVALUE black; + black.r = black.g = black.b = black.a = 0.0f; + D3DLIGHT7 alight; + alight.dltType = D3DLIGHT_POINT; + alight.dcvDiffuse = *(D3DCOLORVALUE *)(light->get_color().get_data()); + alight.dcvAmbient = black ; + alight.dcvSpecular = *(D3DCOLORVALUE *)(light->get_specular().get_data()); - // Position needs to specify x, y, z, and w - // w == 1 implies non-infinite position - alight.dvPosition = *(D3DVECTOR *)(get_rel_pos( light, _current_root_node ).get_data()); + // Position needs to specify x, y, z, and w + // w == 1 implies non-infinite position + alight.dvPosition = *(D3DVECTOR *)(get_rel_pos( light, _current_root_node ).get_data()); - alight.dvRange = D3DLIGHT_RANGE_MAX; - alight.dvFalloff = 1.0f; + alight.dvRange = D3DLIGHT_RANGE_MAX; + alight.dvFalloff = 1.0f; - alight.dvAttenuation0 = (D3DVALUE)light->get_constant_attenuation(); - alight.dvAttenuation1 = (D3DVALUE)light->get_linear_attenuation(); - alight.dvAttenuation2 = (D3DVALUE)light->get_quadratic_attenuation(); + alight.dvAttenuation0 = (D3DVALUE)light->get_constant_attenuation(); + alight.dvAttenuation1 = (D3DVALUE)light->get_linear_attenuation(); + alight.dvAttenuation2 = (D3DVALUE)light->get_quadratic_attenuation(); - HRESULT res = _d3dDevice->SetLight(_cur_light_id, &alight); + HRESULT res = _d3dDevice->SetLight(_cur_light_id, &alight); #endif // WBD_GL_MODE } @@ -3752,83 +3690,82 @@ void DXGraphicsStateGuardian::apply_light( PointLight* light ) // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::apply_light( DirectionalLight* light ) -{ - // The light position will be relative to the current matrix, so - // we have to know what the current matrix is. Find a better - // solution later. +void DXGraphicsStateGuardian::apply_light( DirectionalLight* light ) { + // The light position will be relative to the current matrix, so + // we have to know what the current matrix is. Find a better + // solution later. #ifdef WBD_GL_MODE #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "glMatrixMode(GL_MODELVIEW)" << endl; - dxgsg_cat.debug() - << "glPushMatrix()" << endl; - dxgsg_cat.debug() - << "glLoadIdentity()" << endl; + dxgsg_cat.debug() + << "glMatrixMode(GL_MODELVIEW)" << endl; + dxgsg_cat.debug() + << "glPushMatrix()" << endl; + dxgsg_cat.debug() + << "glLoadIdentity()" << endl; #endif - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf(LMatrix4f::convert_mat(_coordinate_system, CS_yup_left) - .get_data()); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadMatrixf(LMatrix4f::convert_mat(_coordinate_system, CS_yup_left) + .get_data()); - GLenum id = get_light_id( _cur_light_id ); - Colorf black(0, 0, 0, 1); - glLightfv(id, GL_AMBIENT, black.get_data()); - glLightfv(id, GL_DIFFUSE, light->get_color().get_data()); - glLightfv(id, GL_SPECULAR, light->get_specular().get_data()); + GLenum id = get_light_id( _cur_light_id ); + Colorf black(0, 0, 0, 1); + glLightfv(id, GL_AMBIENT, black.get_data()); + glLightfv(id, GL_DIFFUSE, light->get_color().get_data()); + glLightfv(id, GL_SPECULAR, light->get_specular().get_data()); - // Position needs to specify x, y, z, and w - // w == 0 implies light is at infinity - LPoint3f dir = get_rel_forward( light, _current_root_node, - _coordinate_system ); - LPoint4f pos( -dir[0], -dir[1], -dir[2], 0 ); - glLightfv( id, GL_POSITION, pos.get_data() ); + // Position needs to specify x, y, z, and w + // w == 0 implies light is at infinity + LPoint3f dir = get_rel_forward( light, _current_root_node, + _coordinate_system ); + LPoint4f pos( -dir[0], -dir[1], -dir[2], 0 ); + glLightfv( id, GL_POSITION, pos.get_data() ); - // GL_SPOT_DIRECTION is not significant when cutoff == 180 - // In this case, position x, y, z specifies direction + // GL_SPOT_DIRECTION is not significant when cutoff == 180 + // In this case, position x, y, z specifies direction - // Exponent == 0 implies uniform light distribution - glLightf( id, GL_SPOT_EXPONENT, 0 ); + // Exponent == 0 implies uniform light distribution + glLightf( id, GL_SPOT_EXPONENT, 0 ); - // Cutoff == 180 means uniform point light source - glLightf( id, GL_SPOT_CUTOFF, 180.0 ); + // Cutoff == 180 means uniform point light source + glLightf( id, GL_SPOT_CUTOFF, 180.0 ); - // Default attenuation values (only spotlight can modify these) - glLightf( id, GL_CONSTANT_ATTENUATION, 1 ); - glLightf( id, GL_LINEAR_ATTENUATION, 0 ); - glLightf( id, GL_QUADRATIC_ATTENUATION, 0 ); + // Default attenuation values (only spotlight can modify these) + glLightf( id, GL_CONSTANT_ATTENUATION, 1 ); + glLightf( id, GL_LINEAR_ATTENUATION, 0 ); + glLightf( id, GL_QUADRATIC_ATTENUATION, 0 ); - glPopMatrix(); + glPopMatrix(); #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "glPopMatrix()" << endl; + dxgsg_cat.debug() + << "glPopMatrix()" << endl; #endif #else // DX Directional light - D3DCOLORVALUE black; - black.r = black.g = black.b = black.a = 0.0f; - - D3DLIGHT7 alight; - ZeroMemory(&alight, sizeof(D3DLIGHT7)); + D3DCOLORVALUE black; + black.r = black.g = black.b = black.a = 0.0f; - alight.dltType = D3DLIGHT_DIRECTIONAL; - alight.dcvDiffuse = *(D3DCOLORVALUE *)(light->get_color().get_data()); - alight.dcvAmbient = black ; - alight.dcvSpecular = *(D3DCOLORVALUE *)(light->get_specular().get_data()); + D3DLIGHT7 alight; + ZeroMemory(&alight, sizeof(D3DLIGHT7)); - alight.dvDirection = *(D3DVECTOR *) - (get_rel_forward( light, _current_projection_node, CS_yup_left).get_data()); + alight.dltType = D3DLIGHT_DIRECTIONAL; + alight.dcvDiffuse = *(D3DCOLORVALUE *)(light->get_color().get_data()); + alight.dcvAmbient = black ; + alight.dcvSpecular = *(D3DCOLORVALUE *)(light->get_specular().get_data()); - alight.dvRange = D3DLIGHT_RANGE_MAX; - alight.dvFalloff = 1.0f; + alight.dvDirection = *(D3DVECTOR *) + (get_rel_forward( light, _current_projection_node, CS_yup_left).get_data()); - alight.dvAttenuation0 = 1.0f; // constant - alight.dvAttenuation1 = 0.0f; // linear - alight.dvAttenuation2 = 0.0f; // quadratic + alight.dvRange = D3DLIGHT_RANGE_MAX; + alight.dvFalloff = 1.0f; - HRESULT res = _d3dDevice->SetLight(_cur_light_id, &alight); + alight.dvAttenuation0 = 1.0f; // constant + alight.dvAttenuation1 = 0.0f; // linear + alight.dvAttenuation2 = 0.0f; // quadratic + + HRESULT res = _d3dDevice->SetLight(_cur_light_id, &alight); // _d3dDevice->LightEnable( _cur_light_id, TRUE ); // _d3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, TRUE ); - + #endif // WBD_GL_MODE } @@ -3837,83 +3774,82 @@ void DXGraphicsStateGuardian::apply_light( DirectionalLight* light ) // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::apply_light( Spotlight* light ) -{ - // The light position will be relative to the current matrix, so - // we have to know what the current matrix is. Find a better - // solution later. +void DXGraphicsStateGuardian::apply_light( Spotlight* light ) { + // The light position will be relative to the current matrix, so + // we have to know what the current matrix is. Find a better + // solution later. #ifdef WBD_GL_MODE #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "glMatrixMode(GL_MODELVIEW)" << endl; - dxgsg_cat.debug() - << "glPushMatrix()" << endl; - dxgsg_cat.debug() - << "glLoadIdentity()" << endl; + dxgsg_cat.debug() + << "glMatrixMode(GL_MODELVIEW)" << endl; + dxgsg_cat.debug() + << "glPushMatrix()" << endl; + dxgsg_cat.debug() + << "glLoadIdentity()" << endl; #endif - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf(LMatrix4f::convert_mat(_coordinate_system, CS_yup_left) - .get_data()); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadMatrixf(LMatrix4f::convert_mat(_coordinate_system, CS_yup_left) + .get_data()); - GLenum id = get_light_id( _cur_light_id ); - Colorf black(0, 0, 0, 1); - glLightfv(id, GL_AMBIENT, black.get_data()); - glLightfv(id, GL_DIFFUSE, light->get_color().get_data()); - glLightfv(id, GL_SPECULAR, light->get_specular().get_data()); + GLenum id = get_light_id( _cur_light_id ); + Colorf black(0, 0, 0, 1); + glLightfv(id, GL_AMBIENT, black.get_data()); + glLightfv(id, GL_DIFFUSE, light->get_color().get_data()); + glLightfv(id, GL_SPECULAR, light->get_specular().get_data()); - // Position needs to specify x, y, z, and w - // w == 1 implies non-infinite position - LPoint3f pos = get_rel_pos( light, _current_projection_node ); - LPoint4f fpos( pos[0], pos[1], pos[2], 1 ); - glLightfv( id, GL_POSITION, fpos.get_data() ); + // Position needs to specify x, y, z, and w + // w == 1 implies non-infinite position + LPoint3f pos = get_rel_pos( light, _current_projection_node ); + LPoint4f fpos( pos[0], pos[1], pos[2], 1 ); + glLightfv( id, GL_POSITION, fpos.get_data() ); - glLightfv( id, GL_SPOT_DIRECTION, - get_rel_forward( light, _current_projection_node, - _coordinate_system ).get_data() ); - glLightf( id, GL_SPOT_EXPONENT, light->get_exponent() ); - glLightf( id, GL_SPOT_CUTOFF, - light->get_cutoff_angle() ); - glLightf( id, GL_CONSTANT_ATTENUATION, - light->get_constant_attenuation() ); - glLightf( id, GL_LINEAR_ATTENUATION, - light->get_linear_attenuation() ); - glLightf( id, GL_QUADRATIC_ATTENUATION, - light->get_quadratic_attenuation() ); + glLightfv( id, GL_SPOT_DIRECTION, + get_rel_forward( light, _current_projection_node, + _coordinate_system ).get_data() ); + glLightf( id, GL_SPOT_EXPONENT, light->get_exponent() ); + glLightf( id, GL_SPOT_CUTOFF, + light->get_cutoff_angle() ); + glLightf( id, GL_CONSTANT_ATTENUATION, + light->get_constant_attenuation() ); + glLightf( id, GL_LINEAR_ATTENUATION, + light->get_linear_attenuation() ); + glLightf( id, GL_QUADRATIC_ATTENUATION, + light->get_quadratic_attenuation() ); - glPopMatrix(); + glPopMatrix(); #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "glPopMatrix()" << endl; + dxgsg_cat.debug() + << "glPopMatrix()" << endl; #endif #else // DX Spotlight - D3DCOLORVALUE black; - black.r = black.g = black.b = black.a = 0.0f; - - D3DLIGHT7 alight; - ZeroMemory(&alight, sizeof(D3DLIGHT7)); + D3DCOLORVALUE black; + black.r = black.g = black.b = black.a = 0.0f; - alight.dltType = D3DLIGHT_SPOT; - alight.dcvAmbient = black ; - alight.dcvDiffuse = *(D3DCOLORVALUE *)(light->get_color().get_data()); - alight.dcvSpecular = *(D3DCOLORVALUE *)(light->get_specular().get_data()); + D3DLIGHT7 alight; + ZeroMemory(&alight, sizeof(D3DLIGHT7)); - alight.dvPosition = *(D3DVECTOR *) - (get_rel_pos( light, _current_root_node ).get_data()); + alight.dltType = D3DLIGHT_SPOT; + alight.dcvAmbient = black ; + alight.dcvDiffuse = *(D3DCOLORVALUE *)(light->get_color().get_data()); + alight.dcvSpecular = *(D3DCOLORVALUE *)(light->get_specular().get_data()); - alight.dvDirection = *(D3DVECTOR *) - (get_rel_forward( light, _current_root_node, _coordinate_system).get_data()); + alight.dvPosition = *(D3DVECTOR *) + (get_rel_pos( light, _current_root_node ).get_data()); - alight.dvRange = D3DLIGHT_RANGE_MAX; - alight.dvFalloff = 1.0f; - alight.dvTheta = 0.0f; - alight.dvPhi = light->get_cutoff_angle(); + alight.dvDirection = *(D3DVECTOR *) + (get_rel_forward( light, _current_root_node, _coordinate_system).get_data()); - alight.dvAttenuation0 = (D3DVALUE)light->get_constant_attenuation(); // constant - alight.dvAttenuation1 = (D3DVALUE)light->get_linear_attenuation(); // linear - alight.dvAttenuation2 = (D3DVALUE)light->get_quadratic_attenuation();// quadratic + alight.dvRange = D3DLIGHT_RANGE_MAX; + alight.dvFalloff = 1.0f; + alight.dvTheta = 0.0f; + alight.dvPhi = light->get_cutoff_angle(); - HRESULT res = _d3dDevice->SetLight(_cur_light_id, &alight); + alight.dvAttenuation0 = (D3DVALUE)light->get_constant_attenuation(); // constant + alight.dvAttenuation1 = (D3DVALUE)light->get_linear_attenuation(); // linear + alight.dvAttenuation2 = (D3DVALUE)light->get_quadratic_attenuation();// quadratic + + HRESULT res = _d3dDevice->SetLight(_cur_light_id, &alight); #endif // WBD_GL_MODE } @@ -3923,9 +3859,8 @@ void DXGraphicsStateGuardian::apply_light( Spotlight* light ) // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::apply_light( AmbientLight* light ) -{ - _cur_ambient_light = _cur_ambient_light + light->get_color(); +void DXGraphicsStateGuardian::apply_light( AmbientLight* light ) { + _cur_ambient_light = _cur_ambient_light + light->get_color(); } //////////////////////////////////////////////////////////////////// @@ -3935,40 +3870,40 @@ void DXGraphicsStateGuardian::apply_light( AmbientLight* light ) //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_transform(const TransformAttribute *attrib) { - activate(); + activate(); #ifndef NDEBUG - if (dx_show_transforms) { + if (dx_show_transforms) { - bool lighting_was_enabled = _lighting_enabled; - bool texturing_was_enabled = _texturing_enabled; - enable_lighting(false); - enable_texturing(false); + bool lighting_was_enabled = _lighting_enabled; + bool texturing_was_enabled = _texturing_enabled; + enable_lighting(false); + enable_texturing(false); - typedef struct { - D3DVALUE x,y,z; // position - D3DVALUE nx,ny,nz; // normal - D3DCOLOR diff; // diffuse color - } VERTFORMAT; + typedef struct { + D3DVALUE x,y,z; // position + D3DVALUE nx,ny,nz; // normal + D3DCOLOR diff; // diffuse color + } VERTFORMAT; - VERTFORMAT vert_buf[] = { - {0.0, 0.0, 0.0, 0.0, -1.0, 0.0, D3DRGBA(1.0, 0.0, 0.0, 1.0)}, // red - {3.0, 0.0, 0.0, 0.0, -1.0, 0.0, D3DRGBA(1.0, 0.0, 0.0, 1.0)}, // red - {0.0, 0.0, 0.0, 0.0, -1.0, 0.0, D3DRGBA(0.0, 1.0, 0.0, 1.0)}, // grn - {0.0, 3.0, 0.0, 0.0, -1.0, 0.0, D3DRGBA(0.0, 1.0, 0.0, 1.0)}, // grn - {0.0, 0.0, 0.0, 0.0, -1.0, 0.0, D3DRGBA(0.0, 0.0, 1.0, 1.0)}, // blu - {0.0, 0.0, 3.0, 0.0, -1.0, 0.0, D3DRGBA(0.0, 0.0, 1.0, 1.0)}, // blu - }; + VERTFORMAT vert_buf[] = { + {0.0, 0.0, 0.0, 0.0, -1.0, 0.0, D3DRGBA(1.0, 0.0, 0.0, 1.0)}, // red + {3.0, 0.0, 0.0, 0.0, -1.0, 0.0, D3DRGBA(1.0, 0.0, 0.0, 1.0)}, // red + {0.0, 0.0, 0.0, 0.0, -1.0, 0.0, D3DRGBA(0.0, 1.0, 0.0, 1.0)}, // grn + {0.0, 3.0, 0.0, 0.0, -1.0, 0.0, D3DRGBA(0.0, 1.0, 0.0, 1.0)}, // grn + {0.0, 0.0, 0.0, 0.0, -1.0, 0.0, D3DRGBA(0.0, 0.0, 1.0, 1.0)}, // blu + {0.0, 0.0, 3.0, 0.0, -1.0, 0.0, D3DRGBA(0.0, 0.0, 1.0, 1.0)}, // blu + }; - _d3dDevice->DrawPrimitive(D3DPT_LINELIST, D3DFVF_DIFFUSE | D3DFVF_XYZ | D3DFVF_NORMAL, - vert_buf, 6, NULL); + _d3dDevice->DrawPrimitive(D3DPT_LINELIST, D3DFVF_DIFFUSE | D3DFVF_XYZ | D3DFVF_NORMAL, + vert_buf, 6, NULL); - enable_lighting(lighting_was_enabled); - enable_texturing(texturing_was_enabled); - } + enable_lighting(lighting_was_enabled); + enable_texturing(texturing_was_enabled); + } #endif - _d3dDevice->SetTransform(D3DTRANSFORMSTATE_WORLD/*VIEW*/, - (LPD3DMATRIX) attrib->get_matrix().get_data()); + _d3dDevice->SetTransform(D3DTRANSFORMSTATE_WORLD/*VIEW*/, + (LPD3DMATRIX) attrib->get_matrix().get_data()); } //////////////////////////////////////////////////////////////////// @@ -3978,20 +3913,20 @@ issue_transform(const TransformAttribute *attrib) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_tex_matrix(const TexMatrixAttribute *attrib) { - dxgsg_cat.fatal() << "DXGSG issue_tex_matrix unimplemented!!!"; - return; + dxgsg_cat.fatal() << "DXGSG issue_tex_matrix unimplemented!!!"; + return; - activate(); + activate(); #ifdef WBD_GL_MODE #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "glLoadMatrix(GL_TEXTURE): " << attrib->get_matrix() << endl; + dxgsg_cat.debug() + << "glLoadMatrix(GL_TEXTURE): " << attrib->get_matrix() << endl; #endif - glMatrixMode(GL_TEXTURE); - glLoadMatrixf(attrib->get_matrix().get_data()); + glMatrixMode(GL_TEXTURE); + glLoadMatrixf(attrib->get_matrix().get_data()); #else - _d3dDevice->SetTransform( D3DTRANSFORMSTATE_TEXTURE0, - (LPD3DMATRIX)attrib->get_matrix().get_data()); + _d3dDevice->SetTransform( D3DTRANSFORMSTATE_TEXTURE0, + (LPD3DMATRIX)attrib->get_matrix().get_data()); #endif // WBD_GL_MODE } @@ -4004,14 +3939,12 @@ issue_tex_matrix(const TexMatrixAttribute *attrib) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_color(const ColorAttribute *attrib) { - activate(); - if (attrib->is_on()&& attrib->is_real()) - { - _issued_color_enabled = true; - Colorf c = attrib->get_color(); - _issued_color = D3DRGBA(c[0], c[1], c[2], c[3]); - } - else _issued_color_enabled = false; + activate(); + if (attrib->is_on()&& attrib->is_real()) { + _issued_color_enabled = true; + Colorf c = attrib->get_color(); + _issued_color = D3DRGBA(c[0], c[1], c[2], c[3]); + } else _issued_color_enabled = false; } #endif @@ -4024,16 +3957,16 @@ issue_color(const ColorAttribute *attrib) { void DXGraphicsStateGuardian:: issue_texture(const TextureAttribute *attrib) { - activate(); + activate(); - if (attrib->is_on()) { - enable_texturing(true); - Texture *tex = attrib->get_texture(); - nassertv(tex != (Texture *)NULL); - tex->apply(this); - } else { - enable_texturing(false); - } + if (attrib->is_on()) { + enable_texturing(true); + Texture *tex = attrib->get_texture(); + nassertv(tex != (Texture *)NULL); + tex->apply(this); + } else { + enable_texturing(false); + } } //////////////////////////////////////////////////////////////////// @@ -4043,52 +3976,52 @@ issue_texture(const TextureAttribute *attrib) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_tex_gen(const TexGenAttribute *attrib) { - dxgsg_cat.fatal() << "DXGSG issue_tex_gen unimplemented!!!"; - return; - activate(); + dxgsg_cat.fatal() << "DXGSG issue_tex_gen unimplemented!!!"; + return; + activate(); #ifdef WBD_GL_MODE - TexGenProperty::Mode mode = attrib->get_mode(); + TexGenProperty::Mode mode = attrib->get_mode(); - switch (mode) { - case TexGenProperty::M_none: - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - glDisable(GL_TEXTURE_GEN_Q); - glDisable(GL_TEXTURE_GEN_R); - break; + switch (mode) { + case TexGenProperty::M_none: + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + glDisable(GL_TEXTURE_GEN_Q); + glDisable(GL_TEXTURE_GEN_R); + break; - case TexGenProperty::M_texture_projector: - { - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glEnable(GL_TEXTURE_GEN_Q); - glEnable(GL_TEXTURE_GEN_R); - const LMatrix4f &plane = attrib->get_plane(); - glTexGenfv(GL_S, GL_OBJECT_PLANE, plane.get_row(0).get_data()); - glTexGenfv(GL_T, GL_OBJECT_PLANE, plane.get_row(1).get_data()); - glTexGenfv(GL_R, GL_OBJECT_PLANE, plane.get_row(2).get_data()); - glTexGenfv(GL_Q, GL_OBJECT_PLANE, plane.get_row(3).get_data()); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - } - break; - - case TexGenProperty::M_sphere_map: - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glDisable(GL_TEXTURE_GEN_Q); - glDisable(GL_TEXTURE_GEN_R); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); - break; - - default: - dxgsg_cat.error() - << "Unknown texgen mode " << (int)mode << endl; - break; - } + case TexGenProperty::M_texture_projector: + { + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_Q); + glEnable(GL_TEXTURE_GEN_R); + const LMatrix4f &plane = attrib->get_plane(); + glTexGenfv(GL_S, GL_OBJECT_PLANE, plane.get_row(0).get_data()); + glTexGenfv(GL_T, GL_OBJECT_PLANE, plane.get_row(1).get_data()); + glTexGenfv(GL_R, GL_OBJECT_PLANE, plane.get_row(2).get_data()); + glTexGenfv(GL_Q, GL_OBJECT_PLANE, plane.get_row(3).get_data()); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + } + break; + + case TexGenProperty::M_sphere_map: + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glDisable(GL_TEXTURE_GEN_Q); + glDisable(GL_TEXTURE_GEN_R); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + break; + + default: + dxgsg_cat.error() + << "Unknown texgen mode " << (int)mode << endl; + break; + } #endif // WBD_GL_MODE } @@ -4099,12 +4032,12 @@ issue_tex_gen(const TexGenAttribute *attrib) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_material(const MaterialAttribute *attrib) { - activate(); - if (attrib->is_on()) { - Material *material = attrib->get_material(); - nassertv(material != (Material *)NULL); - material->apply(this); - } + activate(); + if (attrib->is_on()) { + Material *material = attrib->get_material(); + nassertv(material != (Material *)NULL); + material->apply(this); + } } //////////////////////////////////////////////////////////////////// @@ -4114,16 +4047,16 @@ issue_material(const MaterialAttribute *attrib) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_fog(const FogAttribute *attrib) { - activate(); + activate(); - if (attrib->is_on()) { - enable_fog(true); - Fog *fog = attrib->get_fog(); - nassertv(fog != (Fog *)NULL); - fog->apply(this); - } else { - enable_fog(false); - } + if (attrib->is_on()) { + enable_fog(true); + Fog *fog = attrib->get_fog(); + nassertv(fog != (Fog *)NULL); + fog->apply(this); + } else { + enable_fog(false); + } } //////////////////////////////////////////////////////////////////// @@ -4133,26 +4066,25 @@ issue_fog(const FogAttribute *attrib) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_render_mode(const RenderModeAttribute *attrib) { - activate(); + activate(); - RenderModeProperty::Mode mode = attrib->get_mode(); + RenderModeProperty::Mode mode = attrib->get_mode(); - switch(mode) - { - case RenderModeProperty::M_filled: - _d3dDevice->SetRenderState(D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID); - break; + switch (mode) { + case RenderModeProperty::M_filled: + _d3dDevice->SetRenderState(D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID); + break; - case RenderModeProperty::M_wireframe: - _d3dDevice->SetRenderState(D3DRENDERSTATE_FILLMODE, D3DFILL_WIREFRAME); + case RenderModeProperty::M_wireframe: + _d3dDevice->SetRenderState(D3DRENDERSTATE_FILLMODE, D3DFILL_WIREFRAME); // call_glLineWidth(attrib->get_line_width()); - break; + break; - default: - dxgsg_cat.error() - << "Unknown render mode " << (int)mode << endl; - } + default: + dxgsg_cat.error() + << "Unknown render mode " << (int)mode << endl; + } } //////////////////////////////////////////////////////////////////// @@ -4160,95 +4092,94 @@ issue_render_mode(const RenderModeAttribute *attrib) { // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::issue_light(const LightAttribute *attrib ) -{ - nassertv(attrib->get_properties_is_on()); - activate(); +void DXGraphicsStateGuardian::issue_light(const LightAttribute *attrib ) { + nassertv(attrib->get_properties_is_on()); + activate(); - // Initialize the current ambient light total and currently enabled - // light list - _cur_ambient_light.set(0, 0, 0, 1); - int i; - for (i = 0; i < _max_lights; i++) - _cur_light_enabled[i] = false; + // Initialize the current ambient light total and currently enabled + // light list + _cur_ambient_light.set(0, 0, 0, 1); + int i; + for (i = 0; i < _max_lights; i++) + _cur_light_enabled[i] = false; - int num_enabled = 0; - LightAttribute::const_iterator li; - for (li = attrib->begin(); li != attrib->end(); ++li) { - _cur_light_id = -1; - num_enabled++; - enable_lighting(true); - Light *light = (*li); - nassertv(light != (Light *)NULL); + int num_enabled = 0; + LightAttribute::const_iterator li; + for (li = attrib->begin(); li != attrib->end(); ++li) { + _cur_light_id = -1; + num_enabled++; + enable_lighting(true); + Light *light = (*li); + nassertv(light != (Light *)NULL); - // Ambient lights don't require specific light ids - // Simply add in the ambient contribution to the current total - if (light->get_light_type() == AmbientLight::get_class_type()) { - light->apply(this); - // We need to indicate that no light id is necessary because - // it's an ambient light - _cur_light_id = -2; - } + // Ambient lights don't require specific light ids + // Simply add in the ambient contribution to the current total + if (light->get_light_type() == AmbientLight::get_class_type()) { + light->apply(this); + // We need to indicate that no light id is necessary because + // it's an ambient light + _cur_light_id = -2; + } - // Check to see if this light has already been bound to an id - for (i = 0; i < _max_lights; i++) { - if (_available_light_ids[i] == light) { - // Light has already been bound to an id, we only need - // to enable the light, not apply it - _cur_light_id = -2; - if (enable_light(i, true)) _cur_light_enabled[i] = true; - break; - } - } - - // See if there are any unbound light ids - if (_cur_light_id == -1) { - for (i = 0; i < _max_lights; i++) { - if (_available_light_ids[i] == NULL) { - _available_light_ids[i] = light; - _cur_light_id = i; - break; - } - } - } - - // If there were no unbound light ids, see if we can replace - // a currently unused but previously bound id - if (_cur_light_id == -1) { - for (i = 0; i < _max_lights; i++) { - if (attrib->is_off(_available_light_ids[i])) { - _available_light_ids[i] = light; - _cur_light_id = i; - break; - } - } - } + // Check to see if this light has already been bound to an id + for (i = 0; i < _max_lights; i++) { + if (_available_light_ids[i] == light) { + // Light has already been bound to an id, we only need + // to enable the light, not apply it + _cur_light_id = -2; + if (enable_light(i, true)) _cur_light_enabled[i] = true; + break; + } + } - if (_cur_light_id >= 0) { - if (enable_light(_cur_light_id, true)) _cur_light_enabled[_cur_light_id] = true; - - // We need to do something different for each type of light - light->apply(this); - } else if (_cur_light_id == -1) { - dxgsg_cat.error() - << "issue_light() - failed to bind light to id" << endl; - } - } + // See if there are any unbound light ids + if (_cur_light_id == -1) { + for (i = 0; i < _max_lights; i++) { + if (_available_light_ids[i] == NULL) { + _available_light_ids[i] = light; + _cur_light_id = i; + break; + } + } + } - // Disable all unused lights - for (i = 0; i < _max_lights; i++) { - if (_cur_light_enabled[i] == false) - enable_light(i, false); - } + // If there were no unbound light ids, see if we can replace + // a currently unused but previously bound id + if (_cur_light_id == -1) { + for (i = 0; i < _max_lights; i++) { + if (attrib->is_off(_available_light_ids[i])) { + _available_light_ids[i] = light; + _cur_light_id = i; + break; + } + } + } - // If no lights were enabled, disable lighting - if (num_enabled == 0) { - enable_lighting(false); - enable_color_material(false); - } else { - call_dxLightModelAmbient(_cur_ambient_light); - enable_color_material(true); - } + if (_cur_light_id >= 0) { + if (enable_light(_cur_light_id, true)) _cur_light_enabled[_cur_light_id] = true; + + // We need to do something different for each type of light + light->apply(this); + } else if (_cur_light_id == -1) { + dxgsg_cat.error() + << "issue_light() - failed to bind light to id" << endl; + } + } + + // Disable all unused lights + for (i = 0; i < _max_lights; i++) { + if (_cur_light_enabled[i] == false) + enable_light(i, false); + } + + // If no lights were enabled, disable lighting + if (num_enabled == 0) { + enable_lighting(false); + enable_color_material(false); + } else { + call_dxLightModelAmbient(_cur_ambient_light); + enable_color_material(true); + } } @@ -4259,9 +4190,8 @@ void DXGraphicsStateGuardian::issue_light(const LightAttribute *attrib ) // Description: //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: -reset_ambient() -{ - _lmodel_ambient += 2.0f; +reset_ambient() { + _lmodel_ambient += 2.0f; } @@ -4272,123 +4202,123 @@ reset_ambient() //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_color_blend(const ColorBlendAttribute *attrib) { - activate(); - ColorBlendProperty::Mode mode = attrib->get_mode(); + activate(); + ColorBlendProperty::Mode mode = attrib->get_mode(); - switch (mode) { - case ColorBlendProperty::M_none: - enable_blend(false); - break; - case ColorBlendProperty::M_multiply: - enable_blend(true); - call_dxBlendFunc(D3DBLEND_DESTCOLOR, D3DBLEND_ZERO); - break; - case ColorBlendProperty::M_add: - enable_blend(true); - call_dxBlendFunc(D3DBLEND_ONE, D3DBLEND_ONE); - break; - case ColorBlendProperty::M_multiply_add: - enable_blend(true); - call_dxBlendFunc(D3DBLEND_DESTCOLOR, D3DBLEND_ONE); - break; - case ColorBlendProperty::M_alpha: - enable_blend(true); - call_dxBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); - break; - default: - dxgsg_cat.error() - << "Unknown color blend mode " << (int)mode << endl; - break; - } + switch (mode) { + case ColorBlendProperty::M_none: + enable_blend(false); + break; + case ColorBlendProperty::M_multiply: + enable_blend(true); + call_dxBlendFunc(D3DBLEND_DESTCOLOR, D3DBLEND_ZERO); + break; + case ColorBlendProperty::M_add: + enable_blend(true); + call_dxBlendFunc(D3DBLEND_ONE, D3DBLEND_ONE); + break; + case ColorBlendProperty::M_multiply_add: + enable_blend(true); + call_dxBlendFunc(D3DBLEND_DESTCOLOR, D3DBLEND_ONE); + break; + case ColorBlendProperty::M_alpha: + enable_blend(true); + call_dxBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); + break; + default: + dxgsg_cat.error() + << "Unknown color blend mode " << (int)mode << endl; + break; + } } void DXGraphicsStateGuardian::SetTextureBlendMode(TextureApplyProperty::Mode TexBlendMode,bool bCanJustEnable) { /*class EXPCL_PANDA TextureApplyProperty { enum Mode { - M_modulate,M_decal,M_blend,M_replace,M_add}; + M_modulate,M_decal,M_blend,M_replace,M_add}; */ - static D3DTEXTUREOP TexBlendColorOp1[/*TextureApplyProperty::Mode */ 10] = - {D3DTOP_MODULATE,D3DTOP_BLENDTEXTUREALPHA,D3DTOP_MODULATE,D3DTOP_SELECTARG1,D3DTOP_ADD}; + static D3DTEXTUREOP TexBlendColorOp1[/*TextureApplyProperty::Mode */ 10] = + {D3DTOP_MODULATE,D3DTOP_BLENDTEXTUREALPHA,D3DTOP_MODULATE,D3DTOP_SELECTARG1,D3DTOP_ADD}; //if bCanJustEnable, then we only need to make sure ColorOp is turned on and set properly - if(bCanJustEnable && (TexBlendMode==_CurTexBlendMode)) { - // just reset COLOROP 0 to enable pipeline, rest is already set properly - _d3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, TexBlendColorOp1[TexBlendMode] ); - return; - } + if (bCanJustEnable && (TexBlendMode==_CurTexBlendMode)) { + // just reset COLOROP 0 to enable pipeline, rest is already set properly + _d3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, TexBlendColorOp1[TexBlendMode] ); + return; + } - _d3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, TexBlendColorOp1[TexBlendMode] ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, TexBlendColorOp1[TexBlendMode] ); - switch(TexBlendMode) { + switch (TexBlendMode) { + + case TextureApplyProperty::M_modulate: + // emulates GL_MODULATE glTexEnv mode + // want to multiply tex-color*pixel color to emulate GL modulate blend (see glTexEnv) + _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); - case TextureApplyProperty::M_modulate: - // emulates GL_MODULATE glTexEnv mode - // want to multiply tex-color*pixel color to emulate GL modulate blend (see glTexEnv) - _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); + break; + case TextureApplyProperty::M_decal: + // emulates GL_DECAL glTexEnv mode + _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - break; - case TextureApplyProperty::M_decal: - // emulates GL_DECAL glTexEnv mode - _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); + break; + case TextureApplyProperty::M_replace: + _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - break; - case TextureApplyProperty::M_replace: - _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + break; + case TextureApplyProperty::M_add: + _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - break; - case TextureApplyProperty::M_add: - _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + // since I'm making up 'add' mode, use modulate. "adding" alpha never makes sense right? + _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); - // since I'm making up 'add' mode, use modulate. "adding" alpha never makes sense right? - _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); - - break; - case TextureApplyProperty::M_blend: - dxgsg_cat.error() - << "Impossible to emulate GL_BLEND in DX exactly " << (int) TexBlendMode << endl; + break; + case TextureApplyProperty::M_blend: + dxgsg_cat.error() + << "Impossible to emulate GL_BLEND in DX exactly " << (int) TexBlendMode << endl; /* - // emulate GL_BLEND glTexEnv - - GL requires 2 independent operations on 3 input vars for this mode - DX texture pipeline requires re-using input of last stage on each new op, so I dont think - exact emulation is possible - _d3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE | D3DTA_COMPLEMENT ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + // emulate GL_BLEND glTexEnv + + GL requires 2 independent operations on 3 input vars for this mode + DX texture pipeline requires re-using input of last stage on each new op, so I dont think + exact emulation is possible + _d3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE | D3DTA_COMPLEMENT ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + _d3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); - need to SetTexture(1,tex) also - _d3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); wrong - _d3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - _d3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_TFACTOR ); + need to SetTexture(1,tex) also + _d3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); wrong + _d3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + _d3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_TFACTOR ); - _d3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); - _d3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_CURRENT ); + _d3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + _d3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_CURRENT ); */ - break; - default: - dxgsg_cat.error() << "Unknown texture blend mode " << (int) TexBlendMode << endl; - break; - } + break; + default: + dxgsg_cat.error() << "Unknown texture blend mode " << (int) TexBlendMode << endl; + break; + } } @@ -4399,17 +4329,17 @@ void DXGraphicsStateGuardian::SetTextureBlendMode(TextureApplyProperty::Mode Tex //////////////////////////////////////////////////////////////////// INLINE void DXGraphicsStateGuardian:: enable_texturing(bool val) { - if (_texturing_enabled != val) { - _texturing_enabled = val; - } + if (_texturing_enabled != val) { + _texturing_enabled = val; + } // assert(_pCurTexContext!=NULL); we're definitely called with it NULL for both true and false - if((val == FALSE) || (_pCurTexContext==NULL)) { - _d3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE); - } else { - SetTextureBlendMode(_CurTexBlendMode,TRUE); - } + if ((val == FALSE) || (_pCurTexContext==NULL)) { + _d3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE); + } else { + SetTextureBlendMode(_CurTexBlendMode,TRUE); + } } //////////////////////////////////////////////////////////////////// @@ -4420,13 +4350,13 @@ enable_texturing(bool val) { void DXGraphicsStateGuardian:: issue_texture_apply(const TextureApplyAttribute *attrib) { - _CurTexBlendMode = attrib->get_mode(); + _CurTexBlendMode = attrib->get_mode(); - if(!_texturing_enabled) { - return; - } + if (!_texturing_enabled) { + return; + } - SetTextureBlendMode(_CurTexBlendMode,FALSE); + SetTextureBlendMode(_CurTexBlendMode,FALSE); } //////////////////////////////////////////////////////////////////// @@ -4436,8 +4366,8 @@ issue_texture_apply(const TextureApplyAttribute *attrib) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_color_mask(const ColorMaskAttribute *attrib) { - dxgsg_cat.fatal() << "DXGSG issue_color_mask unimplemented (not implementable on DX7)!!!"; - return; + dxgsg_cat.fatal() << "DXGSG issue_color_mask unimplemented (not implementable on DX7)!!!"; + return; } //////////////////////////////////////////////////////////////////// @@ -4447,20 +4377,18 @@ issue_color_mask(const ColorMaskAttribute *attrib) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_depth_test(const DepthTestAttribute *attrib) { - activate(); + activate(); - DepthTestProperty::Mode mode = attrib->get_mode(); + DepthTestProperty::Mode mode = attrib->get_mode(); - if (mode == DepthTestProperty::M_none) - { - _depth_test_enabled = false; - _d3dDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_FALSE); - } - else { - _depth_test_enabled = true; - _d3dDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_TRUE); - _d3dDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, get_depth_func_type(mode)); - } + if (mode == DepthTestProperty::M_none) { + _depth_test_enabled = false; + _d3dDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_FALSE); + } else { + _depth_test_enabled = true; + _d3dDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_TRUE); + _d3dDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, get_depth_func_type(mode)); + } } //////////////////////////////////////////////////////////////////// @@ -4470,8 +4398,8 @@ issue_depth_test(const DepthTestAttribute *attrib) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_depth_write(const DepthWriteAttribute *attrib) { - activate(); - _d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, attrib->is_on()); + activate(); + _d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, attrib->is_on()); } //////////////////////////////////////////////////////////////////// @@ -4481,19 +4409,19 @@ issue_depth_write(const DepthWriteAttribute *attrib) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_stencil(const StencilAttribute *attrib) { - activate(); + activate(); - StencilProperty::Mode mode = attrib->get_mode(); - if (mode == StencilProperty::M_none) { - enable_stencil_test(false); + StencilProperty::Mode mode = attrib->get_mode(); + if (mode == StencilProperty::M_none) { + enable_stencil_test(false); - } else { - enable_stencil_test(true); - _d3dDevice->SetRenderState(D3DRENDERSTATE_STENCILFUNC, get_stencil_func_type(mode)); - _d3dDevice->SetRenderState(D3DRENDERSTATE_STENCILPASS, get_stencil_action_type(attrib->get_action())); - _d3dDevice->SetRenderState(D3DRENDERSTATE_STENCILFAIL, get_stencil_action_type(attrib->get_action())); - _d3dDevice->SetRenderState(D3DRENDERSTATE_STENCILZFAIL, get_stencil_action_type(attrib->get_action())); - } + } else { + enable_stencil_test(true); + _d3dDevice->SetRenderState(D3DRENDERSTATE_STENCILFUNC, get_stencil_func_type(mode)); + _d3dDevice->SetRenderState(D3DRENDERSTATE_STENCILPASS, get_stencil_action_type(attrib->get_action())); + _d3dDevice->SetRenderState(D3DRENDERSTATE_STENCILFAIL, get_stencil_action_type(attrib->get_action())); + _d3dDevice->SetRenderState(D3DRENDERSTATE_STENCILZFAIL, get_stencil_action_type(attrib->get_action())); + } } //////////////////////////////////////////////////////////////////// @@ -4503,29 +4431,29 @@ issue_stencil(const StencilAttribute *attrib) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_cull_face(const CullFaceAttribute *attrib) { - activate(); + activate(); - CullFaceProperty::Mode mode = attrib->get_mode(); + CullFaceProperty::Mode mode = attrib->get_mode(); - switch (mode) { - case CullFaceProperty::M_cull_none: - _d3dDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); - break; - case CullFaceProperty::M_cull_clockwise: - _d3dDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW); - break; - case CullFaceProperty::M_cull_counter_clockwise: - _d3dDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CCW); - break; - case CullFaceProperty::M_cull_all: - dxgsg_cat.warning() << "M_cull_all is invalid for DX GSG renderer, using CULL_CCW \n"; - _d3dDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CCW); - break; - default: - dxgsg_cat.error() - << "invalid cull face mode " << (int)mode << endl; - break; - } + switch (mode) { + case CullFaceProperty::M_cull_none: + _d3dDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); + break; + case CullFaceProperty::M_cull_clockwise: + _d3dDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW); + break; + case CullFaceProperty::M_cull_counter_clockwise: + _d3dDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CCW); + break; + case CullFaceProperty::M_cull_all: + dxgsg_cat.warning() << "M_cull_all is invalid for DX GSG renderer, using CULL_CCW \n"; + _d3dDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CCW); + break; + default: + dxgsg_cat.error() + << "invalid cull face mode " << (int)mode << endl; + break; + } } //////////////////////////////////////////////////////////////////// @@ -4534,83 +4462,82 @@ issue_cull_face(const CullFaceAttribute *attrib) { // Description: //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: -issue_clip_plane(const ClipPlaneAttribute *attrib) -{ - activate(); +issue_clip_plane(const ClipPlaneAttribute *attrib) { + activate(); - // Initialize the currently enabled clip plane list - int i; - for (i = 0; i < _max_clip_planes; i++) - _cur_clip_plane_enabled[i] = false; + // Initialize the currently enabled clip plane list + int i; + for (i = 0; i < _max_clip_planes; i++) + _cur_clip_plane_enabled[i] = false; - int num_enabled = 0; - ClipPlaneAttribute::const_iterator pi; - for (pi = attrib->begin(); pi != attrib->end(); ++pi) { - PlaneNode *plane_node; - DCAST_INTO_V(plane_node, (*pi)); - nassertv(plane_node != (PlaneNode *)NULL); + int num_enabled = 0; + ClipPlaneAttribute::const_iterator pi; + for (pi = attrib->begin(); pi != attrib->end(); ++pi) { + PlaneNode *plane_node; + DCAST_INTO_V(plane_node, (*pi)); + nassertv(plane_node != (PlaneNode *)NULL); - _cur_clip_plane_id = -1; - num_enabled++; - - // Check to see if this clip plane has already been bound to an id - for (i = 0; i < _max_clip_planes; i++) { - if (_available_clip_plane_ids[i] == plane_node) { - // Clip plane has already been bound to an id, we only need - // to enable the clip plane, not apply it - _cur_clip_plane_id = -2; - enable_clip_plane(i, true); - _cur_clip_plane_enabled[i] = true; - break; - } - } + _cur_clip_plane_id = -1; + num_enabled++; - // See if there are any unbound clip plane ids - if (_cur_clip_plane_id == -1) { - for (i = 0; i < _max_clip_planes; i++) { - if (_available_clip_plane_ids[i] == NULL) { - _available_clip_plane_ids[i] = plane_node; - _cur_clip_plane_id = i; - break; - } - } - } - - // If there were no unbound clip plane ids, see if we can replace - // a currently unused but previously bound id - if (_cur_clip_plane_id == -1) { - for (i = 0; i < _max_clip_planes; i++) { - if (attrib->is_off(_available_clip_plane_ids[i])) { - _available_clip_plane_ids[i] = plane_node; - _cur_clip_plane_id = i; - break; - } - } - } - - if (_cur_clip_plane_id >= 0) { - enable_clip_plane(_cur_clip_plane_id, true); - _cur_clip_plane_enabled[_cur_clip_plane_id] = true; - const Planef clip_plane = plane_node->get_plane(); + // Check to see if this clip plane has already been bound to an id + for (i = 0; i < _max_clip_planes; i++) { + if (_available_clip_plane_ids[i] == plane_node) { + // Clip plane has already been bound to an id, we only need + // to enable the clip plane, not apply it + _cur_clip_plane_id = -2; + enable_clip_plane(i, true); + _cur_clip_plane_enabled[i] = true; + break; + } + } - D3DVALUE equation[4]; - equation[0] = clip_plane._a; - equation[1] = clip_plane._b; - equation[2] = clip_plane._c; - equation[3] = clip_plane._d; - _d3dDevice->SetClipPlane(_cur_clip_plane_id, equation); + // See if there are any unbound clip plane ids + if (_cur_clip_plane_id == -1) { + for (i = 0; i < _max_clip_planes; i++) { + if (_available_clip_plane_ids[i] == NULL) { + _available_clip_plane_ids[i] = plane_node; + _cur_clip_plane_id = i; + break; + } + } + } - } else if (_cur_clip_plane_id == -1) { - dxgsg_cat.error() - << "issue_clip_plane() - failed to bind clip plane to id" << endl; - } - } + // If there were no unbound clip plane ids, see if we can replace + // a currently unused but previously bound id + if (_cur_clip_plane_id == -1) { + for (i = 0; i < _max_clip_planes; i++) { + if (attrib->is_off(_available_clip_plane_ids[i])) { + _available_clip_plane_ids[i] = plane_node; + _cur_clip_plane_id = i; + break; + } + } + } - // Disable all unused clip planes - for (i = 0; i < _max_clip_planes; i++) { - if (_cur_clip_plane_enabled[i] == false) - enable_clip_plane(i, false); - } + if (_cur_clip_plane_id >= 0) { + enable_clip_plane(_cur_clip_plane_id, true); + _cur_clip_plane_enabled[_cur_clip_plane_id] = true; + const Planef clip_plane = plane_node->get_plane(); + + D3DVALUE equation[4]; + equation[0] = clip_plane._a; + equation[1] = clip_plane._b; + equation[2] = clip_plane._c; + equation[3] = clip_plane._d; + _d3dDevice->SetClipPlane(_cur_clip_plane_id, equation); + + } else if (_cur_clip_plane_id == -1) { + dxgsg_cat.error() + << "issue_clip_plane() - failed to bind clip plane to id" << endl; + } + } + + // Disable all unused clip planes + for (i = 0; i < _max_clip_planes; i++) { + if (_cur_clip_plane_enabled[i] == false) + enable_clip_plane(i, false); + } } //////////////////////////////////////////////////////////////////// @@ -4619,58 +4546,57 @@ issue_clip_plane(const ClipPlaneAttribute *attrib) // Description: //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: -issue_transparency(const TransparencyAttribute *attrib ) -{ - activate(); +issue_transparency(const TransparencyAttribute *attrib ) { + activate(); - TransparencyProperty::Mode mode = attrib->get_mode(); + TransparencyProperty::Mode mode = attrib->get_mode(); - switch (mode) { - case TransparencyProperty::M_none: - enable_multisample_alpha_one(false); - enable_multisample_alpha_mask(false); - enable_blend(false); - enable_alpha_test(false); - break; - case TransparencyProperty::M_alpha: - case TransparencyProperty::M_alpha_sorted: - // Should we really have an "alpha" and an "alpha_sorted" mode, - // like Performer does? (The difference is that "alpha" is with - // the write to the depth buffer disabled.) Or should we just use - // the separate depth write transition to control this? Doing it - // implicitly requires a bit more logic here and in the state - // management; for now we require the user to explicitly turn off - // the depth write. - enable_multisample_alpha_one(false); - enable_multisample_alpha_mask(false); - enable_blend(true); - enable_alpha_test(false); - call_dxBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); - break; - case TransparencyProperty::M_multisample: - enable_multisample_alpha_one(true); - enable_multisample_alpha_mask(true); - enable_blend(false); - enable_alpha_test(false); - break; - case TransparencyProperty::M_multisample_mask: - enable_multisample_alpha_one(false); - enable_multisample_alpha_mask(true); - enable_blend(false); - enable_alpha_test(false); - break; - case TransparencyProperty::M_binary: - enable_multisample_alpha_one(false); - enable_multisample_alpha_mask(false); - enable_blend(false); - enable_alpha_test(true); - call_dxAlphaFunc(D3DCMP_EQUAL, 1); - break; - default: - dxgsg_cat.error() - << "invalid transparency mode " << (int)mode << endl; - break; - } + switch (mode) { + case TransparencyProperty::M_none: + enable_multisample_alpha_one(false); + enable_multisample_alpha_mask(false); + enable_blend(false); + enable_alpha_test(false); + break; + case TransparencyProperty::M_alpha: + case TransparencyProperty::M_alpha_sorted: + // Should we really have an "alpha" and an "alpha_sorted" mode, + // like Performer does? (The difference is that "alpha" is with + // the write to the depth buffer disabled.) Or should we just use + // the separate depth write transition to control this? Doing it + // implicitly requires a bit more logic here and in the state + // management; for now we require the user to explicitly turn off + // the depth write. + enable_multisample_alpha_one(false); + enable_multisample_alpha_mask(false); + enable_blend(true); + enable_alpha_test(false); + call_dxBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); + break; + case TransparencyProperty::M_multisample: + enable_multisample_alpha_one(true); + enable_multisample_alpha_mask(true); + enable_blend(false); + enable_alpha_test(false); + break; + case TransparencyProperty::M_multisample_mask: + enable_multisample_alpha_one(false); + enable_multisample_alpha_mask(true); + enable_blend(false); + enable_alpha_test(false); + break; + case TransparencyProperty::M_binary: + enable_multisample_alpha_one(false); + enable_multisample_alpha_mask(false); + enable_blend(false); + enable_alpha_test(true); + call_dxAlphaFunc(D3DCMP_EQUAL, 1); + break; + default: + dxgsg_cat.error() + << "invalid transparency mode " << (int)mode << endl; + break; + } } //////////////////////////////////////////////////////////////////// @@ -4680,8 +4606,8 @@ issue_transparency(const TransparencyAttribute *attrib ) //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_linesmooth(const LinesmoothAttribute *attrib) { - activate(); - enable_line_smooth(attrib->is_on()); + activate(); + enable_line_smooth(attrib->is_on()); } //////////////////////////////////////////////////////////////////// @@ -4691,7 +4617,7 @@ issue_linesmooth(const LinesmoothAttribute *attrib) { //////////////////////////////////////////////////////////////////// INLINE bool DXGraphicsStateGuardian:: wants_normals() const { - return (_lighting_enabled || _normals_enabled); + return(_lighting_enabled || _normals_enabled); } //////////////////////////////////////////////////////////////////// @@ -4701,7 +4627,7 @@ wants_normals() const { //////////////////////////////////////////////////////////////////// INLINE bool DXGraphicsStateGuardian:: wants_texcoords() const { - return _texturing_enabled; + return _texturing_enabled; } //////////////////////////////////////////////////////////////////// @@ -4711,21 +4637,21 @@ wants_texcoords() const { // commands, false otherwise. //////////////////////////////////////////////////////////////////// INLINE bool DXGraphicsStateGuardian:: -wants_colors() const { - // If we have scene graph color enabled, return false to indicate we - // shouldn't bother issuing geometry color commands. +wants_colors() const { + // If we have scene graph color enabled, return false to indicate we + // shouldn't bother issuing geometry color commands. - const ColorAttribute *catt; - if (!get_attribute_into(catt, _state, ColorTransition::get_class_type())) { - // No scene graph color at all. - return true; - } + const ColorAttribute *catt; + if (!get_attribute_into(catt, _state, ColorTransition::get_class_type())) { + // No scene graph color at all. + return true; + } - // We should issue geometry colors only if the scene graph color is off. - if(catt->is_off() || (!catt->is_real())) - return true; + // We should issue geometry colors only if the scene graph color is off. + if (catt->is_off() || (!catt->is_real())) + return true; - return false; + return false; } //////////////////////////////////////////////////////////////////// @@ -4740,35 +4666,36 @@ wants_colors() const { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: begin_decal(GeomNode *base_geom) { - nassertv(base_geom != (GeomNode *)NULL); + nassertv(base_geom != (GeomNode *)NULL); - _decal_level++; - nassertv(4*_decal_level < 16); + _decal_level++; + nassertv(4*_decal_level < 16); #ifndef DISABLE_POLYGON_OFFSET_DECALING - if (dx_decal_type == GDT_offset) { + if (dx_decal_type == GDT_offset) { #define POLYGON_OFFSET_MULTIPLIER 2 - // Just draw the base geometry normally. - base_geom->draw(this); - _d3dDevice->SetRenderState(D3DRENDERSTATE_ZBIAS, POLYGON_OFFSET_MULTIPLIER * _decal_level); // _decal_level better not be higher than 8! - } else + + // Just draw the base geometry normally. + base_geom->draw(this); + _d3dDevice->SetRenderState(D3DRENDERSTATE_ZBIAS, POLYGON_OFFSET_MULTIPLIER * _decal_level); // _decal_level better not be higher than 8! + } else #endif - { - if (_decal_level > 1) - base_geom->draw(this); // If we're already decaling, just draw the geometry. - else { - // First turn off writing the depth buffer to render the base geometry. - _d3dDevice->GetRenderState(D3DRENDERSTATE_ZWRITEENABLE, (unsigned long *)&_depth_write_enabled); //save cur val - _d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); - - // Now render the base geometry. - base_geom->draw(this); - - // Render all of the decal geometry, too. We'll keep the depth - // buffer write off during this. - } - } + { + if (_decal_level > 1) + base_geom->draw(this); // If we're already decaling, just draw the geometry. + else { + // First turn off writing the depth buffer to render the base geometry. + _d3dDevice->GetRenderState(D3DRENDERSTATE_ZWRITEENABLE, (unsigned long *)&_depth_write_enabled); //save cur val + _d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); + + // Now render the base geometry. + base_geom->draw(this); + + // Render all of the decal geometry, too. We'll keep the depth + // buffer write off during this. + } + } } //////////////////////////////////////////////////////////////////// @@ -4780,86 +4707,86 @@ begin_decal(GeomNode *base_geom) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: end_decal(GeomNode *base_geom) { - nassertv(base_geom != (GeomNode *)NULL); + nassertv(base_geom != (GeomNode *)NULL); - _decal_level--; + _decal_level--; // nassertv(_decal_level >= 1); #ifndef DISABLE_POLYGON_OFFSET_DECALING - if (dx_decal_type == GDT_offset) { - // Restore the Zbias offset. - _d3dDevice->SetRenderState(D3DRENDERSTATE_ZBIAS, POLYGON_OFFSET_MULTIPLIER * _decal_level); // _decal_level better not be higher than 8! - } else + if (dx_decal_type == GDT_offset) { + // Restore the Zbias offset. + _d3dDevice->SetRenderState(D3DRENDERSTATE_ZBIAS, POLYGON_OFFSET_MULTIPLIER * _decal_level); // _decal_level better not be higher than 8! + } else #endif - { // for GDT_mask - if (_decal_level == 0) { - // Now we need to re-render the base geometry with the depth write - // on and the color mask off, so we update the depth buffer - // properly. - bool was_textured = _texturing_enabled; - bool was_blend = _blend_enabled; - D3DBLEND old_blend_source_func = _blend_source_func; - D3DBLEND old_blend_dest_func = _blend_dest_func; + { // for GDT_mask + if (_decal_level == 0) { + // Now we need to re-render the base geometry with the depth write + // on and the color mask off, so we update the depth buffer + // properly. + bool was_textured = _texturing_enabled; + bool was_blend = _blend_enabled; + D3DBLEND old_blend_source_func = _blend_source_func; + D3DBLEND old_blend_dest_func = _blend_dest_func; - // Enable the writing to the depth buffer. - _d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE); + // Enable the writing to the depth buffer. + _d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE); - // Disable the writing to the color buffer, however we have to - // do this. (I don't think this is possible in DX without blending.) - if (dx_decal_type == GDT_blend) { - // Expensive. - enable_blend(true); - call_dxBlendFunc(D3DBLEND_ZERO, D3DBLEND_ONE); - } + // Disable the writing to the color buffer, however we have to + // do this. (I don't think this is possible in DX without blending.) + if (dx_decal_type == GDT_blend) { + // Expensive. + enable_blend(true); + call_dxBlendFunc(D3DBLEND_ZERO, D3DBLEND_ONE); + } - #if(DIRECT3D_VERSION < 0x700) - else { // dx7 doesn't support planemask rstate - // note: not saving current planemask val, assumes this is always all 1's. should be ok - _d3dDevice->SetRenderState(D3DRENDERSTATE_PLANEMASK,0x0); // note PLANEMASK is supposedly obsolete for DX7 - } - #endif +#if(DIRECT3D_VERSION < 0x700) + else { // dx7 doesn't support planemask rstate + // note: not saving current planemask val, assumes this is always all 1's. should be ok + _d3dDevice->SetRenderState(D3DRENDERSTATE_PLANEMASK,0x0); // note PLANEMASK is supposedly obsolete for DX7 + } +#endif // Note: For DX8, use D3DRS_COLORWRITEENABLE (check D3DPMISCCAPS_COLORWRITEENABLE first) - // No need to have texturing on for this. - enable_texturing(false); - - base_geom->draw(this); - - // Finally, restore the depth write and color mask states to the - // way they're supposed to be. + // No need to have texturing on for this. + enable_texturing(false); + + base_geom->draw(this); + + // Finally, restore the depth write and color mask states to the + // way they're supposed to be. /* - DepthWriteAttribute *depth_write; - if (get_attribute_into(depth_write, _state, - DepthWriteTransition::get_class_type())) - issue_depth_write(depth_write); + DepthWriteAttribute *depth_write; + if (get_attribute_into(depth_write, _state, + DepthWriteTransition::get_class_type())) + issue_depth_write(depth_write); - ColorMaskAttribute *color_mask; - if (get_attribute_into(color_mask, _state, - ColorMaskTransition::get_class_type())) { - issue_color_mask(color_mask); - } else { + ColorMaskAttribute *color_mask; + if (get_attribute_into(color_mask, _state, + ColorMaskTransition::get_class_type())) { + issue_color_mask(color_mask); + } else { - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - } + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + } */ - if (dx_decal_type == GDT_blend) { - enable_blend(was_blend); - if (was_blend) - call_dxBlendFunc(old_blend_source_func, old_blend_dest_func); - } - #if(DIRECT3D_VERSION < 0x700) - else { - _d3dDevice->SetRenderState(D3DRENDERSTATE_PLANEMASK,0xFFFFFFFF); // this is unlikely to work due to poor driver support - } - #endif + if (dx_decal_type == GDT_blend) { + enable_blend(was_blend); + if (was_blend) + call_dxBlendFunc(old_blend_source_func, old_blend_dest_func); + } +#if(DIRECT3D_VERSION < 0x700) + else { + _d3dDevice->SetRenderState(D3DRENDERSTATE_PLANEMASK,0xFFFFFFFF); // this is unlikely to work due to poor driver support + } +#endif - enable_texturing(was_textured); - _d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, _depth_write_enabled); - } - } + enable_texturing(was_textured); + _d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, _depth_write_enabled); + } + } } //////////////////////////////////////////////////////////////////// @@ -4870,15 +4797,15 @@ end_decal(GeomNode *base_geom) { // indicated point, assumed to be in modelview // coordinates, from the camera plane. //////////////////////////////////////////////////////////////////// -float DXGraphicsStateGuardian:: +INLINE float DXGraphicsStateGuardian:: compute_distance_to(const LPoint3f &point) const { - // In the case of a DXGraphicsStateGuardian, we know that the - // modelview matrix already includes the relative transform from the - // camera, as well as a to-y-up conversion. Thus, the distance to - // the camera plane is simply the +z distance. (negative of gl compute_distance_to, - // since d3d uses left-hand coords) + // In the case of a DXGraphicsStateGuardian, we know that the + // modelview matrix already includes the relative transform from the + // camera, as well as a to-y-up conversion. Thus, the distance to + // the camera plane is simply the +z distance. (negative of gl compute_distance_to, + // since d3d uses left-hand coords) - return point[2]; + return point[2]; } //////////////////////////////////////////////////////////////////// @@ -4891,103 +4818,67 @@ compute_distance_to(const LPoint3f &point) const { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: set_draw_buffer(const RenderBuffer &rb) { - dxgsg_cat.fatal() << "DX set_draw_buffer unimplemented!!!"; - return; + dxgsg_cat.fatal() << "DX set_draw_buffer unimplemented!!!"; + return; #ifdef WBD_GL_MODE - switch (rb._buffer_type & RenderBuffer::T_color) { - case RenderBuffer::T_front: - call_glDrawBuffer(GL_FRONT); - break; - - case RenderBuffer::T_back: - call_glDrawBuffer(GL_BACK); - break; - - case RenderBuffer::T_right: - call_glDrawBuffer(GL_RIGHT); - break; - - case RenderBuffer::T_left: - call_glDrawBuffer(GL_LEFT); - break; - - case RenderBuffer::T_front_right: - call_glDrawBuffer(GL_FRONT_RIGHT); - break; - - case RenderBuffer::T_front_left: - call_glDrawBuffer(GL_FRONT_LEFT); - break; - - case RenderBuffer::T_back_right: - call_glDrawBuffer(GL_BACK_RIGHT); - break; - - case RenderBuffer::T_back_left: - call_glDrawBuffer(GL_BACK_LEFT); - break; - - default: - call_glDrawBuffer(GL_FRONT_AND_BACK); - } + switch (rb._buffer_type & RenderBuffer::T_color) { + case RenderBuffer::T_front: + call_glDrawBuffer(GL_FRONT); + break; + + case RenderBuffer::T_back: + call_glDrawBuffer(GL_BACK); + break; + + case RenderBuffer::T_right: + call_glDrawBuffer(GL_RIGHT); + break; + + case RenderBuffer::T_left: + call_glDrawBuffer(GL_LEFT); + break; + + case RenderBuffer::T_front_right: + call_glDrawBuffer(GL_FRONT_RIGHT); + break; + + case RenderBuffer::T_front_left: + call_glDrawBuffer(GL_FRONT_LEFT); + break; + + case RenderBuffer::T_back_right: + call_glDrawBuffer(GL_BACK_RIGHT); + break; + + case RenderBuffer::T_back_left: + call_glDrawBuffer(GL_BACK_LEFT); + break; + + default: + call_glDrawBuffer(GL_FRONT_AND_BACK); + } #endif // WBD_GL_MODE } //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::set_read_buffer // Access: Protected -// Description: Sets up the glReadBuffer to render into the buffer -// indicated by the RenderBuffer object. This only sets -// up the color bits; it does not affect the depth, -// stencil, accum layers. +// Description: Vestigial analog of glReadBuffer //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: set_read_buffer(const RenderBuffer &rb) { - dxgsg_cat.fatal() << "DX set_read_buffer unimplemented!!!"; - return; -#ifdef WBD_GL_MODE - switch (rb._buffer_type & RenderBuffer::T_color) { - case RenderBuffer::T_front: - call_glReadBuffer(GL_FRONT); - break; - - case RenderBuffer::T_back: - call_glReadBuffer(GL_BACK); - break; - - case RenderBuffer::T_right: - call_glReadBuffer(GL_RIGHT); - break; - - case RenderBuffer::T_left: - call_glReadBuffer(GL_LEFT); - break; - - case RenderBuffer::T_front_right: - call_glReadBuffer(GL_FRONT_RIGHT); - break; - - case RenderBuffer::T_front_left: - call_glReadBuffer(GL_FRONT_LEFT); - break; - - case RenderBuffer::T_back_right: - call_glReadBuffer(GL_BACK_RIGHT); - break; - - case RenderBuffer::T_back_left: - call_glReadBuffer(GL_BACK_LEFT); - break; - - default: - call_glReadBuffer(GL_FRONT_AND_BACK); - } -#endif // WBD_GL_MODE + if(rb._buffer_type & RenderBuffer::T_front) { + _cur_read_pixel_buffer=RenderBuffer::T_front; + } else if(rb._buffer_type & RenderBuffer::T_back) { + _cur_read_pixel_buffer=RenderBuffer::T_back; + } else { + dxgsg_cat.error() << "Invalid or unimplemented Argument to set_read_buffer!\n"; + } + return; } - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::get_texture_wrap_mode // Access: Protected @@ -4996,21 +4887,16 @@ set_read_buffer(const RenderBuffer &rb) { //////////////////////////////////////////////////////////////////// INLINE D3DTEXTUREADDRESS DXGraphicsStateGuardian:: get_texture_wrap_mode(Texture::WrapMode wm) { -/* - switch (wm) { - case Texture::WM_clamp: - return D3DTADDRESS_CLAMP; - case Texture::WM_repeat: - return D3DTADDRESS_WRAP; - } -*/ - if(wm == Texture::WM_clamp) - return D3DTADDRESS_CLAMP; - else if (wm != Texture::WM_repeat) { - dxgsg_cat.error() << "Invalid Texture::WrapMode value!\n"; - } - return D3DTADDRESS_WRAP; + if (wm == Texture::WM_clamp) + return D3DTADDRESS_CLAMP; + else if (wm != Texture::WM_repeat) { +#ifdef _DEBUG + dxgsg_cat.error() << "Invalid or Unimplemented Texture::WrapMode value!\n"; +#endif + } + + return D3DTADDRESS_WRAP; } //////////////////////////////////////////////////////////////////// @@ -5019,22 +4905,20 @@ get_texture_wrap_mode(Texture::WrapMode wm) { // Description: Maps from the depth func modes to gl version //////////////////////////////////////////////////////////////////// INLINE D3DCMPFUNC DXGraphicsStateGuardian:: -get_depth_func_type(DepthTestProperty::Mode m) const -{ - switch(m) - { - case DepthTestProperty::M_never: return D3DCMP_NEVER; - case DepthTestProperty::M_less: return D3DCMP_LESS; - case DepthTestProperty::M_equal: return D3DCMP_EQUAL; - case DepthTestProperty::M_less_equal: return D3DCMP_LESSEQUAL; - case DepthTestProperty::M_greater: return D3DCMP_GREATER; - case DepthTestProperty::M_not_equal: return D3DCMP_NOTEQUAL; - case DepthTestProperty::M_greater_equal: return D3DCMP_GREATEREQUAL; - case DepthTestProperty::M_always: return D3DCMP_ALWAYS; - } - dxgsg_cat.error() - << "Invalid DepthTestProperty::Mode value" << endl; - return D3DCMP_LESS; +get_depth_func_type(DepthTestProperty::Mode m) const { + switch (m) { + case DepthTestProperty::M_never: return D3DCMP_NEVER; + case DepthTestProperty::M_less: return D3DCMP_LESS; + case DepthTestProperty::M_equal: return D3DCMP_EQUAL; + case DepthTestProperty::M_less_equal: return D3DCMP_LESSEQUAL; + case DepthTestProperty::M_greater: return D3DCMP_GREATER; + case DepthTestProperty::M_not_equal: return D3DCMP_NOTEQUAL; + case DepthTestProperty::M_greater_equal: return D3DCMP_GREATEREQUAL; + case DepthTestProperty::M_always: return D3DCMP_ALWAYS; + } + dxgsg_cat.error() + << "Invalid DepthTestProperty::Mode value" << endl; + return D3DCMP_LESS; } //////////////////////////////////////////////////////////////////// @@ -5043,21 +4927,20 @@ get_depth_func_type(DepthTestProperty::Mode m) const // Description: Maps from the stencil func modes to dx version //////////////////////////////////////////////////////////////////// INLINE D3DCMPFUNC DXGraphicsStateGuardian:: -get_stencil_func_type(StencilProperty::Mode m) const -{ - switch(m) { - case StencilProperty::M_never: return D3DCMP_NEVER; - case StencilProperty::M_less: return D3DCMP_LESS; - case StencilProperty::M_equal: return D3DCMP_EQUAL; - case StencilProperty::M_less_equal: return D3DCMP_LESSEQUAL; - case StencilProperty::M_greater: return D3DCMP_GREATER; - case StencilProperty::M_not_equal: return D3DCMP_NOTEQUAL; - case StencilProperty::M_greater_equal: return D3DCMP_GREATEREQUAL; - case StencilProperty::M_always: return D3DCMP_ALWAYS; - } - dxgsg_cat.error() - << "Invalid StencilProperty::Mode value" << endl; - return D3DCMP_LESS; +get_stencil_func_type(StencilProperty::Mode m) const { + switch (m) { + case StencilProperty::M_never: return D3DCMP_NEVER; + case StencilProperty::M_less: return D3DCMP_LESS; + case StencilProperty::M_equal: return D3DCMP_EQUAL; + case StencilProperty::M_less_equal: return D3DCMP_LESSEQUAL; + case StencilProperty::M_greater: return D3DCMP_GREATER; + case StencilProperty::M_not_equal: return D3DCMP_NOTEQUAL; + case StencilProperty::M_greater_equal: return D3DCMP_GREATEREQUAL; + case StencilProperty::M_always: return D3DCMP_ALWAYS; + } + dxgsg_cat.error() + << "Invalid StencilProperty::Mode value" << endl; + return D3DCMP_LESS; } @@ -5067,19 +4950,18 @@ get_stencil_func_type(StencilProperty::Mode m) const // Description: Maps from the stencil action modes to dx version //////////////////////////////////////////////////////////////////// INLINE D3DSTENCILOP DXGraphicsStateGuardian:: -get_stencil_action_type(StencilProperty::Action a) const -{ - switch(a) { - case StencilProperty::A_keep: return D3DSTENCILOP_KEEP; - case StencilProperty::A_zero: return D3DSTENCILOP_ZERO; - case StencilProperty::A_replace: return D3DSTENCILOP_REPLACE; - case StencilProperty::A_increment: return D3DSTENCILOP_INCR; - case StencilProperty::A_decrement: return D3DSTENCILOP_DECR; - case StencilProperty::A_invert: return D3DSTENCILOP_INVERT; - } - dxgsg_cat.error() - << "Invalid StencilProperty::Action value" << endl; - return D3DSTENCILOP_KEEP; +get_stencil_action_type(StencilProperty::Action a) const { + switch (a) { + case StencilProperty::A_keep: return D3DSTENCILOP_KEEP; + case StencilProperty::A_zero: return D3DSTENCILOP_ZERO; + case StencilProperty::A_replace: return D3DSTENCILOP_REPLACE; + case StencilProperty::A_increment: return D3DSTENCILOP_INCR; + case StencilProperty::A_decrement: return D3DSTENCILOP_DECR; + case StencilProperty::A_invert: return D3DSTENCILOP_INVERT; + } + dxgsg_cat.error() + << "Invalid StencilProperty::Action value" << endl; + return D3DSTENCILOP_KEEP; } @@ -5090,13 +4972,13 @@ get_stencil_action_type(StencilProperty::Action a) const //////////////////////////////////////////////////////////////////// INLINE D3DFOGMODE DXGraphicsStateGuardian:: get_fog_mode_type(Fog::Mode m) const { - switch(m) { - case Fog::M_linear: return D3DFOG_LINEAR; - case Fog::M_exponential: return D3DFOG_EXP; - case Fog::M_super_exponential: return D3DFOG_EXP2; - } - dxgsg_cat.error() << "Invalid Fog::Mode value" << endl; - return D3DFOG_EXP; + switch (m) { + case Fog::M_linear: return D3DFOG_LINEAR; + case Fog::M_exponential: return D3DFOG_EXP; + case Fog::M_super_exponential: return D3DFOG_EXP2; + } + dxgsg_cat.error() << "Invalid Fog::Mode value" << endl; + return D3DFOG_EXP; } @@ -5108,27 +4990,27 @@ get_fog_mode_type(Fog::Mode m) const { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: free_pointers() { - if (_light_enabled != (bool *)NULL) { - delete[] _light_enabled; - _light_enabled = (bool *)NULL; - } - if (_cur_light_enabled != (bool *)NULL) { - delete[] _cur_light_enabled; - _cur_light_enabled = (bool *)NULL; - } - if (_clip_plane_enabled != (bool *)NULL) { - delete[] _clip_plane_enabled; - _clip_plane_enabled = (bool *)NULL; - } - if (_cur_clip_plane_enabled != (bool *)NULL) { - delete[] _cur_clip_plane_enabled; - _cur_clip_plane_enabled = (bool *)NULL; - } + if (_light_enabled != (bool *)NULL) { + delete[] _light_enabled; + _light_enabled = (bool *)NULL; + } + if (_cur_light_enabled != (bool *)NULL) { + delete[] _cur_light_enabled; + _cur_light_enabled = (bool *)NULL; + } + if (_clip_plane_enabled != (bool *)NULL) { + delete[] _clip_plane_enabled; + _clip_plane_enabled = (bool *)NULL; + } + if (_cur_clip_plane_enabled != (bool *)NULL) { + delete[] _cur_clip_plane_enabled; + _cur_clip_plane_enabled = (bool *)NULL; + } - if( _pTexPixFmts != NULL) { - delete _pTexPixFmts; - _pTexPixFmts = NULL; - } + if (_pTexPixFmts != NULL) { + delete _pTexPixFmts; + _pTexPixFmts = NULL; + } } //////////////////////////////////////////////////////////////////// @@ -5143,24 +5025,30 @@ free_pointers() { //////////////////////////////////////////////////////////////////// PT(SavedFrameBuffer) DXGraphicsStateGuardian:: save_frame_buffer(const RenderBuffer &buffer, - CPT(DisplayRegion) dr) { - DXSavedFrameBuffer *sfb = new DXSavedFrameBuffer(buffer, dr); + CPT(DisplayRegion) dr) { - if (buffer._buffer_type & RenderBuffer::T_depth) { - // Save the depth buffer. - sfb->_depth = - new PixelBuffer(PixelBuffer::depth_buffer(dr->get_pixel_width(), - dr->get_pixel_height())); - copy_pixel_buffer(sfb->_depth, dr, buffer); - } + dxgsg_cat.error() << "save_frame_buffer unimplemented!!\n"; + return NULL; - if (buffer._buffer_type & RenderBuffer::T_back) { - // Save the color buffer. - sfb->_back_rgba = new Texture; - copy_texture(sfb->_back_rgba->prepare(this), dr, buffer); - } +#if 0 + DXSavedFrameBuffer *sfb = new DXSavedFrameBuffer(buffer, dr); - return sfb; + if (buffer._buffer_type & RenderBuffer::T_depth) { + // Save the depth buffer. + sfb->_depth = + new PixelBuffer(PixelBuffer::depth_buffer(dr->get_pixel_width(), + dr->get_pixel_height())); + copy_pixel_buffer(sfb->_depth, dr, buffer); + } + + if (buffer._buffer_type & RenderBuffer::T_back) { + // Save the color buffer. + sfb->_back_rgba = new Texture; + copy_texture(sfb->_back_rgba->prepare(this), dr, buffer); + } + + return sfb; +#endif } //////////////////////////////////////////////////////////////////// @@ -5170,49 +5058,55 @@ save_frame_buffer(const RenderBuffer &buffer, //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: restore_frame_buffer(SavedFrameBuffer *frame_buffer) { - DXSavedFrameBuffer *sfb = DCAST(DXSavedFrameBuffer, frame_buffer); + + dxgsg_cat.error() << "restore_frame_buffer unimplemented!!\n"; + return; - if (sfb->_back_rgba != (Texture *)NULL && - (sfb->_buffer._buffer_type & RenderBuffer::T_back) != 0) { - // Restore the color buffer. - draw_texture(sfb->_back_rgba->prepare(this), - sfb->_display_region, sfb->_buffer); - } +#if 0 + DXSavedFrameBuffer *sfb = DCAST(DXSavedFrameBuffer, frame_buffer); - if (sfb->_depth != (PixelBuffer *)NULL && - (sfb->_buffer._buffer_type & RenderBuffer::T_depth) != 0) { - // Restore the depth buffer. - draw_pixel_buffer(sfb->_depth, sfb->_display_region, sfb->_buffer); - } + if (sfb->_back_rgba != (Texture *)NULL && + (sfb->_buffer._buffer_type & RenderBuffer::T_back) != 0) { + // Restore the color buffer. + draw_texture(sfb->_back_rgba->prepare(this), + sfb->_display_region, sfb->_buffer); + } + + if (sfb->_depth != (PixelBuffer *)NULL && + (sfb->_buffer._buffer_type & RenderBuffer::T_depth) != 0) { + // Restore the depth buffer. + draw_pixel_buffer(sfb->_depth, sfb->_display_region, sfb->_buffer); + } +#endif } // factory and type stuff GraphicsStateGuardian *DXGraphicsStateGuardian:: make_DXGraphicsStateGuardian(const FactoryParams ¶ms) { - GraphicsStateGuardian::GsgWindow *win_param; - if (!get_param_into(win_param, params)) { - dxgsg_cat.error() - << "No window specified for gsg creation!" << endl; - return NULL; - } + GraphicsStateGuardian::GsgWindow *win_param; + if (!get_param_into(win_param, params)) { + dxgsg_cat.error() + << "No window specified for gsg creation!" << endl; + return NULL; + } - GraphicsWindow *win = win_param->get_window(); - return new DXGraphicsStateGuardian(win); + GraphicsWindow *win = win_param->get_window(); + return new DXGraphicsStateGuardian(win); } TypeHandle DXGraphicsStateGuardian::get_type(void) const { - return get_class_type(); + return get_class_type(); } TypeHandle DXGraphicsStateGuardian::get_class_type(void) { - return _type_handle; + return _type_handle; } void DXGraphicsStateGuardian::init_type(void) { - GraphicsStateGuardian::init_type(); - register_type(_type_handle, "DXGraphicsStateGuardian", - GraphicsStateGuardian::get_class_type()); + GraphicsStateGuardian::init_type(); + register_type(_type_handle, "DXGraphicsStateGuardian", + GraphicsStateGuardian::get_class_type()); } //////////////////////////////////////////////////////////////////// @@ -5222,32 +5116,32 @@ void DXGraphicsStateGuardian::init_type(void) { void DXGraphicsStateGuardian:: dx_cleanup() { - release_all_textures(); + release_all_textures(); - // Do a safe check for releasing the D3DDEVICE. RefCount should be zero. - if( _d3dDevice!=NULL ) { - if( 0 < _d3dDevice->Release() ) { - dxgsg_cat.error() << "DXGraphicsStateGuardian::destructor - d3dDevice reference count > 0" << endl; - } - _d3dDevice = NULL; // clear the pointer in the Gsg - } + // Do a safe check for releasing the D3DDEVICE. RefCount should be zero. + if (_d3dDevice!=NULL) { + if (0 < _d3dDevice->Release()) { + dxgsg_cat.error() << "DXGraphicsStateGuardian::destructor - d3dDevice reference count > 0" << endl; + } + _d3dDevice = NULL; // clear the pointer in the Gsg + } - // Release the DDraw and D3D objects used by the app - RELEASE(_zbuf); - RELEASE(_back); - RELEASE(_pri); + // Release the DDraw and D3D objects used by the app + RELEASE(_zbuf); + RELEASE(_back); + RELEASE(_pri); - RELEASE(_d3d); + RELEASE(_d3d); - // Do a safe check for releasing DDRAW. RefCount should be zero. - if( _pDD!=NULL ) { - int val; - if( 0 < (val = _pDD->Release()) ) { - dxgsg_cat.error() - << "DXGraphicsStateGuardian::destructor - context reference count = " << val << endl; - } - _pDD = NULL; - } + // Do a safe check for releasing DDRAW. RefCount should be zero. + if (_pDD!=NULL) { + int val; + if (0 < (val = _pDD->Release())) { + dxgsg_cat.error() + << "DXGraphicsStateGuardian::destructor - context reference count = " << val << endl; + } + _pDD = NULL; + } } //////////////////////////////////////////////////////////////////// @@ -5255,113 +5149,112 @@ dx_cleanup() { // Description: Recreate the back buffer and zbuffers at the new size //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: -dx_setup_after_resize(RECT viewrect, HWND mwindow) -{ - if(_back == NULL) // nothing created yet - return; +dx_setup_after_resize(RECT viewrect, HWND mwindow) { + if (_back == NULL) // nothing created yet + return; - // for safety, need some better error-cleanup here - assert((_pri!=NULL) && (_back!=NULL) && (_zbuf!=NULL)); + // for safety, need some better error-cleanup here + assert((_pri!=NULL) && (_back!=NULL) && (_zbuf!=NULL)); - DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd_back); - DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd_zbuf); + DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd_back); + DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd_zbuf); + + _back->GetSurfaceDesc(&ddsd_back); + _zbuf->GetSurfaceDesc(&ddsd_zbuf); - _back->GetSurfaceDesc(&ddsd_back); - _zbuf->GetSurfaceDesc(&ddsd_zbuf); - #if 0 - DWORD refcnt; - refcnt = _zbuf->Release(); _zbuf = NULL; - dxgsg_cat.error() << "zbuf refcnt= "<Release(); _back = NULL; - dxgsg_cat.error() << "back refcnt= "<Release(); _pri = NULL; - dxgsg_cat.error() << "pri refcnt= "<Release(); _zbuf = NULL; + dxgsg_cat.error() << "zbuf refcnt= "<Release(); _back = NULL; + dxgsg_cat.error() << "back refcnt= "<Release(); _pri = NULL; + dxgsg_cat.error() << "pri refcnt= "<CreateSurface( &ddsd, &_pri, NULL ))) { - dxgsg_cat.fatal() << "DXGraphicsStateGuardian::resize() - CreateSurface failed for primary : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } + if (FAILED(hr = _pDD->CreateSurface( &ddsd, &_pri, NULL ))) { + dxgsg_cat.fatal() << "DXGraphicsStateGuardian::resize() - CreateSurface failed for primary : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } - // Create a clipper object which handles all our clipping for cases when - // our window is partially obscured by other windows. - LPDIRECTDRAWCLIPPER Clipper; + // Create a clipper object which handles all our clipping for cases when + // our window is partially obscured by other windows. + LPDIRECTDRAWCLIPPER Clipper; - if(FAILED(hr = _pDD->CreateClipper( 0, &Clipper, NULL ))) { - dxgsg_cat.fatal() - << "dxgsg - CreateClipper after resize failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - // Associate the clipper with our window. Note that, afterwards, the - // clipper is internally referenced by the primary surface, so it is safe - // to release our local reference to it. - Clipper->SetHWnd( 0, mwindow ); - _pri->SetClipper( Clipper ); - Clipper->Release(); + if (FAILED(hr = _pDD->CreateClipper( 0, &Clipper, NULL ))) { + dxgsg_cat.fatal() + << "dxgsg - CreateClipper after resize failed : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + // Associate the clipper with our window. Note that, afterwards, the + // clipper is internally referenced by the primary surface, so it is safe + // to release our local reference to it. + Clipper->SetHWnd( 0, mwindow ); + _pri->SetClipper( Clipper ); + Clipper->Release(); - // Recreate the backbuffer. (might want to handle failure due to running out of video memory) + // Recreate the backbuffer. (might want to handle failure due to running out of video memory) - ddsd_back.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; // just to make sure - ddsd_back.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; - - PRINTVIDMEM(_pDD,&ddsd_back.ddsCaps,"resize backbuffer surf"); - - if(FAILED(hr = _pDD->CreateSurface( &ddsd_back, &_back, NULL ))) { - dxgsg_cat.fatal() << "DXGraphicsStateGuardian::resize() - CreateSurface failed for backbuffer : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - PRINTVIDMEM(_pDD,&ddsd_back.ddsCaps,"resize zbuffer surf"); - - // Recreate and attach a z-buffer. - if(FAILED(hr = _pDD->CreateSurface( &ddsd_zbuf, &_zbuf, NULL ))) { - dxgsg_cat.fatal() << "DXGraphicsStateGuardian::resize() - CreateSurface failed for Z buffer: result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } + ddsd_back.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; // just to make sure + ddsd_back.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; - // Attach the z-buffer to the back buffer. - if( (hr = _back->AddAttachedSurface( _zbuf ) ) != DD_OK) { - dxgsg_cat.fatal() - << "DXGraphicsStateGuardian::resize() - AddAttachedSurface failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } + PRINTVIDMEM(_pDD,&ddsd_back.ddsCaps,"resize backbuffer surf"); - if( (hr = _d3dDevice->SetRenderTarget(_back,0x0) ) != DD_OK) { - dxgsg_cat.fatal() - << "DXGraphicsStateGuardian::resize() - SetRenderTarget failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } + if (FAILED(hr = _pDD->CreateSurface( &ddsd_back, &_back, NULL ))) { + dxgsg_cat.fatal() << "DXGraphicsStateGuardian::resize() - CreateSurface failed for backbuffer : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } - // Create the viewport - D3DVIEWPORT7 vp = { 0, 0, renderWid, renderHt, 0.0f, 1.0f }; - hr = _d3dDevice->SetViewport( &vp ); - if (hr != DD_OK) { - dxgsg_cat.fatal() - << "DXGraphicsStateGuardian::config() - SetViewport failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } + PRINTVIDMEM(_pDD,&ddsd_back.ddsCaps,"resize zbuffer surf"); + + // Recreate and attach a z-buffer. + if (FAILED(hr = _pDD->CreateSurface( &ddsd_zbuf, &_zbuf, NULL ))) { + dxgsg_cat.fatal() << "DXGraphicsStateGuardian::resize() - CreateSurface failed for Z buffer: result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + // Attach the z-buffer to the back buffer. + if ((hr = _back->AddAttachedSurface( _zbuf ) ) != DD_OK) { + dxgsg_cat.fatal() + << "DXGraphicsStateGuardian::resize() - AddAttachedSurface failed : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + if ((hr = _d3dDevice->SetRenderTarget(_back,0x0) ) != DD_OK) { + dxgsg_cat.fatal() + << "DXGraphicsStateGuardian::resize() - SetRenderTarget failed : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + // Create the viewport + D3DVIEWPORT7 vp = { 0, 0, renderWid, renderHt, 0.0f, 1.0f}; + hr = _d3dDevice->SetViewport( &vp ); + if (hr != DD_OK) { + dxgsg_cat.fatal() + << "DXGraphicsStateGuardian::config() - SetViewport failed : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } } @@ -5372,62 +5265,123 @@ dx_setup_after_resize(RECT viewrect, HWND mwindow) //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian::show_frame(void) { - PStatTimer timer(_win->_swap_pcollector); // this times just the flip, so it must go here in dxgsg, instead of wdxdisplay, which would time the whole frame + PStatTimer timer(_win->_swap_pcollector); // this times just the flip, so it must go here in dxgsg, instead of wdxdisplay, which would time the whole frame - if (_pri!=NULL) { - if( dx_full_screen ) { + if (_pri!=NULL) { + if (dx_full_screen) { - HRESULT hr = _pri->Flip( NULL, DDFLIP_WAIT ); // bugbug: dont we want triple buffering instead of wasting time waiting for vsync? - if (hr == DDERR_SURFACELOST) { - // Check/restore the primary surface - if(( _pri!=NULL ) && _pri->IsLost()) - _pri->Restore(); - // Check/restore the back buffer - if(( _back!=NULL ) && _back->IsLost()) - _back->Restore(); - // Check/restore the z-buffer - if(( _zbuf!=NULL ) && _zbuf->IsLost()) - _zbuf->Restore(); - return; - } + HRESULT hr = _pri->Flip( NULL, DDFLIP_WAIT ); // bugbug: dont we want triple buffering instead of wasting time waiting for vsync? + if (hr == DDERR_SURFACELOST || hr == DDERR_SURFACEBUSY) { +#if 0 + if (hr == DDERR_SURFACELOST || hr == DDERR_SURFACEBUSY) { + HRESULT hr; - if (hr != DD_OK) { - dxgsg_cat.error() << "DXGraphicsStateGuardian::show_frame() - Flip failed : " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - } else { - DX_DECLARE_CLEAN(DDBLTFX, bltfx); + // TestCooperativeLevel returns DD_OK: If the current mode is same as the one which the App set. + // The following two errors are returned to NORMALMODE (windowed)apps only. + // + // DDERR_WRONGMODE: If the App is a windowed app and the current mode is + // not the same as the one in which the app was created. + // DDERR_EXCLUSIVEMODEALREADYSET: If another app took exclusivemode access + // + // The following error is returned only for exclusivemode apps. + // DDERR_NOEXCLUSIVEMODE: Some other app took exclusive mode. + // + hr = _pDD->TestCooperativeLevel(); + if (SUCCEEDED( hr )) { + // This means that mode changes had taken place, surfaces + // were lost but still we are in the original mode, so we + // simply restore all surfaces and keep going. - bltfx.dwDDFX |= DDBLTFX_NOTEARING; - HRESULT hr = _pri->Blt( &_view_rect, _back, NULL, DDBLT_DDFX | DDBLT_WAIT, &bltfx ); - if(hr!=DD_OK) { - if (hr == DDERR_SURFACELOST) { - // Check/restore the primary surface - if(( _pri!=NULL ) && _pri->IsLost()) - _pri->Restore(); - // Check/restore the back buffer - if(( _back!=NULL ) && _back->IsLost()) - _back->Restore(); - // Check/restore the z-buffer - if(( _zbuf!=NULL ) && _zbuf->IsLost()) - _zbuf->Restore(); - return; - } else { - dxgsg_cat.error() << "DXGraphicsStateGuardian::show_frame() - Blt failed : " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - } - // right now, we force sync to v-blank (time from now up to vblank is wasted) - // this keeps calling processes from trying to render more frames than the refresh - // rate since (as implemented right now) they expect this call to block - hr = _pDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL); - if (hr != DD_OK) { - dxgsg_cat.error() << "DXGraphicsStateGuardian::WaitForVerticalBlank() failed : " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - } - } + + + if (FAILED( m_pDD->RestoreAllSurfaces() )) + return hr; + + // Re-fill the contents of textures and vertex buffers + // which just got restored now. + // You will need to destroy and recreate + // optimized vertex buffers however, restoring is not enough. + RefillAppSurfaces(); + } else if (hr == DDERR_NOEXCLUSIVEMODE) { + // This means that some app took exclusive mode access + // we need to sit in a loop till we get back to the right mode. + do { + // Dont consume CPU. + Sleep( 500 ); + } while (DDERR_NOEXCLUSIVEMODE== + (hr = m_pDD->TestCooperativeLevel())); + if (SUCCEEDED( hr )) { + // This means that the exclusive mode app relinquished its + // control and we are back to the safe mode, so simply restore + if (FAILED( m_pDD->RestoreAllSurfaces() )) + return hr; + // Re-fill the contents of textures and vertex buffers + // which just got restored now. + // You will need to destroy and recreate + // optimized vertex buffers however, restoring is not enough. + RefillAppSurfaces(); + } else { + // Busted!! + return hr; + } + } else { + // Busted!! + return hr; + } + } + +#endif + + + // Check/restore the primary surface + if (( _pri!=NULL ) && _pri->IsLost()) + _pri->Restore(); + // Check/restore the back buffer + if (( _back!=NULL ) && _back->IsLost()) + _back->Restore(); + // Check/restore the z-buffer + if (( _zbuf!=NULL ) && _zbuf->IsLost()) + _zbuf->Restore(); + return; + } + + if (hr != DD_OK) { + dxgsg_cat.error() << "DXGraphicsStateGuardian::show_frame() - Flip failed : " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + } else { + DX_DECLARE_CLEAN(DDBLTFX, bltfx); + + bltfx.dwDDFX |= DDBLTFX_NOTEARING; + HRESULT hr = _pri->Blt( &_view_rect, _back, NULL, DDBLT_DDFX | DDBLT_WAIT, &bltfx ); + if (hr!=DD_OK) { + if (hr == DDERR_SURFACELOST) { + // Check/restore the primary surface + if (( _pri!=NULL ) && _pri->IsLost()) + _pri->Restore(); + // Check/restore the back buffer + if (( _back!=NULL ) && _back->IsLost()) + _back->Restore(); + // Check/restore the z-buffer + if (( _zbuf!=NULL ) && _zbuf->IsLost()) + _zbuf->Restore(); + return; + } else { + dxgsg_cat.error() << "DXGraphicsStateGuardian::show_frame() - Blt failed : " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + } + // right now, we force sync to v-blank (time from now up to vblank is wasted) + // this keeps calling processes from trying to render more frames than the refresh + // rate since (as implemented right now) they expect this call to block + hr = _pDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL); + if (hr != DD_OK) { + dxgsg_cat.error() << "DXGraphicsStateGuardian::WaitForVerticalBlank() failed : " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + } + } } //////////////////////////////////////////////////////////////////// @@ -5435,17 +5389,15 @@ void DXGraphicsStateGuardian::show_frame(void) { // Access: // Description: we receive the new x and y position of the client //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::adjust_view_rect(int x, int y) -{ - if (_view_rect.left != x || _view_rect.top != y) - { - _view_rect.right = x + _view_rect.right - _view_rect.left; - _view_rect.left = x; - _view_rect.bottom = y + _view_rect.bottom - _view_rect.top; - _view_rect.top = y; +void DXGraphicsStateGuardian::adjust_view_rect(int x, int y) { + if (_view_rect.left != x || _view_rect.top != y) { + _view_rect.right = x + _view_rect.right - _view_rect.left; + _view_rect.left = x; + _view_rect.bottom = y + _view_rect.bottom - _view_rect.top; + _view_rect.top = y; // set_clipper(clip_rect); - } + } } #if 0 @@ -5455,61 +5407,58 @@ void DXGraphicsStateGuardian::adjust_view_rect(int x, int y) // function builds a 4x4 view matrix. //----------------------------------------------------------------------------- HRESULT SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom, D3DVECTOR& vAt, - D3DVECTOR& vWorldUp ) -{ - // Get the z basis vector, which points straight ahead. This is the - // difference from the eyepoint to the lookat point. - D3DVECTOR vView = vAt - vFrom; + D3DVECTOR& vWorldUp ) { + // Get the z basis vector, which points straight ahead. This is the + // difference from the eyepoint to the lookat point. + D3DVECTOR vView = vAt - vFrom; - float fLength = Magnitude( vView ); - if( fLength < 1e-6f ) - return E_INVALIDARG; + float fLength = Magnitude( vView ); + if (fLength < 1e-6f) + return E_INVALIDARG; - // Normalize the z basis vector - vView /= fLength; + // Normalize the z basis vector + vView /= fLength; - // Get the dot product, and calculate the projection of the z basis - // vector onto the up vector. The projection is the y basis vector. - float fDotProduct = DotProduct( vWorldUp, vView ); + // Get the dot product, and calculate the projection of the z basis + // vector onto the up vector. The projection is the y basis vector. + float fDotProduct = DotProduct( vWorldUp, vView ); - D3DVECTOR vUp = vWorldUp - fDotProduct * vView; + D3DVECTOR vUp = vWorldUp - fDotProduct * vView; - // If this vector has near-zero length because the input specified a - // bogus up vector, let's try a default up vector - if( 1e-6f > ( fLength = Magnitude( vUp ) ) ) - { - vUp = D3DVECTOR( 0.0f, 1.0f, 0.0f ) - vView.y * vView; + // If this vector has near-zero length because the input specified a + // bogus up vector, let's try a default up vector + if (1e-6f > ( fLength = Magnitude( vUp ) )) { + vUp = D3DVECTOR( 0.0f, 1.0f, 0.0f ) - vView.y * vView; - // If we still have near-zero length, resort to a different axis. - if( 1e-6f > ( fLength = Magnitude( vUp ) ) ) - { - vUp = D3DVECTOR( 0.0f, 0.0f, 1.0f ) - vView.z * vView; + // If we still have near-zero length, resort to a different axis. + if (1e-6f > ( fLength = Magnitude( vUp ) )) { + vUp = D3DVECTOR( 0.0f, 0.0f, 1.0f ) - vView.z * vView; - if( 1e-6f > ( fLength = Magnitude( vUp ) ) ) - return E_INVALIDARG; - } - } + if (1e-6f > ( fLength = Magnitude( vUp ) )) + return E_INVALIDARG; + } + } - // Normalize the y basis vector - vUp /= fLength; + // Normalize the y basis vector + vUp /= fLength; - // The x basis vector is found simply with the cross product of the y - // and z basis vectors - D3DVECTOR vRight = CrossProduct( vUp, vView ); - - // Start building the matrix. The first three rows contains the basis - // vectors used to rotate the view to point at the lookat point - mat._11 = vRight.x; mat._12 = vUp.x; mat._13 = vView.x; mat._14 = 0.0f; - mat._21 = vRight.y; mat._22 = vUp.y; mat._23 = vView.y; mat._24 = 0.0f; - mat._31 = vRight.z; mat._32 = vUp.z; mat._33 = vView.z; mat._34 = 0.0f; + // The x basis vector is found simply with the cross product of the y + // and z basis vectors + D3DVECTOR vRight = CrossProduct( vUp, vView ); - // Do the translation values (rotations are still about the eyepoint) - mat._41 = - DotProduct( vFrom, vRight ); - mat._42 = - DotProduct( vFrom, vUp ); - mat._43 = - DotProduct( vFrom, vView ); - mat._44 = 1.0f; + // Start building the matrix. The first three rows contains the basis + // vectors used to rotate the view to point at the lookat point + mat._11 = vRight.x; mat._12 = vUp.x; mat._13 = vView.x; mat._14 = 0.0f; + mat._21 = vRight.y; mat._22 = vUp.y; mat._23 = vView.y; mat._24 = 0.0f; + mat._31 = vRight.z; mat._32 = vUp.z; mat._33 = vView.z; mat._34 = 0.0f; - return S_OK; + // Do the translation values (rotations are still about the eyepoint) + mat._41 = - DotProduct( vFrom, vRight ); + mat._42 = - DotProduct( vFrom, vUp ); + mat._43 = - DotProduct( vFrom, vView ); + mat._44 = 1.0f; + + return S_OK; } #endif diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.h b/panda/src/dxgsg/dxGraphicsStateGuardian.h index e33c737e74..8aa0b3ac07 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.h +++ b/panda/src/dxgsg/dxGraphicsStateGuardian.h @@ -169,7 +169,7 @@ public: virtual void begin_decal(GeomNode *base_geom); virtual void end_decal(GeomNode *base_geom); - virtual float compute_distance_to(const LPoint3f &point) const; + INLINE float compute_distance_to(const LPoint3f &point) const; void reset_ambient(); @@ -207,6 +207,8 @@ protected: LPDDPIXELFORMAT _pTexPixFmts; DXTextureContext *_pCurTexContext; + RenderBuffer::Type _cur_read_pixel_buffer; // source for copy_pixel_buffer operation + bool _color_transform_enabled; bool _alpha_transform_enabled; @@ -307,8 +309,8 @@ protected: D3DBLEND _blend_source_func; D3DBLEND _blend_dest_func; - int _pack_alignment; - int _unpack_alignment; +// int _pack_alignment; +// int _unpack_alignment; bool _issued_color_enabled; // WBD ADDED D3DCOLOR _issued_color; // WBD ADDED