From 1e37df2ff265e58a09c6cd3ff8815aa15f191999 Mon Sep 17 00:00:00 2001 From: cxgeorge <> Date: Sat, 13 Oct 2001 23:00:23 +0000 Subject: [PATCH] add resize() fullscrn support, more stenciling support --- panda/src/dxgsg/dxGraphicsStateGuardian.I | 145 ++-- panda/src/dxgsg/dxGraphicsStateGuardian.cxx | 394 +++++---- panda/src/dxgsg/dxGraphicsStateGuardian.h | 72 +- panda/src/dxgsg/dxTextureContext.h | 10 +- panda/src/wdxdisplay/config_wdxdisplay.cxx | 2 + panda/src/wdxdisplay/wdxGraphicsPipe.cxx | 11 +- panda/src/wdxdisplay/wdxGraphicsWindow.cxx | 875 +++++++++++++------- panda/src/wdxdisplay/wdxGraphicsWindow.h | 17 +- 8 files changed, 908 insertions(+), 618 deletions(-) diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.I b/panda/src/dxgsg/dxGraphicsStateGuardian.I index 9e4b3c018e..08061540c8 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.I +++ b/panda/src/dxgsg/dxGraphicsStateGuardian.I @@ -19,43 +19,6 @@ #include "config_dxgsg.h" #include -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::set_pack_alignment -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: -set_pack_alignment(int alignment) { - #ifdef NDEBUG - dxgsg_cat.error() << "set_pack_alignment() unimplemented, has no meaning in DX\n"; - #endif -} - -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::set_unpack_alignment -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: -set_unpack_alignment(int alignment) { - #ifdef NDEBUG - dxgsg_cat.error() << "set_unpack_alignment() unimplemented, has no meaning in DX\n"; - #endif -} - -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_multisample -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: -enable_multisample(bool val) { - _multisample_enabled = val; - #ifdef NDEBUG - dxgsg_cat.error() << "dx multisample unimplemented!!\n"; - #endif -} - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::enable_line_smooth // Access: @@ -76,20 +39,6 @@ enable_line_smooth(bool val) { } } -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_point_smooth -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: -enable_point_smooth(bool val) { - _point_smooth_enabled = val; - #ifdef NDEBUG - dxgsg_cat.error() << "dx point smoothing unimplemented!!\n"; - #endif -} - - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::enable_lighting // Access: @@ -122,7 +71,6 @@ enable_dither(bool val) { #endif _dither_enabled = val; - _d3dDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, (DWORD)val); } } @@ -173,32 +121,6 @@ enable_clip_plane(int clip_plane, bool val) } } - - -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_multisample_alpha_one -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: -enable_multisample_alpha_one(bool val) { - if (_multisample_alpha_one_enabled != val) { - _multisample_alpha_one_enabled = val; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::enable_multisample_alpha_mask -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void DXGraphicsStateGuardian:: -enable_multisample_alpha_mask(bool val) { - if (_multisample_alpha_mask_enabled != val) { - _multisample_alpha_mask_enabled = val; - } -} - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::enable_blend // Access: @@ -225,15 +147,6 @@ set_shademode(D3DSHADEMODE val) { } } -INLINE void DXGraphicsStateGuardian:: -SetDeviceTexture(LPDIRECTDRAWSURFACE7 pTexture) { - // this fn is useful because GetTexture() does an AddRef, so faster to cache it ourself - if (_pCurDeviceTexture != pTexture) { - _pCurDeviceTexture = pTexture; - _d3dDevice->SetTexture(0,_pCurDeviceTexture); - } -} - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::enable_fog // Access: @@ -272,8 +185,7 @@ call_dxLightModelAmbient( const Colorf& color) if (_lmodel_ambient != color) { _lmodel_ambient = color; #ifdef GSG_VERBOSE - dxgsg_cat.debug() - << "glLightModel(GL_LIGHT_MODEL_AMBIENT, " << color << ")" << endl; + dxgsg_cat.debug() << "dxLightModel(LIGHT_MODEL_AMBIENT, " << color << ")" << endl; #endif _d3dDevice->SetRenderState( D3DRENDERSTATE_AMBIENT, D3DRGBA(color[0], color[1], color[2], color[3])); @@ -414,3 +326,58 @@ call_dxBlendFunc(D3DBLEND sfunc, D3DBLEND dfunc ) } } + +/** unimplemented + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian::enable_multisample +// Access: +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void DXGraphicsStateGuardian:: +enable_multisample(bool val) { + _multisample_enabled = val; + #ifdef NDEBUG + dxgsg_cat.error() << "dx multisample unimplemented!!\n"; + #endif +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian::enable_multisample_alpha_one +// Access: +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void DXGraphicsStateGuardian:: +enable_multisample_alpha_one(bool val) { + if (_multisample_alpha_one_enabled != val) { + _multisample_alpha_one_enabled = val; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian::enable_multisample_alpha_mask +// Access: +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void DXGraphicsStateGuardian:: +enable_multisample_alpha_mask(bool val) { + if (_multisample_alpha_mask_enabled != val) { + _multisample_alpha_mask_enabled = val; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian::enable_point_smooth +// Access: +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void DXGraphicsStateGuardian:: +enable_point_smooth(bool val) { + // _point_smooth_enabled = val; + + #ifdef NDEBUG + dxgsg_cat.error() << "dx point smoothing unimplemented!!\n"; + #endif +} +*/ + diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.cxx b/panda/src/dxgsg/dxGraphicsStateGuardian.cxx index e1f9487256..17388d82f8 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.cxx +++ b/panda/src/dxgsg/dxGraphicsStateGuardian.cxx @@ -109,6 +109,7 @@ TypeHandle DXGraphicsStateGuardian::_type_handle; static D3DMATRIX matIdentity; #ifdef COUNT_DRAWPRIMS +// you should just use Intel GPT instead of this stuff static DWORD cDPcount=0; static DWORD cVertcount=0; @@ -124,7 +125,7 @@ static void CountDPs(DWORD nVerts,DWORD nTris) { cVertcount+=nVerts; cTricount+=nTris; - if(_pCurDeviceTexture==pLastTexture) { + if(_pCurDeviceTexture==pLastTexture) { cDP_noTexChangeCount++; } else pLastTexture = _pCurDeviceTexture; } @@ -139,20 +140,17 @@ static bool bTexStatsRetrievalImpossible=false; //#define Colorf_to_D3DCOLOR(out_color) (D3DRGBA((out_color)[0], (out_color)[1], (out_color)[2], (out_color)[3])) INLINE DWORD -Colorf_to_D3DCOLOR(Colorf &cColorf) { +Colorf_to_D3DCOLOR(const Colorf &cColorf) { // MS VC defines _M_IX86 for x86. gcc should define _X86_ #if defined(_M_IX86) || defined(_X86_) DWORD d3dcolor,tempcolorval=255; -// DWORD *Colorf_addr=(DWORD*)&cColorf; // note the default FPU rounding mode will give 255*0.5f=0x80, not 0x7F as VC would force it to by resetting rounding mode // dont think this makes much difference __asm { -; push eax push ebx ; want to save this in case this fn is inlined push ecx -; mov ecx, Colorf_addr ; must be a better way to do this w/o using ecx mov ecx, cColorf fild tempcolorval fld [ecx] @@ -185,16 +183,21 @@ Colorf_to_D3DCOLOR(Colorf &cColorf) { mov d3dcolor,eax pop ecx pop ebx -; pop eax } -// dxgsg_cat.debug() << (void*)d3dcolor << endl; + // dxgsg_cat.debug() << (void*)d3dcolor << endl; return d3dcolor; #else //!_X86_ return D3DRGBA(cColorf[0], cColorf[1], cColorf[2], cColorf[3]); #endif //!_X86_ } +void DXGraphicsStateGuardian:: +set_color_clear_value(const Colorf& value) { + _color_clear_value = value; + _d3dcolor_clear_value = Colorf_to_D3DCOLOR(value); +} + void DXGraphicsStateGuardian::SetFPSMeterPosition(RECT &view_rect) { if(_fpsmeter_verts==NULL) return; @@ -278,7 +281,7 @@ void DXGraphicsStateGuardian::FillFPSMeterTexture(void) { ZeroMemory(ddsd.lpSurface,ddsd.dwWidth*ddsd.dwHeight*2); _fpsmeter_font_surf->Unlock(NULL); - // draw text using GDI + // draw FPS text using GDI HDC hDC; if(FAILED( hr = _fpsmeter_font_surf->GetDC(&hDC))) { dxgsg_cat.error() << "fps meter creation failed, GetDC failed on fps font surface! hr = " << ConvD3DErrorToString(hr) << "\n"; @@ -340,33 +343,28 @@ void DXGraphicsStateGuardian::FillFPSMeterTexture(void) { //////////////////////////////////////////////////////////////////// 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; + // allocate local buffers used during rendering + + GraphicsStateGuardian::reset(); + _pCurFvfBufPtr = NULL; _pFvfBufBasePtr = new char[VERT_BUFFER_SIZE]; // allocate storage for vertex info. _index_buf = new WORD[D3DMAXNUMVERTICES]; // allocate storage for vertex index info. _fpsmeter_verts=NULL; _fpsmeter_font_surf=NULL; _dx_ready = false; - _pCurDeviceTexture = NULL; - - _CurShadeMode = D3DSHADE_FLAT; _pri = _zbuf = _back = NULL; _pDD = NULL; _d3dDevice = NULL; - _cur_read_pixel_buffer=RenderBuffer::T_front; + // non-dx obj values inited here should not change if resize is + // called and dx objects need to be recreated (otherwise they + // belong in dx_init, with other renderstate ZeroMemory(&matIdentity,sizeof(D3DMATRIX)); matIdentity._11 = matIdentity._22 = matIdentity._33 = matIdentity._44 = 1.0f; - _cNumTexPixFmts = 0; - _pTexPixFmts = NULL; - _pCurTexContext = NULL; - // Create a default RenderTraverser. if (dx_cull_traversal) { _render_traverser = new CullTraverser(this, RenderRelation::get_class_type()); @@ -374,14 +372,21 @@ DXGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) { _render_traverser = new DirectRenderTraverser(this, RenderRelation::get_class_type()); } - //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; + // All implementations have the following buffers. + _buffer_mask = (RenderBuffer::T_color | + RenderBuffer::T_depth | + RenderBuffer::T_back +// RenderBuffer::T_stencil | +// RenderBuffer::T_accum + ); - reset(); + // this is incorrect for general mono displays, need both right and left flags set. + // stereo has not been handled yet for dx + // _buffer_mask &= ~RenderBuffer::T_right; + + _cur_read_pixel_buffer=RenderBuffer::T_front; + + set_color_clear_value(_color_clear_value); } //////////////////////////////////////////////////////////////////// @@ -407,71 +412,36 @@ DXGraphicsStateGuardian:: // created. //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: -reset() { - free_pointers(); +reset(void) { GraphicsStateGuardian::reset(); - _buffer_mask = 0; + dxgsg_cat.error() << "DXGSG reset() not implemented properly yet!\n"; + // delete all the objs too, right? + //dx_init(); +} - // All implementations have the following buffers. - _buffer_mask = (RenderBuffer::T_color | - RenderBuffer::T_depth | - RenderBuffer::T_back -// RenderBuffer::T_stencil | -// RenderBuffer::T_accum - ); +// recreate dx objects without modifying gsg state, other than clearing state cache +void DXGraphicsStateGuardian:: +free_dxgsg_objects(void) { + ULONG refcnt; - _current_projection_mat = LMatrix4f::ident_mat(); - _projection_mat_stack_count = 0; + free_pointers(); - _issued_color_enabled = false; - _enable_all_color = true; - -// this is incorrect for general mono displays, need both right and left flags set. -// stereo has not been handled yet for dx -// _buffer_mask &= ~RenderBuffer::T_right; - - // Set up our clear values to invalid values, so the glClear* calls - // will be made initially. - _clear_color_red = -1.0f; - _clear_color_green = -1.0f; - _clear_color_blue = -1.0f; - _clear_color_alpha = -1.0f; - _clear_depth = -1.0f; - _clear_stencil = -1; - _clear_accum_red = -1.0f; - _clear_accum_green = -1.0f; - _clear_accum_blue = -1.0f; - _clear_accum_alpha = -1.0f; - _line_width = 1.0f; - _point_size = 1.0f; - _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; - - // 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; + // dont want a full reset of gsg, just a state clear + GraphicsStateGuardian::clear_cached_state(); // want gsg to pass all state settings through _dx_ready = false; + + if (_d3dDevice!=NULL) { + _d3dDevice->SetTexture(0,NULL); // should release this stuff internally anyway + RELEASE(_d3dDevice,dxgsg,"d3dDevice",RELEASE_DOWN_TO_ZERO); + } + + DeleteAllVideoSurfaces(); + + // Release the DDraw and D3D objects used by the app + RELEASE(_zbuf,dxgsg,"zbuffer",false); + RELEASE(_back,dxgsg,"backbuffer",false); + RELEASE(_pri,dxgsg,"primary surface",false); } HRESULT CALLBACK EnumTexFmtsCallback( LPDDPIXELFORMAT pddpf, VOID* param ) { @@ -490,7 +460,7 @@ HRESULT CALLBACK EnumTexFmtsCallback( LPDDPIXELFORMAT pddpf, VOID* param ) { // set up. //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: -init_dx( LPDIRECTDRAW7 context, +dx_init( LPDIRECTDRAW7 context, LPDIRECTDRAWSURFACE7 pri, LPDIRECTDRAWSURFACE7 back, LPDIRECTDRAWSURFACE7 zbuf, @@ -505,6 +475,69 @@ init_dx( LPDIRECTDRAW7 context, _d3dDevice = pDevice; _view_rect = viewrect; + _depth_write_enabled = true; + _d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, _depth_write_enabled); + + ZeroMemory(&_lmodel_ambient,sizeof(Colorf)); + _d3dDevice->SetRenderState( D3DRENDERSTATE_AMBIENT, 0x0); + + _light_enabled = (bool *)NULL; + _cur_light_enabled = (bool *)NULL; + _clip_plane_enabled = (bool *)NULL; + _cur_clip_plane_enabled = (bool *)NULL; + _d3dDevice->SetRenderState(D3DRENDERSTATE_CLIPPLANEENABLE , 0x0); + + _CurShadeMode = D3DSHADE_FLAT; + _d3dDevice->SetRenderState(D3DRENDERSTATE_SHADEMODE, _CurShadeMode); + + // need to free these properly + _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; + + // none of these are implemented + //_multisample_enabled = false; + //_point_smooth_enabled = false; + + _line_smooth_enabled = false; + _d3dDevice->SetRenderState(D3DRENDERSTATE_EDGEANTIALIAS, false); + + + _color_material_enabled = false; + _normals_enabled = false; + + _depth_test_enabled = D3DZB_FALSE; + _d3dDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_FALSE); + + _blend_enabled = false; + _d3dDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, (DWORD)_blend_enabled); + + _d3dDevice->GetRenderState(D3DRENDERSTATE_SRCBLEND, (DWORD*)&_blend_source_func); + _d3dDevice->GetRenderState(D3DRENDERSTATE_DESTBLEND, (DWORD*)&_blend_dest_func); + + _fog_enabled = false; + _d3dDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, _fog_enabled); + + _decal_level = 0; + _current_projection_mat = LMatrix4f::ident_mat(); + _projection_mat_stack_count = 0; + _issued_color_enabled = false; + _enable_all_color = true; + +// GL stuff that hasnt been translated to DX +// _scissor_enabled = false; +// _multisample_alpha_one_enabled = false; +// _multisample_alpha_mask_enabled = false; +// _line_width = 1.0f; +// _point_size = 1.0f; + assert(_back!=NULL); // dxgsg is always double-buffered right now #ifdef COUNT_DRAWPRIMS @@ -521,6 +554,8 @@ init_dx( LPDIRECTDRAW7 context, HRESULT hr; _pTexPixFmts = new DDPIXELFORMAT[MAX_DX_TEXPIXFMTS]; + _cNumTexPixFmts = 0; + assert(_pTexPixFmts!=NULL); if (pDevice->EnumTextureFormats(EnumTexFmtsCallback, this) != S_OK) { @@ -542,7 +577,6 @@ init_dx( LPDIRECTDRAW7 context, if ((dx_decal_type==GDT_offset) && !(_D3DDevDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZBIAS)) { #ifdef _DEBUG - // dx7 doesnt support PLANEMASK renderstate #if(DIRECT3D_VERSION < 0x700) dxgsg_cat.debug() << "dx-decal-type 'offset' not supported by hardware, switching to decal masking\n"; @@ -571,13 +605,13 @@ init_dx( LPDIRECTDRAW7 context, 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.debug() << "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"; + 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| \ @@ -637,25 +671,24 @@ init_dx( LPDIRECTDRAW7 context, } } - SetRect(&clip_rect, 0,0,0,0); // no clip rect set + SetRect(&clip_rect, 0,0,0,0); // no clip rect set // Lighting, let's turn it off by default - _lighting_enabled = true; - enable_lighting(false); + _lighting_enabled = false; + _d3dDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, _lighting_enabled); // turn on dithering if the rendertarget is < 8bits/color channel DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd_back); _back->GetSurfaceDesc(&ddsd_back); _dither_enabled = ((ddsd_back.ddpfPixelFormat.dwRGBBitCount < 24) && (_D3DDevDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_DITHER)); - _d3dDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, _dither_enabled); + _d3dDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, _dither_enabled); - _d3dDevice->SetRenderState(D3DRENDERSTATE_CLIPPING,true); + _d3dDevice->SetRenderState(D3DRENDERSTATE_CLIPPING,true); // Stencil test is off by default _stencil_test_enabled = false; -// _stencil_func = D3DCMP_NOTEQUAL; -// _stencil_op = D3DSTENCILOP_REPLACE; + _d3dDevice->SetRenderState(D3DRENDERSTATE_STENCILENABLE, _stencil_test_enabled); // Antialiasing. enable_line_smooth(false); @@ -700,24 +733,12 @@ init_dx( LPDIRECTDRAW7 context, // 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(DepthTestTransition) dta = new DepthTestTransition; - PT(DepthWriteTransition) dwa = new DepthWriteTransition; - PT(CullFaceTransition) cfa = new CullFaceTransition; - PT(LightTransition) la = new LightTransition; - PT(TextureTransition) ta = new TextureTransition; - - 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 _CurTexBlendMode = TextureApplyProperty::M_modulate; SetTextureBlendMode(_CurTexBlendMode,FALSE); + _texturing_enabled = false; _d3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE); // disables texturing // Init more Texture State @@ -735,8 +756,6 @@ init_dx( LPDIRECTDRAW7 context, _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 - #ifdef _DEBUG if ((_D3DDevDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_MIPMAPLODBIAS) && (dx_global_miplevel_bias!=0.0f)) { @@ -744,8 +763,6 @@ init_dx( LPDIRECTDRAW7 context, } #endif - _d3dDevice->SetRenderState(D3DRENDERSTATE_SHADEMODE, _CurShadeMode); - if(dx_full_screen_antialiasing) { if(_D3DDevDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT) { _d3dDevice->SetRenderState(D3DRENDERSTATE_ANTIALIAS,D3DANTIALIAS_SORTINDEPENDENT); @@ -770,7 +787,16 @@ init_dx( LPDIRECTDRAW7 context, } #endif - // need to release this better, so init_dx can be called multiple times + _d3dDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, dx_force_backface_culling); + + _alpha_func = D3DCMP_ALWAYS; + _alpha_func_ref = 0; + _d3dDevice->SetRenderState(D3DRENDERSTATE_ALPHAFUNC, _alpha_func); + _d3dDevice->SetRenderState(D3DRENDERSTATE_ALPHAREF, _alpha_func_ref); + _alpha_test_enabled = false; + _d3dDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, _alpha_test_enabled); + + // need to release this better, so dx_init can be called multiple times if(dx_show_fps_meter) { _start_time = timeGetTime(); @@ -841,7 +867,10 @@ init_dx( LPDIRECTDRAW7 context, ddsd.dwWidth = texdim_x; ddsd.dwHeight = texdim_y; - assert(_fpsmeter_font_surf==NULL); + if(_fpsmeter_font_surf!=NULL) { + ULONG refcnt; + RELEASE(_fpsmeter_font_surf,dxgsg,"fpsmeter fontsurf",false); + } PRINTREFCNT(_pDD,"pre-fpsmeter-font-create IDirectDraw7"); @@ -863,13 +892,27 @@ init_dx( LPDIRECTDRAW7 context, int numverts=(NUM_FPSMETER_LETTERS+1)*2*3; // +1 for square to hold suffix - _fpsmeter_verts = (DWORD *) new BYTE[_fps_vertexsize*numverts]; //bugbug remember to release this + if(_fpsmeter_verts == NULL) + _fpsmeter_verts = (DWORD *) new BYTE[_fps_vertexsize*numverts]; _fps_u_usedwidth = letterfontareaWidth/(float)texdim_x; _fps_v_usedheight = fontareaHeight/(float)texdim_y; SetFPSMeterPosition(_view_rect); } + + // Make sure the DX state matches all of our initial attribute states. + PT(DepthTestTransition) dta = new DepthTestTransition; + PT(DepthWriteTransition) dwa = new DepthWriteTransition; + PT(CullFaceTransition) cfa = new CullFaceTransition; + PT(LightTransition) la = new LightTransition; + PT(TextureTransition) ta = new TextureTransition; + + dta->issue(this); + dwa->issue(this); + cfa->issue(this); + la->issue(this); + ta->issue(this); // no curtextcontext, this does nothing. dx should already be properly inited above anyway } //////////////////////////////////////////////////////////////////// @@ -894,9 +937,7 @@ clear(const RenderBuffer &buffer) { if (buffer_type & RenderBuffer::T_stencil) flags |= D3DCLEAR_STENCIL; - D3DCOLOR clear_colr = Colorf_to_D3DCOLOR(_color_clear_value); - - HRESULT hr = _d3dDevice->Clear(0, NULL, flags, clear_colr, + HRESULT hr = _d3dDevice->Clear(0, NULL, flags, _d3dcolor_clear_value, (D3DVALUE) _depth_clear_value, (DWORD)_stencil_clear_value); if (hr != DD_OK) dxgsg_cat.error() << "clear_buffer failed: Clear returned " << ConvD3DErrorToString(hr) << endl; @@ -1299,7 +1340,7 @@ render_frame() { _d3dDevice->SetRenderState(D3DRENDERSTATE_FILLMODE, saved_fill_state); } - _d3dDevice->SetTexture(0, _pCurDeviceTexture); + _d3dDevice->SetTexture(0, ((_pCurTexContext != NULL) ? _pCurTexContext->_surface : NULL)); } hr = _d3dDevice->EndScene(); @@ -2707,9 +2748,9 @@ draw_tri(GeomTri *geom, GeomContext *gc) { DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector)); DO_PSTATS_STUFF(_vertices_tri_pcollector.add_level(geom->get_num_vertices())); -#ifdef _DEBUG - if (_pCurTexContext!=NULL) { -// dxgsg_cat.spam() << "Cur active DX texture: " << _pCurTexContext->_tex->get_name() << "\n"; +#if 0 + if (_pCurTexContext!=NULL) { + dxgsg_cat.spam() << "Cur active DX texture: " << _pCurTexContext->_tex->get_name() << "\n"; } #endif @@ -3808,7 +3849,7 @@ apply_texture(TextureContext *tc) { // bind_texture(tc); // specify_texture(tc->_texture); - // Note: if this code changes, make sure to change initialization SetTSS code in init_dx as well + // Note: if this code changes, make sure to change initialization SetTSS code in dx_init as well // so DX TSS renderstate matches dxgsg state DXTextureContext *dtc = DCAST(DXTextureContext, tc); @@ -3844,13 +3885,7 @@ apply_texture(TextureContext *tc) { int aniso_degree=tex->get_anisotropic_degree(); Texture::FilterType ft=tex->get_magfilter(); - if (aniso_degree>1) { - if (aniso_degree!=_CurTexAnisoDegree) { - _CurTexAnisoDegree = aniso_degree; - _d3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_ANISOTROPIC ); - _d3dDevice->SetTextureStageState(0, D3DTSS_MAXANISOTROPY,aniso_degree); - } - } else { + if (aniso_degree<=1) { if (_CurTexMagFilter!=ft) { _CurTexMagFilter = ft; @@ -3861,6 +3896,12 @@ apply_texture(TextureContext *tc) { } #endif } + } else { + if (aniso_degree!=_CurTexAnisoDegree) { + _CurTexAnisoDegree = aniso_degree; + _d3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_ANISOTROPIC ); + _d3dDevice->SetTextureStageState(0, D3DTSS_MAXANISOTROPY,aniso_degree); + } } #ifdef _DEBUG @@ -3942,7 +3983,7 @@ apply_texture(TextureContext *tc) { // bugbug: does this handle the case of untextured geometry? // we dont see this bug cause we never mix textured/untextured - SetDeviceTexture(dtc->_surface); + _d3dDevice->SetTexture(0,dtc->_surface); #if 0 if (dtc!=NULL) { @@ -4400,6 +4441,7 @@ apply_fog(Fog *fog) { Fog::Mode panda_fogmode = fog->get_mode(); D3DFOGMODE d3dfogmode = get_fog_mode_type(panda_fogmode); + // should probably avoid doing redundant SetRenderStates, but whatever _d3dDevice->SetRenderState((D3DRENDERSTATETYPE)_doFogType, d3dfogmode); @@ -5068,8 +5110,7 @@ void DXGraphicsStateGuardian::issue_light(const LightTransition *attrib ) { } } - - +/* //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::reset_ambient // Access: Public, Virtual @@ -5079,7 +5120,7 @@ void DXGraphicsStateGuardian:: reset_ambient() { _lmodel_ambient += 2.0f; } - +*/ //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::issue_color_blend // @@ -5300,26 +5341,19 @@ issue_stencil(const StencilTransition *attrib) { StencilProperty::Mode mode = attrib->get_mode(); -#if 1 - if (mode != StencilProperty::M_none) { - dxgsg_cat.error() << "stencil buffering unimplemented for DX GSG renderer!!!\n"; - // to implement stenciling, need to change wdxGraphicsWindow to create a stencil - // z-buffer or maybe do a SetRenderTarget on a new zbuffer - } - -#else - if (mode == StencilProperty::M_none) { enable_stencil_test(false); - } else { enable_stencil_test(true); + // TODO: need to cache all these _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())); + _d3dDevice->SetRenderState(D3DRENDERSTATE_STENCILPASS, get_stencil_action_type(attrib->get_pass_action())); + _d3dDevice->SetRenderState(D3DRENDERSTATE_STENCILFAIL, get_stencil_action_type(attrib->get_fail_action())); + _d3dDevice->SetRenderState(D3DRENDERSTATE_STENCILZFAIL, get_stencil_action_type(attrib->get_zfail_action())); + _d3dDevice->SetRenderState(D3DRENDERSTATE_STENCILREF, attrib->get_reference_value()); + _d3dDevice->SetRenderState(D3DRENDERSTATE_STENCILMASK, attrib->get_func_mask()); + _d3dDevice->SetRenderState(D3DRENDERSTATE_STENCILWRITEMASK, attrib->get_write_mask()); } -#endif } //////////////////////////////////////////////////////////////////// @@ -5818,9 +5852,6 @@ get_depth_func_type(DepthTestProperty::Mode m) const { return D3DCMP_LESS; } -#if 0 -// ifdef out until stencil zbuf creation works in wdxGraphicsWindow.c - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::get_stencil_func_type // Access: Protected @@ -5838,8 +5869,7 @@ get_stencil_func_type(StencilProperty::Mode m) const { case StencilProperty::M_greater_equal: return D3DCMP_GREATEREQUAL; case StencilProperty::M_always: return D3DCMP_ALWAYS; } - dxgsg_cat.error() - << "Invalid StencilProperty::Mode value" << endl; + dxgsg_cat.error() << "Invalid StencilProperty::Mode value" << endl; return D3DCMP_LESS; } @@ -5859,13 +5889,10 @@ get_stencil_action_type(StencilProperty::Action a) const { case StencilProperty::A_decrement: return D3DSTENCILOP_DECR; case StencilProperty::A_invert: return D3DSTENCILOP_INVERT; } - dxgsg_cat.error() - << "Invalid StencilProperty::Action value" << endl; + dxgsg_cat.error() << "Invalid StencilProperty::Action value" << endl; return D3DSTENCILOP_KEEP; } -#endif - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::get_fog_mode_type // Access: Protected @@ -6228,6 +6255,55 @@ bool refill_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { return hr==S_OK; } +bool delete_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { + DXTextureContext *dtc = DCAST(DXTextureContext, tc); + + // release DDSurf (but not the texture context) + dtc->DeleteTexture(); + return true; +} + +bool recreate_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { + DXTextureContext *dtc = DCAST(DXTextureContext, tc); + DXGraphicsStateGuardian *dxgsg = (DXGraphicsStateGuardian *)void_dxgsg_ptr; + + // Re-fill the contents of textures and vertex buffers + // which just got restored now. + + LPDIRECTDRAWSURFACE7 ddtex = dtc->CreateTexture(dxgsg->_d3dDevice, + dxgsg->_cNumTexPixFmts,dxgsg->_pTexPixFmts); + return ddtex!=NULL; +} + +// release all textures and vertex/index buffers +HRESULT DXGraphicsStateGuardian::DeleteAllVideoSurfaces(void) { + // BUGBUG: need to handle vertexbuffer handling here + + // cant access template in libpanda.dll directly due to vc++ limitations, use traverser to get around it + traverse_prepared_textures(delete_tex_callback,this); + + ULONG refcnt; + + if(dx_show_fps_meter) + RELEASE(_fpsmeter_font_surf,dxgsg,"fpsmeter fontsurf",false); + + if(dxgsg_cat.is_debug()) + dxgsg_cat.debug() << "release of all textures complete\n"; + return S_OK; +} + +// recreate all textures and vertex/index buffers +HRESULT DXGraphicsStateGuardian::RecreateAllVideoSurfaces(void) { + // BUGBUG: need to handle vertexbuffer handling here + + // cant access template in libpanda.dll directly due to vc++ limitations, use traverser to get around it + traverse_prepared_textures(recreate_tex_callback,this); + + if(dxgsg_cat.is_debug()) + dxgsg_cat.debug() << "recreation of all textures complete\n"; + return S_OK; +} + HRESULT DXGraphicsStateGuardian::RestoreAllVideoSurfaces(void) { // BUGBUG: this should also restore vertex buffer contents when they are implemented // You will need to destroy and recreate diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.h b/panda/src/dxgsg/dxGraphicsStateGuardian.h index 10f21a8c5e..b76c29661b 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.h +++ b/panda/src/dxgsg/dxGraphicsStateGuardian.h @@ -122,6 +122,9 @@ extern void dbgPrintVidMem(LPDIRECTDRAW7 pDD, LPDDSCAPS2 lpddsCaps,const char *p // outside of this object. //////////////////////////////////////////////////////////////////// class EXPCL_PANDADX DXGraphicsStateGuardian : public GraphicsStateGuardian { + friend class wdxGraphicsWindow; + friend class DXTextureContext; + public: DXGraphicsStateGuardian(GraphicsWindow *win); ~DXGraphicsStateGuardian(); @@ -220,11 +223,17 @@ public: virtual void end_decal(GeomNode *base_geom); INLINE float compute_distance_to(const LPoint3f &point) const; + virtual void set_color_clear_value(const Colorf& value); - void reset_ambient(); +public: + // recreate_tex_callback needs these to be public + LPDIRECT3DDEVICE7 _d3dDevice; + LPDDPIXELFORMAT _pTexPixFmts; + int _cNumTexPixFmts; protected: - void free_pointers(); + void free_pointers(); // free local internal buffers + void free_dxgsg_objects(void); // free the DirectX objects we create virtual PT(SavedFrameBuffer) save_frame_buffer(const RenderBuffer &buffer, CPT(DisplayRegion) dr); virtual void restore_frame_buffer(SavedFrameBuffer *frame_buffer); @@ -245,15 +254,12 @@ protected: LPDIRECTDRAWSURFACE7 _back; LPDIRECTDRAWSURFACE7 _zbuf; LPDIRECT3D7 _d3d; - LPDIRECT3DDEVICE7 _d3dDevice; LPDIRECTDRAWSURFACE7 _pri; LPDIRECTDRAW7 _pDD; RECT _view_rect; RECT clip_rect; HDC _front_hdc; - int _cNumTexPixFmts; - LPDDPIXELFORMAT _pTexPixFmts; DXTextureContext *_pCurTexContext; bool _bTransformIssued; // decaling needs to tell when a transform has been issued @@ -268,14 +274,16 @@ protected: D3DVECTOR *pCenter, float fRadius, DWORD wNumRings, DWORD wNumSections, float sx, float sy, float sz, DWORD *pNumVertices,DWORD *pNumIndices,DWORD fvfFlags,DWORD dwVertSize); - HRESULT DXGraphicsStateGuardian::RestoreAllVideoSurfaces(void); - - INLINE void set_pack_alignment(int alignment); - INLINE void set_unpack_alignment(int alignment); + HRESULT RestoreAllVideoSurfaces(void); + HRESULT RecreateAllVideoSurfaces(void); + HRESULT DeleteAllVideoSurfaces(void); +/* INLINE void enable_multisample_alpha_one(bool val); INLINE void enable_multisample_alpha_mask(bool val); INLINE void enable_multisample(bool val); +*/ + INLINE void enable_color_material(bool val); INLINE void enable_clip_plane(int clip_plane, bool val); INLINE void enable_fog(bool val); @@ -285,15 +293,9 @@ protected: INLINE D3DCMPFUNC get_depth_func_type(DepthTestProperty::Mode m) const; INLINE D3DFOGMODE get_fog_mode_type(Fog::Mode m) const; - #if 0 - INLINE D3DCMPFUNC get_stencil_func_type(StencilProperty::Mode m) const; - INLINE D3DSTENCILOP get_stencil_action_type(StencilProperty::Action a) const; - #endif + INLINE D3DCMPFUNC get_stencil_func_type(StencilProperty::Mode m) const; + INLINE D3DSTENCILOP get_stencil_action_type(StencilProperty::Action a) const; -/* INLINE void enable_multisample_alpha_one(bool val); - INLINE void enable_multisample_alpha_mask(bool val); - INLINE void enable_multisample(bool val, LPDIRECT3DDEVICE7 d3dDevice); -*/ INLINE void enable_alpha_test(bool val); INLINE void enable_line_smooth(bool val); INLINE void enable_blend(bool val); @@ -328,6 +330,7 @@ protected: bool _enable_all_color; Colorf _issued_color; // WBD ADDED D3DCOLOR _issued_color_D3DCOLOR; // WBD ADDED + D3DCOLOR _d3dcolor_clear_value; D3DSHADEMODE _CurShadeMode; @@ -340,27 +343,12 @@ protected: Geom::TexCoordIterator ti; Geom::ColorIterator ci; - float _clear_color_red, _clear_color_green, _clear_color_blue,_clear_color_alpha; - double _clear_depth; - int _clear_stencil; - float _clear_accum_red, _clear_accum_green, _clear_accum_blue,_clear_accum_alpha; - int _scissor_x; - int _scissor_y; - int _scissor_width; - int _scissor_height; - int _viewport_x; - int _viewport_y; - int _viewport_width; - int _viewport_height; Colorf _lmodel_ambient; float _material_ambient; float _material_diffuse; float _material_specular; float _material_shininess; float _material_emission; - float _line_width; - float _point_size; - bool _depth_mask; typedef enum {None, PerVertexFog=D3DRENDERSTATE_FOGVERTEXMODE, @@ -368,19 +356,20 @@ protected: } DxgsgFogType; DxgsgFogType _doFogType; bool _fog_enabled; - int _fog_mode; +/* + TODO: cache fog state float _fog_start; float _fog_end; float _fog_density; float _fog_color; - float _alpha_func_ref; - D3DCMPFUNC _alpha_func; +*/ + float _alpha_func_ref; + D3DCMPFUNC _alpha_func; + D3DBLEND _blend_source_func; D3DBLEND _blend_dest_func; - bool _multisample_enabled; bool _line_smooth_enabled; - bool _point_smooth_enabled; bool* _light_enabled; // bool[_max_lights] bool _color_material_enabled; bool _lighting_enabled; @@ -389,16 +378,11 @@ protected: bool _dither_enabled; bool _stencil_test_enabled; bool* _clip_plane_enabled; // bool[_max_clip_planes] - bool _multisample_alpha_one_enabled; - bool _multisample_alpha_mask_enabled; bool _blend_enabled; bool _depth_test_enabled; bool _depth_write_enabled; - DWORD _old_colormaskval; bool _alpha_test_enabled; int _decal_level; - LPDIRECTDRAWSURFACE7 _pCurDeviceTexture; - INLINE void SetDeviceTexture(LPDIRECTDRAWSURFACE7 pTexture); RenderModeProperty::Mode _current_fill_mode; //poinr/wireframe/solid @@ -433,8 +417,6 @@ protected: float _current_alpha_offset; float _current_alpha_scale; - int _pass_number; - // vars for frames/sec meter DWORD _start_time; DWORD _start_frame_count; @@ -476,7 +458,7 @@ public: void show_frame(); void show_full_screen_frame(); void show_windowed_frame(); - void init_dx( LPDIRECTDRAW7 context, + void dx_init( LPDIRECTDRAW7 context, LPDIRECTDRAWSURFACE7 pri, LPDIRECTDRAWSURFACE7 back, LPDIRECTDRAWSURFACE7 zbuf, diff --git a/panda/src/dxgsg/dxTextureContext.h b/panda/src/dxgsg/dxTextureContext.h index 3721d8ed5e..bb68334378 100644 --- a/panda/src/dxgsg/dxTextureContext.h +++ b/panda/src/dxgsg/dxTextureContext.h @@ -45,6 +45,9 @@ // Description : //////////////////////////////////////////////////////////////////// class EXPCL_PANDADX DXTextureContext : public TextureContext { + friend class DXGraphicsStateGuardian; + friend class wdxGraphicsWindow; + public: DXTextureContext(Texture *tex); ~DXTextureContext(); @@ -54,10 +57,11 @@ public: LPDIRECTDRAWSURFACE7 CreateTexture(LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts, LPDDPIXELFORMAT pTexPixFmts); - void DeleteTexture(); - bool _bHasMipMaps; DWORD _PixBufConversionType; // enum ConversionType + + // must be public since called from global callback fns + void DeleteTexture(void); HRESULT FillDDSurfTexturePixels(void); protected: @@ -79,8 +83,6 @@ public: private: static TypeHandle _type_handle; - - friend class DXGraphicsStateGuardian; }; diff --git a/panda/src/wdxdisplay/config_wdxdisplay.cxx b/panda/src/wdxdisplay/config_wdxdisplay.cxx index f0694e692d..ca09b53c92 100644 --- a/panda/src/wdxdisplay/config_wdxdisplay.cxx +++ b/panda/src/wdxdisplay/config_wdxdisplay.cxx @@ -60,6 +60,8 @@ init_libwdxdisplay() { GraphicsWindow::get_factory().register_factory( wdxGraphicsWindow::get_class_type(), wdxGraphicsWindow::make_wdxGraphicsWindow); + + set_global_parameters(); } // cant use global var cleanly because global var static init executed after init_libwdxdisplay(), incorrectly reiniting var diff --git a/panda/src/wdxdisplay/wdxGraphicsPipe.cxx b/panda/src/wdxdisplay/wdxGraphicsPipe.cxx index 5788c1caad..2eaf4aac95 100644 --- a/panda/src/wdxdisplay/wdxGraphicsPipe.cxx +++ b/panda/src/wdxdisplay/wdxGraphicsPipe.cxx @@ -62,9 +62,11 @@ TypeHandle wdxGraphicsPipe::get_class_type(void) { return _type_handle; } +const char *pipe_type_name="wdxGraphicsPipe"; + void wdxGraphicsPipe::init_type(void) { InteractiveGraphicsPipe::init_type(); - register_type(_type_handle, "wdxGraphicsPipe", + register_type(_type_handle, pipe_type_name, InteractiveGraphicsPipe::get_class_type()); } @@ -74,18 +76,17 @@ TypeHandle wdxGraphicsPipe::get_type(void) const { wdxGraphicsPipe::wdxGraphicsPipe(void) { wdxdisplay_cat.error() - << "wdxGraphicsPipes should not be created with the default constructor" - << endl; + << pipe_type_name <<"s should not be created with the default constructor" << endl; } wdxGraphicsPipe::wdxGraphicsPipe(const wdxGraphicsPipe&) { wdxdisplay_cat.error() - << "wdxGraphicsPipes should not be copied" << endl; + << pipe_type_name << "s should not be copied" << endl; } wdxGraphicsPipe& wdxGraphicsPipe::operator=(const wdxGraphicsPipe&) { wdxdisplay_cat.error() - << "wdxGraphicsPipes should not be assigned" << endl; + << pipe_type_name << "s should not be assigned" << endl; return *this; } diff --git a/panda/src/wdxdisplay/wdxGraphicsWindow.cxx b/panda/src/wdxdisplay/wdxGraphicsWindow.cxx index 4e9cf066dc..441b00569c 100644 --- a/panda/src/wdxdisplay/wdxGraphicsWindow.cxx +++ b/panda/src/wdxdisplay/wdxGraphicsWindow.cxx @@ -82,7 +82,20 @@ static DWORD BitDepth_2_DDBDMask(DWORD iBitDepth) { } return 0x0; } +/* +typedef enum {DBGLEV_FATAL,DBGLEV_ERROR,DBGLEV_WARNING,DBGLEV_INFO,DBGLEV_DEBUG,DBGLEV_SPAM + } DebugLevels; + +void PrintDBGStr(DebugLevels level,HRESULT hr,const char *msgstr) { + ostream *pstrm; + static ostream dbg_strms[DBGLEV_SPAM+1]={wdxdisplay_cat.fatal,wdxdisplay_cat.error, + wdxdisplay_cat.warning,wdxdisplay_cat.info,wdxdisplay_cat.debug,wdxdisplay_cat.spam}; + assert(level<=DBGLEV_SPAM); + pstrm=dbg_strms[level]; + (*pstrm)->fatal() << "GetDisplayMode failed, result = " << ConvD3DErrorToString(hr) << endl; +} +*/ #ifdef _DEBUG static void DebugPrintPixFmt(DDPIXELFORMAT* pddpf) { static int iddpfnum=0; @@ -223,7 +236,9 @@ void AtExitFn() { #ifdef _DEBUG wdxdisplay_cat.spam() << "AtExitFn called\n"; #endif - + + restore_global_parameters(); + DestroyAllWindows(true); } @@ -259,37 +274,8 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { int x, y, width, height; switch(msg) { - case WM_CREATE: - break; - case WM_CLOSE: - close_window(); - - // BUGBUG: right now there is no way to tell the panda app the graphics window is invalid or - // has been closed by the user, to prevent further methods from being called on the window. - // this needs to be added to panda for multiple windows to work. in the meantime, just - // trigger an exit here if # windows==0, since that is the expected behavior when all - // windows are closed (should be done by the app though, and it assumes you only make this - // type of panda gfx window) - - if(hwnd_pandawin_map.size()==0) { - exit(0); - } - return 0; - - case WM_ACTIVATEAPP: { - #ifdef _DEBUG - wdxdisplay_cat.spam() << "WM_ACTIVATEAPP(" << (bool)(wparam!=0) <<") received\n"; - #endif - - if((!wparam) && _props._fullscreen) { - deactivate_window(); - return 0; - } // dont want to reactivate until window is actually un-minimized (see WM_SIZE) - break; - } - - case WM_PAINT: { + case WM_PAINT: { PAINTSTRUCT ps; BeginPaint(hwnd, &ps); @@ -299,9 +285,27 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { return 0; } + case WM_MOUSEMOVE: + if(!DXREADY) + break; + + x = LOWORD(lparam); + y = HIWORD(lparam); + if(x & 1 << 15) x -= (1 << 16); + if(y & 1 << 15) y -= (1 << 16); + if(mouse_motion_enabled() + && wparam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) { + handle_mouse_motion(x, y); + } else if(mouse_passive_motion_enabled() && + ((wparam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) == 0)) { + handle_mouse_motion(x, y); + } + return 0; + #if 0 case WM_SYSCHAR: case WM_CHAR: // shouldnt receive WM_CHAR unless WM_KEYDOWN stops returning 0 and passes on to DefWindProc break; + #endif case WM_SYSKEYDOWN: case WM_KEYDOWN: { @@ -397,23 +401,6 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { handle_keyrelease(MouseButton::button(button)); return 0; - case WM_MOUSEMOVE: - if(!DXREADY) - break; - - x = LOWORD(lparam); - y = HIWORD(lparam); - if(x & 1 << 15) x -= (1 << 16); - if(y & 1 << 15) y -= (1 << 16); - if(mouse_motion_enabled() - && wparam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) { - handle_mouse_motion(x, y); - } else if(mouse_passive_motion_enabled() && - ((wparam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) == 0)) { - handle_mouse_motion(x, y); - } - return 0; - case WM_MOVE: if(!DXREADY) break; @@ -426,76 +413,10 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { #endif if(_WindowAdjustingType==Resizing) { - - GdiFlush(); - - if(_dxgsg!=NULL) { - _dxgsg->SetDXReady(false); // disable rendering whilst we mess with surfs - - // Want to change rendertarget size without destroying d3d device. To save vid memory - // (and make resizing work on memory-starved 4MB cards), we need to construct - // a temporary mini-sized render target for the d3d device (it cannot point to a - // NULL rendertarget) before creating the fully resized buffers. The old - // rendertargets will be freed when these temp targets are set, and that will give - // us the memory to create the resized target - - LPDIRECTDRAWSURFACE7 pddsDummy = NULL, pddsDummyZ = NULL; - HRESULT hr; - ULONG refcnt; - - DX_DECLARE_CLEAN( DDSURFACEDESC2, ddsd ); - - if(_dxgsg->GetBackBuffer()==NULL) // bugbug why is this ever true?? - return DefWindowProc(hwnd, msg, wparam, lparam); - - _dxgsg->GetBackBuffer()->GetSurfaceDesc(&ddsd); - LPDIRECTDRAW7 pDD = _dxgsg->GetDDInterface(); - - ddsd.dwFlags &= ~DDSD_PITCH; - ddsd.dwWidth = 1; ddsd.dwHeight = 1; - ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER); - - PRINTVIDMEM(pDD,&ddsd.ddsCaps,"dummy backbuf"); - - if(FAILED( hr = pDD->CreateSurface( &ddsd, &pddsDummy, NULL ) )) { - wdxdisplay_cat.fatal() << "Resize CreateSurface for temp backbuf failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - DX_DECLARE_CLEAN( DDSURFACEDESC2, ddsdZ ); - _dxgsg->GetZBuffer()->GetSurfaceDesc(&ddsdZ); - ddsdZ.dwFlags &= ~DDSD_PITCH; - ddsdZ.dwWidth = 1; ddsdZ.dwHeight = 1; - - PRINTVIDMEM(pDD,&ddsdZ.ddsCaps,"dummy zbuf"); - - if(FAILED( hr = pDD->CreateSurface( &ddsdZ, &pddsDummyZ, NULL ) )) { - wdxdisplay_cat.fatal() << "Resize CreateSurface for temp zbuf failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - if(FAILED( hr = pddsDummy->AddAttachedSurface( pddsDummyZ ) )) { - wdxdisplay_cat.fatal() << "Resize AddAttachedSurf for temp zbuf failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - if(FAILED( hr = _dxgsg->GetD3DDevice()->SetRenderTarget( pddsDummy, 0x0 ))) { - wdxdisplay_cat.fatal() - << "Resize failed to set render target to temporary surface, result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - RELEASE(pddsDummyZ,wdxdisplay,"dummy resize zbuffer",false); - RELEASE(pddsDummy,wdxdisplay,"dummy resize rendertarget buffer",false); - } - handle_reshape(true); - - if(_dxgsg!=NULL) { - _dxgsg->SetDXReady(true); - } } - _WindowAdjustingType = NotAdjusting; + _WindowAdjustingType = NotAdjusting; return 0; case WM_ENTERSIZEMOVE: { @@ -523,6 +444,8 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // _dxgsg->CheckCooperativeLevel(DO_REACTIVATE_WINDOW); // else reactivate_window(); // } + + // does the windowed case handle displaychange properly? no. need to recreate all devices } break; @@ -538,7 +461,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { } #endif // old comment -- added SIZE_RESTORED to handle 3dfx case - if((_mwindow==NULL) || ((wparam != SIZE_RESTORED) && (wparam != SIZE_MAXIMIZED))) + if((_mwindow==NULL) || dx_full_screen || ((wparam != SIZE_RESTORED) && (wparam != SIZE_MAXIMIZED))) break; width = LOWORD(lparam); height = HIWORD(lparam); @@ -547,7 +470,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { _WindowAdjustingType = Resizing; // for maximized,unmaximize, need to call resize code artificially - // since no WM_EXITSIZEMOVE is generated + // since no WM_EXITSIZEMOVE is generated. if(wparam==SIZE_MAXIMIZED) { _bSizeIsMaximized=TRUE; window_proc(hwnd, WM_EXITSIZEMOVE, 0x0,0x0); @@ -617,6 +540,8 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { #endif case WM_ERASEBKGND: + // WM_ERASEBKGND will be ignored during resizing, because + // we dont want to redraw as user is manually resizing window if(_WindowAdjustingType) break; return 0; // dont let GDI waste time redrawing the deflt background @@ -652,6 +577,36 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // does app need to know to avoid major computation? } return 0; + + case WM_CLOSE: + close_window(); + + // BUGBUG: right now there is no way to tell the panda app the graphics window is invalid or + // has been closed by the user, to prevent further methods from being called on the window. + // this needs to be added to panda for multiple windows to work. in the meantime, just + // trigger an exit here if # windows==0, since that is the expected behavior when all + // windows are closed (should be done by the app though, and it assumes you only make this + // type of panda gfx window) + + if(hwnd_pandawin_map.size()==0) { + exit(0); + } + return 0; + + //case WM_CREATE: + // break; + + case WM_ACTIVATEAPP: { + #ifdef _DEBUG + wdxdisplay_cat.spam() << "WM_ACTIVATEAPP(" << (bool)(wparam!=0) <<") received\n"; + #endif + + if((!wparam) && _props._fullscreen) { + deactivate_window(); + return 0; + } // dont want to reactivate until window is actually un-minimized (see WM_SIZE) + break; + } } return DefWindowProc(hwnd, msg, wparam, lparam); @@ -664,24 +619,98 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // Description: //////////////////////////////////////////////////////////////////// void wdxGraphicsWindow::handle_reshape(bool bDoDxReset) { - RECT view_rect; - GetClientRect( _mwindow, &view_rect ); - ClientToScreen( _mwindow, (POINT*)&view_rect.left ); // translates top,left pnt - ClientToScreen( _mwindow, (POINT*)&view_rect.right ); // translates right,bottom pnt + + GdiFlush(); - // change _props xsize,ysize - resized((view_rect.right - view_rect.left),(view_rect.bottom - view_rect.top)); + if(bDoDxReset && _dxgsg!=NULL) { + HRESULT hr; - _props._xorg = view_rect.left; // _props origin should reflect upper left of view rectangle - _props._yorg = view_rect.top; + if(_dxgsg->GetBackBuffer()==NULL) { + //assume this is initial creation reshape and ignore this call + return; + } - if(wdxdisplay_cat.is_spam()) { - wdxdisplay_cat.spam() << "reshape to origin: (" << _props._xorg << "," << _props._yorg << "), size: (" << _props._xsize << "," << _props._ysize << ")\n"; - } + if(FAILED(hr = _dxgsg->_pDD->TestCooperativeLevel())) { + wdxdisplay_cat.error() << "TestCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; + return; + } - if((_dxgsg!=NULL) && bDoDxReset) { + _dxgsg->SetDXReady(false); // disable rendering whilst we mess with surfs + + _dxgsg->RestoreAllVideoSurfaces(); + + // Want to change rendertarget size without destroying d3d device. To save vid memory + // (and make resizing work on memory-starved 4MB cards), we need to construct + // a temporary mini-sized render target for the d3d device (it cannot point to a + // NULL rendertarget) before creating the fully resized buffers. The old + // rendertargets will be freed when these temp targets are set, and that will give + // us the memory to create the resized target + + LPDIRECTDRAWSURFACE7 pddsDummy = NULL, pddsDummyZ = NULL; + ULONG refcnt; + + DX_DECLARE_CLEAN( DDSURFACEDESC2, ddsd ); + + _dxgsg->GetBackBuffer()->GetSurfaceDesc(&ddsd); + LPDIRECTDRAW7 pDD = _dxgsg->GetDDInterface(); + + ddsd.dwFlags &= ~DDSD_PITCH; + ddsd.dwWidth = 1; ddsd.dwHeight = 1; + ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER); + + PRINTVIDMEM(pDD,&ddsd.ddsCaps,"dummy backbuf"); + + if(FAILED( hr = pDD->CreateSurface( &ddsd, &pddsDummy, NULL ) )) { + wdxdisplay_cat.fatal() << "Resize CreateSurface for temp backbuf failed : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + DX_DECLARE_CLEAN( DDSURFACEDESC2, ddsdZ ); + _dxgsg->GetZBuffer()->GetSurfaceDesc(&ddsdZ); + ddsdZ.dwFlags &= ~DDSD_PITCH; + ddsdZ.dwWidth = 1; ddsdZ.dwHeight = 1; + + PRINTVIDMEM(pDD,&ddsdZ.ddsCaps,"dummy zbuf"); + + if(FAILED( hr = pDD->CreateSurface( &ddsdZ, &pddsDummyZ, NULL ) )) { + wdxdisplay_cat.fatal() << "Resize CreateSurface for temp zbuf failed : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + if(FAILED( hr = pddsDummy->AddAttachedSurface( pddsDummyZ ) )) { + wdxdisplay_cat.fatal() << "Resize AddAttachedSurf for temp zbuf failed : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + if(FAILED( hr = _dxgsg->GetD3DDevice()->SetRenderTarget( pddsDummy, 0x0 ))) { + wdxdisplay_cat.fatal() + << "Resize failed to set render target to temporary surface, result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + RELEASE(pddsDummyZ,wdxdisplay,"dummy resize zbuffer",false); + RELEASE(pddsDummy,wdxdisplay,"dummy resize rendertarget buffer",false); + } + + RECT view_rect; + GetClientRect( _mwindow, &view_rect ); + ClientToScreen( _mwindow, (POINT*)&view_rect.left ); // translates top,left pnt + ClientToScreen( _mwindow, (POINT*)&view_rect.right ); // translates right,bottom pnt + + // change _props xsize,ysize + resized((view_rect.right - view_rect.left),(view_rect.bottom - view_rect.top)); + + _props._xorg = view_rect.left; // _props origin should reflect upper left of view rectangle + _props._yorg = view_rect.top; + + if(wdxdisplay_cat.is_spam()) { + wdxdisplay_cat.spam() << "reshape to origin: (" << _props._xorg << "," << _props._yorg << "), size: (" << _props._xsize << "," << _props._ysize << ")\n"; + } + + if(_dxgsg!=NULL) { + if(bDoDxReset) _dxgsg->dx_setup_after_resize(view_rect,_mwindow); // create the new resized rendertargets - } + _dxgsg->SetDXReady(true); + } } void wdxGraphicsWindow::deactivate_window(void) { @@ -974,7 +1003,7 @@ HRESULT CALLBACK EnumDevicesCallback(LPSTR pDeviceDescription, LPSTR pDeviceName return DDENUMRET_OK; } -#define MAX_DISPLAY_MODES 100 +#define MAX_DISPLAY_MODES 100 // probably dont need this much, since i already screen for width&hgt typedef struct { DWORD maxWidth,maxHeight; DWORD supportedBitDepths; // uses DDBD_* flags @@ -985,10 +1014,8 @@ typedef struct { HRESULT WINAPI EnumDisplayModesCallBack(LPDDSURFACEDESC2 lpDDSurfaceDesc,LPVOID lpContext) { DisplayModeInfo *pDMI = (DisplayModeInfo *) lpContext; - // ignore everything over specified dimensions - if((lpDDSurfaceDesc->dwWidth > pDMI->maxWidth) || - (lpDDSurfaceDesc->dwHeight > pDMI->maxHeight)) - return DDENUMRET_OK; + // ddsd_search should assure this is true + assert((lpDDSurfaceDesc->dwWidth == pDMI->maxWidth) && (lpDDSurfaceDesc->dwHeight == pDMI->maxHeight)); // ignore refresh rates under 60Hz (and special values of 0 & 1) if((lpDDSurfaceDesc->dwRefreshRate>1) && (lpDDSurfaceDesc->dwRefreshRate<60)) @@ -1017,8 +1044,145 @@ BOOL WINAPI DriverEnumCallback( GUID* pGUID, TCHAR* strDesc,TCHAR* strName, return DDENUMRET_OK; } -//void wdxGraphicsWindow::resize(unsigned int xsize,unsigned int ysize) { -//} +void wdxGraphicsWindow::resize(unsigned int xsize,unsigned int ysize) { + if(wdxdisplay_cat.is_debug()) + wdxdisplay_cat.debug() << "resize("<SetDXReady(false); + + HRESULT hr; + + DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd_curmode); + + if(FAILED(hr = _dxgsg->_pDD->GetDisplayMode(&ddsd_curmode))) { + wdxdisplay_cat.fatal() << "resize() - GetDisplayMode failed, result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd_search); + + ddsd_search.dwFlags = DDSD_HEIGHT | DDSD_WIDTH; + ddsd_search.dwWidth=xsize; ddsd_search.dwHeight=ysize; + + // not requesting same refresh rate since changing res might not support same refresh rate + + DDSURFACEDESC2 DDSD_Arr[MAX_DISPLAY_MODES]; + DisplayModeInfo DMI; + ZeroMemory(&DDSD_Arr,sizeof(DDSD_Arr)); + ZeroMemory(&DMI,sizeof(DMI)); + DMI.maxWidth=xsize; DMI.maxHeight=ysize; + DMI.pDDSD_Arr=DDSD_Arr; + + if(FAILED(hr = _dxgsg->_pDD->EnumDisplayModes(DDEDM_REFRESHRATES,&ddsd_search,&DMI,EnumDisplayModesCallBack))) { + wdxdisplay_cat.fatal() << "resize() - EnumDisplayModes failed, result = " << ConvD3DErrorToString(hr) << endl; + return; + } + + DMI.supportedBitDepths &= _dxgsg->_D3DDevDesc.dwDeviceRenderBitDepth; + + DWORD dwFullScreenBitDepth; + DWORD requested_bpp=ddsd_curmode.ddpfPixelFormat.dwRGBBitCount; + + // would like to match current bpp first. if that is not possible, try 16bpp, then 32 + DWORD requested_bpp_DDBD = BitDepth_2_DDBDMask(requested_bpp); + + if(DMI.supportedBitDepths & requested_bpp_DDBD) { + dwFullScreenBitDepth=requested_bpp; + } else if(DMI.supportedBitDepths & DDBD_16) { + dwFullScreenBitDepth=16; + } else if(DMI.supportedBitDepths & DDBD_32) { + dwFullScreenBitDepth=32; + } else { + wdxdisplay_cat.error() + << "resize failed, no fullScreen resolutions at " << xsize << "x" << ysize << endl; + return; + } + + if(FAILED(hr = _dxgsg->_pDD->TestCooperativeLevel())) { + wdxdisplay_cat.error() << "TestCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; + wdxdisplay_cat.error() << "Full screen app failed to get exclusive mode on resize, exiting..\n"; + return; + } + + _dxgsg->free_dxgsg_objects(); + + // let driver choose default refresh rate (hopefully its >=60Hz) + if(FAILED( hr = _dxgsg->_pDD->SetDisplayMode( xsize,ysize,dwFullScreenBitDepth, 0L, 0L ))) { + wdxdisplay_cat.error() << "resize failed to reset display mode to (" << xsize <<"x"<_pDD,_dxgsg->_d3d,NULL); + _dxgsg->RecreateAllVideoSurfaces(); + _dxgsg->SetDXReady(true); +} + +unsigned int wdxGraphicsWindow:: +verify_window_sizes(unsigned int numsizes,unsigned int *dimen) { + DWORD num_valid_modes=0; + HRESULT hr; + + // not requesting same refresh rate since changing res might not support same refresh rate at new size + + DDSURFACEDESC2 DDSD_Arr[MAX_DISPLAY_MODES]; + DisplayModeInfo DMI; + DWORD i,*pCurDim=(DWORD *)dimen; + + + for(i=0;i_pDD->EnumDisplayModes(DDEDM_REFRESHRATES,&ddsd_search,&DMI,EnumDisplayModesCallBack))) { + wdxdisplay_cat.fatal() << "resize() - EnumDisplayModes failed, result = " << ConvD3DErrorToString(hr) << endl; + return 0; + } + + // get rid of bpp's we cant render at + DMI.supportedBitDepths &= _dxgsg->_D3DDevDesc.dwDeviceRenderBitDepth; + + bool bIsGoodMode=false; + + if(_bIsLowVidMemCard) + bIsGoodMode=(((float)xsize*(float)ysize)<=(float)(640*480)); + else bIsGoodMode=((DMI.supportedBitDepths & (DDBD_16 | DDBD_24 | DDBD_32))!=0); + + if(bIsGoodMode) + num_valid_modes++; + else { + pCurDim[0] = 0; + pCurDim[1] = 0; + } + } + + return num_valid_modes; +} //////////////////////////////////////////////////////////////////// // Function: dx_setup @@ -1029,22 +1193,16 @@ BOOL WINAPI DriverEnumCallback( GUID* pGUID, TCHAR* strDesc,TCHAR* strName, //////////////////////////////////////////////////////////////////// void wdxGraphicsWindow:: dx_setup() { - LPDIRECTDRAWSURFACE7 pBackDDSurf; - LPDIRECTDRAWSURFACE7 pZDDSurf; LPDIRECT3D7 pD3DI; - LPDIRECT3DDEVICE7 pD3DDevice; - LPDIRECTDRAWSURFACE7 pPrimaryDDSurf; LPDIRECTDRAW7 pDD; - RECT view_rect; - int i; HRESULT hr; DX_DECLARE_CLEAN( DDSURFACEDESC2, SurfaceDesc ); - // Check for DirectX 7 by looking for DirectDrawCreateEx + // Check for DirectX 7 by looking for DirectDrawCreateEx HINSTANCE DDHinst = LoadLibrary( "ddraw.dll" ); if(DDHinst == 0) { - wdxdisplay_cat.fatal() << "error: DDRAW.DLL doesn't exist!" << endl; + wdxdisplay_cat.fatal() << "can't locate DDRAW.DLL!" << endl; exit(1); } @@ -1079,16 +1237,15 @@ dx_setup() { FreeLibrary(DDHinst); //undo LoadLib above, decrement ddrawl.dll refcnt (after DDrawCreate, since dont want to unload/reload) - DDDEVICEIDENTIFIER2 dddi; - pDD->GetDeviceIdentifier(&dddi,0x0); + pDD->GetDeviceIdentifier(&_DXDeviceID,0x0); #ifdef _DEBUG - wdxdisplay_cat.debug() << " GfxCard: " << dddi.szDescription << "; DriverFile: '" << dddi.szDriver << "'; VendorID: " <QueryInterface( IID_IDirect3D7, (VOID**)&pD3DI ); @@ -1097,16 +1254,17 @@ dx_setup() { exit(1); } - // just look for HAL and TnL devices right now. I dont think - // we have any interest in the sw rasts at this point + D3DDEVICEDESC7 d3ddevs[2]; // put HAL in 0, TnLHAL in 1 + + + // just look for HAL and TnL devices right now. I dont think + // we have any interest in the sw rasts at this point - D3DDEVICEDESC7 d3ddevs[2]; // put HAL in 0, TnLHAL in 1 ZeroMemory(d3ddevs,2*sizeof(D3DDEVICEDESC7)); hr = pD3DI->EnumDevices(EnumDevicesCallback,d3ddevs); if(hr != DD_OK) { - wdxdisplay_cat.fatal() - << "EnumDevices failed : result = " << ConvD3DErrorToString(hr) << endl; + wdxdisplay_cat.fatal() << "EnumDevices failed : result = " << ConvD3DErrorToString(hr) << endl; exit(1); } @@ -1122,158 +1280,215 @@ dx_setup() { DeviceIdx=TNLHALIDX; } + D3DDEVICEDESC7 *pD3DDevDesc=&d3ddevs[DeviceIdx]; + + DWORD dwRenderWidth=0, dwRenderHeight=0; + + if(dx_full_screen) { + dwRenderWidth = _props._xsize; + dwRenderHeight = _props._ysize; + _props._xorg = _props._yorg = 0; + + // CREATE FULL SCREEN BUFFERS + // Store the rectangle which contains the renderer + + DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd_search); + ddsd_search.dwFlags = DDSD_HEIGHT | DDSD_WIDTH; + ddsd_search.dwWidth=dwRenderWidth; ddsd_search.dwHeight=dwRenderHeight; + + DDSURFACEDESC2 DDSD_Arr[MAX_DISPLAY_MODES]; + DisplayModeInfo DMI; + ZeroMemory(&DDSD_Arr,sizeof(DDSD_Arr)); + ZeroMemory(&DMI,sizeof(DMI)); + DMI.maxWidth=dwRenderWidth; DMI.maxHeight=dwRenderHeight; + DMI.pDDSD_Arr=DDSD_Arr; + + if(FAILED(hr= pDD->EnumDisplayModes(DDEDM_REFRESHRATES,&ddsd_search,&DMI,EnumDisplayModesCallBack))) { + wdxdisplay_cat.fatal() << "EnumDisplayModes failed, result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + DWORD dwFullScreenBitDepth; + + // Now we try to figure out if we can use requested screen resolution and best + // rendertarget bpp and still have at least 2 meg of texture vidmem + + // Get Current VidMem avail. Note this is only an estimate, when we switch to fullscreen + // mode from desktop, more vidmem will be available (typically 1.2 meg). I dont want + // to switch to fullscreen more than once due to the annoying monitor flicker, so try + // to figure out optimal mode using this estimate + DDSCAPS2 ddsCaps; + DWORD dwTotal,dwFree; + ZeroMemory(&ddsCaps,sizeof(DDSCAPS2)); + ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY; //set internally by DX anyway, dont think this any different than 0x0 + + if(FAILED( hr = pDD->GetAvailableVidMem(&ddsCaps,&dwTotal,&dwFree))) { + wdxdisplay_cat.error() << "GetAvailableVidMem failed : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + #ifdef _DEBUG + wdxdisplay_cat.debug() << "before FullScreen switch: GetAvailableVidMem returns Total: " << dwTotal/1000000.0 << " Free: " << dwFree/1000000.0 << endl; + #endif + + DMI.supportedBitDepths &= pD3DDevDesc->dwDeviceRenderBitDepth; + + // note: this chooses 32bpp, which may not be preferred over 16 for memory & speed reasons + if(DMI.supportedBitDepths & DDBD_32) { + dwFullScreenBitDepth=32; // go for 32bpp if its avail + } else if(DMI.supportedBitDepths & DDBD_24) { + dwFullScreenBitDepth=24; // go for 24bpp if its avail + } else if(DMI.supportedBitDepths & DDBD_16) { + dwFullScreenBitDepth=16; // do 16bpp + } else { + wdxdisplay_cat.fatal() + << "No Supported FullScreen resolutions at " << dwRenderWidth << "x" << dwRenderHeight << endl; + exit(1); + } + + if(dwFree>0) { // assume buggy drivers (this means you, FireGL2) may return zero for dwTotal, so ignore value if its 0 + + // hack: figuring out exactly what res to use is tricky, instead I will + // just use 640x480 if we have < 3 meg avail + + #define LOWVIDMEMTHRESHOLD 3500000 + if(dwFree< LOWVIDMEMTHRESHOLD) { + // we're going to need 800x600 or 640x480 at 16 bit to save enough tex vidmem + dwFullScreenBitDepth=16; // do 16bpp + dwRenderWidth=640; + dwRenderHeight=480; + _bIsLowVidMemCard = true; + wdxdisplay_cat.debug() << " "<>3); + int memleft = dwFree-rendertargetmem*2; //*2 to handle backbuf/zbuf + + if(memleft < RESERVEDTEXVIDMEM) { + dwFullScreenBitDepth=16; + wdxdisplay_cat.debug() << "using 16bpp rendertargets to save tex vidmem\n"; + assert((DMI.supportedBitDepths & DDBD_16) && (pD3DDevDesc->dwDeviceRenderBitDepth & DDBD_16)); // probably a safe assumption + rendertargetmem=dwRenderWidth*dwRenderHeight*(dwFullScreenBitDepth>>3); + memleft = dwFree-rendertargetmem*2; + + // BUGBUG: if we still cant reserve 2 megs of vidmem, need to auto-reduce the scrn res + if(memleft < RESERVEDTEXVIDMEM) + wdxdisplay_cat.debug() << " XXXXXX WARNING: cant reserve 2MB of tex vidmem. only " << memleft << " bytes available. Need to rewrite wdxdisplay to try lower resolutions XXXXXXXXXXXXXXXXXXXX\n"; + } + #endif + } + + // extern bool dx_preserve_fpu_state; + DWORD SCL_FPUFlag = DDSCL_FPUSETUP; + + // if(dx_preserve_fpu_state) + // SCL_FPUFlag = DDSCL_FPUPRESERVE; // tell d3d to preserve the fpu state across calls. this hurts perf, but is good for dbgging + + DWORD SCL_FLAGS = SCL_FPUFlag | DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT; + + if(FAILED(hr = pDD->SetCooperativeLevel(_mwindow, SCL_FLAGS))) { + wdxdisplay_cat.fatal() << "SetCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + // s3 savage2000 on w95 seems to set EXCLUSIVE_MODE only if you call SetCoopLevel twice. + // so we do it, it really shouldnt be necessary if drivers werent buggy + if(FAILED(hr = pDD->SetCooperativeLevel(_mwindow, SCL_FLAGS))) { + wdxdisplay_cat.fatal() + << "SetCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + if(FAILED(hr = pDD->TestCooperativeLevel())) { + wdxdisplay_cat.fatal() << "TestCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; + wdxdisplay_cat.fatal() << "Full screen app failed to get exclusive mode on init, exiting..\n"; + exit(1); + } + + // let driver choose default refresh rate (hopefully its >=60Hz) + if(FAILED( hr = pDD->SetDisplayMode( dwRenderWidth, dwRenderHeight, + dwFullScreenBitDepth, 0L, 0L ))) { + wdxdisplay_cat.fatal() << "failed to reset display mode to ("<GetAvailableVidMem(&ddsCaps,&dwTotal,&dwFree))) { + wdxdisplay_cat.debug() << "GetAvailableVidMem failed : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + wdxdisplay_cat.debug() << "after FullScreen switch: GetAvailableVidMem returns Total: " << dwTotal/1000000.0 << " Free: " << dwFree/1000000.0 << endl; + #endif + } + } + + CreateScreenBuffersAndDevice(dwRenderWidth,dwRenderHeight,pDD,pD3DI,pD3DDevDesc); + + _dxgsg->SetDXReady(true); +} + + +void wdxGraphicsWindow:: +CreateScreenBuffersAndDevice(DWORD dwRenderWidth, DWORD dwRenderHeight,LPDIRECTDRAW7 pDD, + LPDIRECT3D7 pD3DI,D3DDEVICEDESC7 *pD3DDevDesc) { + LPDIRECTDRAWSURFACE7 pPrimaryDDSurf,pBackDDSurf,pZDDSurf; + LPDIRECT3DDEVICE7 pD3DDevice; + RECT view_rect; + int i; + HRESULT hr; + DX_DECLARE_CLEAN( DDSURFACEDESC2, SurfaceDesc ); + D3DDEVICEDESC7 d3ddevs[2]; // put HAL in 0, TnLHAL in 1 + + assert(pDD!=NULL); + assert(pD3DI!=NULL); + + // select the best device if the caller does not provide one + if(pD3DDevDesc==NULL) { + + // just look for HAL and TnL devices right now. I dont think + // we have any interest in the sw rasts at this point + + ZeroMemory(d3ddevs,2*sizeof(D3DDEVICEDESC7)); + + hr = pD3DI->EnumDevices(EnumDevicesCallback,d3ddevs); + if(hr != DD_OK) { + wdxdisplay_cat.fatal() << "EnumDevices failed : result = " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + + WORD DeviceIdx=REGHALIDX; + + if(!(d3ddevs[DeviceIdx].dwDevCaps & D3DDEVCAPS_HWRASTERIZATION )) { + wdxdisplay_cat.fatal() << "No 3D HW present, exiting..." << endl; + exit(1); + } + + // select TNL if present + if(d3ddevs[TNLHALIDX].dwDevCaps & D3DDEVCAPS_HWRASTERIZATION) { + DeviceIdx=TNLHALIDX; + } + + pD3DDevDesc=&d3ddevs[DeviceIdx]; + } + DX_DECLARE_CLEAN(DDCAPS,DDCaps); pDD->GetCaps(&DDCaps,NULL); - DWORD dwRenderWidth,dwRenderHeight; - - if(dx_full_screen) { - dwRenderWidth = _props._xsize; - dwRenderHeight = _props._ysize; - _props._xorg = _props._yorg = 0; - - // CREATE FULL SCREEN BUFFERS - // Store the rectangle which contains the renderer - - DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd_search); - ddsd_search.dwFlags = DDSD_HEIGHT | DDSD_WIDTH; - ddsd_search.dwWidth=dwRenderWidth; ddsd_search.dwHeight=dwRenderHeight; - - DDSURFACEDESC2 DDSD_Arr[MAX_DISPLAY_MODES]; - DisplayModeInfo DMI; - ZeroMemory(&DDSD_Arr,sizeof(DDSD_Arr)); - ZeroMemory(&DMI,sizeof(DMI)); - DMI.maxWidth=dwRenderWidth; DMI.maxHeight=dwRenderHeight; - DMI.pDDSD_Arr=DDSD_Arr; - - if(FAILED(hr= pDD->EnumDisplayModes(DDEDM_REFRESHRATES,&ddsd_search,&DMI,EnumDisplayModesCallBack))) { - wdxdisplay_cat.fatal() << "EnumDisplayModes failed, result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - DWORD dwFullScreenBitDepth; - - // Now we try to figure out if we can use requested screen resolution and best - // rendertarget bpp and still have at least 2 meg of texture vidmem - - // Get Current VidMem avail. Note this is only an estimate, when we switch to fullscreen - // mode from desktop, more vidmem will be available (typically 1.2 meg). I dont want - // to switch to fullscreen more than once due to the annoying monitor flicker, so try - // to figure out optimal mode using this estimate - DDSCAPS2 ddsCaps; - DWORD dwTotal,dwFree; - ZeroMemory(&ddsCaps,sizeof(DDSCAPS2)); - ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY; //set internally by DX anyway, dont think this any different than 0x0 - - if(FAILED( hr = pDD->GetAvailableVidMem(&ddsCaps,&dwTotal,&dwFree))) { - wdxdisplay_cat.error() << "GetAvailableVidMem failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - -#ifdef _DEBUG - wdxdisplay_cat.debug() << "before FullScreen switch: GetAvailableVidMem returns Total: " << dwTotal/1000000.0 << " Free: " << dwFree/1000000.0 << endl; -#endif - - // note: this chooses 32bpp, which may not be preferred over 16 for memory & speed reasons - if((DMI.supportedBitDepths & DDBD_32) && (d3ddevs[DeviceIdx].dwDeviceRenderBitDepth & DDBD_32)) { - dwFullScreenBitDepth=32; // go for 32bpp if its avail - } else if((DMI.supportedBitDepths & DDBD_24) && (d3ddevs[DeviceIdx].dwDeviceRenderBitDepth & DDBD_24)) { - dwFullScreenBitDepth=24; // go for 24bpp if its avail - } else if((DMI.supportedBitDepths & DDBD_16) && (d3ddevs[DeviceIdx].dwDeviceRenderBitDepth & DDBD_16)) { - dwFullScreenBitDepth=16; // do 16bpp - } else { - wdxdisplay_cat.fatal() - << "No Supported FullScreen resolutions at " << dwRenderWidth << "x" << dwRenderHeight << endl; - exit(1); - } - - if(dwFree>0) { // assume buggy drivers (this means you, FireGL2) may return zero for dwTotal, so ignore value if its 0 - - // hack: figuring out exactly what res to use is tricky, instead I will - // just use 640x480 if we have < 3 meg avail - - #define LOWVIDMEMTHRESHOLD 3500000 - if(dwFree< LOWVIDMEMTHRESHOLD) { - // we're going to need 800x600 or 640x480 at 16 bit to save enough tex vidmem - dwFullScreenBitDepth=16; // do 16bpp - dwRenderWidth=640; - dwRenderHeight=480; - wdxdisplay_cat.debug() << " "<>3); - int memleft = dwFree-rendertargetmem*2; //*2 to handle backbuf/zbuf - - if(memleft < RESERVEDTEXVIDMEM) { - dwFullScreenBitDepth=16; - wdxdisplay_cat.debug() << "using 16bpp rendertargets to save tex vidmem\n"; - assert((DMI.supportedBitDepths & DDBD_16) && (d3ddevs[DeviceIdx].dwDeviceRenderBitDepth & DDBD_16)); // probably a safe assumption - rendertargetmem=dwRenderWidth*dwRenderHeight*(dwFullScreenBitDepth>>3); - memleft = dwFree-rendertargetmem*2; - - // BUGBUG: if we still cant reserve 2 megs of vidmem, need to auto-reduce the scrn res - if(memleft < RESERVEDTEXVIDMEM) - wdxdisplay_cat.debug() << " XXXXXX WARNING: cant reserve 2MB of tex vidmem. only " << memleft << " bytes available. Need to rewrite wdxdisplay to try lower resolutions XXXXXXXXXXXXXXXXXXXX\n"; - } - #endif - } - -// extern bool dx_preserve_fpu_state; - DWORD SCL_FPUFlag = DDSCL_FPUSETUP; - -// if(dx_preserve_fpu_state) -// SCL_FPUFlag = DDSCL_FPUPRESERVE; // tell d3d to preserve the fpu state across calls. this hurts perf, but is good for dbgging - - DWORD SCL_FLAGS = SCL_FPUFlag | DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT; - - if(FAILED(hr = pDD->SetCooperativeLevel(_mwindow, SCL_FLAGS))) { - wdxdisplay_cat.fatal() << "SetCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - // s3 savage2000 on w95 seems to set EXCLUSIVE_MODE only if you call SetCoopLevel twice. - // so we do it, it really shouldnt be necessary if drivers werent buggy - if(FAILED(hr = pDD->SetCooperativeLevel(_mwindow, SCL_FLAGS))) { - wdxdisplay_cat.fatal() - << "SetCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - if(FAILED(hr = pDD->TestCooperativeLevel())) { - wdxdisplay_cat.fatal() << "TestCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; - wdxdisplay_cat.fatal() << "Full screen app failed to get exclusive mode on init, exiting..\n"; - exit(1); - } - - if(FAILED( hr = pDD->SetDisplayMode( dwRenderWidth, dwRenderHeight, - dwFullScreenBitDepth, 0L, 0L ))) { - wdxdisplay_cat.fatal() << "failed to reset display mode to ("<GetAvailableVidMem(&ddsCaps,&dwTotal,&dwFree))) { - wdxdisplay_cat.debug() << "GetAvailableVidMem failed : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - wdxdisplay_cat.debug() << "after FullScreen switch: GetAvailableVidMem returns Total: " << dwTotal/1000000.0 << " Free: " << dwFree/1000000.0 << endl; - #endif - } - + if(dx_full_screen) { // Setup to create the primary surface w/backbuffer DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd) ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT; @@ -1322,6 +1537,7 @@ dx_setup() { } // end create full screen buffers else { // CREATE WINDOWED BUFFERS + assert(dwRenderWidth==0 && dwRenderHeight==0); // these params are ignored for windowed mode if(!(DDCaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED)) { wdxdisplay_cat.fatal() << "the 3D HW cannot render windowed, exiting..." << endl; @@ -1338,7 +1554,7 @@ dx_setup() { exit(1); } - if(!(BitDepth_2_DDBDMask(SurfaceDesc.ddpfPixelFormat.dwRGBBitCount) & d3ddevs[DeviceIdx].dwDeviceRenderBitDepth)) { + if(!(BitDepth_2_DDBDMask(SurfaceDesc.ddpfPixelFormat.dwRGBBitCount) & pD3DDevDesc->dwDeviceRenderBitDepth)) { wdxdisplay_cat.fatal() << "3D Device doesnt support rendering at " << SurfaceDesc.ddpfPixelFormat.dwRGBBitCount << "bpp (current desktop bitdepth)" << endl; exit(1); } @@ -1453,7 +1669,7 @@ dx_setup() { // Check if the device supports z-bufferless hidden surface removal. If so, // we don't really need a z-buffer - if((!(d3ddevs[DeviceIdx].dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR )) && + if((!(pD3DDevDesc->dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR )) && (_props._mask & W_DEPTH)) { // Get z-buffer dimensions from the render target @@ -1514,8 +1730,8 @@ dx_setup() { exit(1); } - if(bIsNvidia) { - DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd_pri) + if(ISNVIDIA(_DXDeviceID)) { + DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd_pri) pPrimaryDDSurf->GetSurfaceDesc(&ddsd_pri); // must pick zbuf depth to match primary surface depth for nvidia @@ -1583,7 +1799,7 @@ dx_setup() { // Create the device. The device is created off of our back buffer, which // becomes the render target for the newly created device. - hr = pD3DI->CreateDevice(d3ddevs[DeviceIdx].deviceGUID, pBackDDSurf, &pD3DDevice ); + hr = pD3DI->CreateDevice(pD3DDevDesc->deviceGUID, pBackDDSurf, &pD3DDevice ); if(hr != DD_OK) { wdxdisplay_cat.fatal() << "CreateDevice failed : result = " << ConvD3DErrorToString(hr) << endl; exit(1); @@ -1598,9 +1814,8 @@ dx_setup() { } _dxgsg->Set_HDC(_hdc); - _dxgsg->init_dx(pDD, pPrimaryDDSurf, pBackDDSurf, pZDDSurf, pD3DI, pD3DDevice, view_rect); - - _dxgsg->SetDXReady(true); + _dxgsg->dx_init(pDD, pPrimaryDDSurf, pBackDDSurf, pZDDSurf, pD3DI, pD3DDevice, view_rect); + // do not SetDXReady() yet since caller may want to do more work before letting rendering proceed } //////////////////////////////////////////////////////////////////// @@ -2012,3 +2227,39 @@ lookup_key(WPARAM wparam) const { } return ButtonHandle::none(); } + +// Global system parameters we want to modify during our run +static int iMouseTrails; +static bool bCursorShadowOn,bMouseVanish; + +#ifndef SPI_GETMOUSEVANISH +// get of this when we upgrade to winxp winuser.h +#define SPI_GETMOUSEVANISH 0x1020 +#define SPI_SETMOUSEVANISH 0x1021 +#endif + +void set_global_parameters(void) { + // turn off mousetrails and cursor shadow and mouse cursor vanish + // cursor shadow causes cursor blink and reduced frame rate due to lack of driver support for + // cursor alpha blending + + // this is a win2k/xp only param, could use GetVersionEx to do it just for win2k, + // but since it is just a param it will just cause a silent error on other OS's + // that should be ok + SystemParametersInfo(SPI_GETCURSORSHADOW,NULL,&bCursorShadowOn,NULL); + SystemParametersInfo(SPI_SETCURSORSHADOW,NULL,(PVOID)false,NULL); + + SystemParametersInfo(SPI_GETMOUSETRAILS,NULL,&iMouseTrails,NULL); + SystemParametersInfo(SPI_SETMOUSETRAILS,NULL,(PVOID)0,NULL); + + // this is ME/XP only feature + SystemParametersInfo(SPI_GETMOUSEVANISH,NULL,&bMouseVanish,NULL); + SystemParametersInfo(SPI_SETMOUSEVANISH,NULL,(PVOID)false,NULL); +} + +void restore_global_parameters(void) { + SystemParametersInfo(SPI_SETCURSORSHADOW,NULL,(PVOID)bCursorShadowOn,NULL); + SystemParametersInfo(SPI_SETMOUSETRAILS,NULL,(PVOID)iMouseTrails,NULL); + SystemParametersInfo(SPI_SETMOUSEVANISH,NULL,(PVOID)bMouseVanish,NULL); +} + diff --git a/panda/src/wdxdisplay/wdxGraphicsWindow.h b/panda/src/wdxdisplay/wdxGraphicsWindow.h index 5d2a23a0e7..e621e5d92b 100644 --- a/panda/src/wdxdisplay/wdxGraphicsWindow.h +++ b/panda/src/wdxdisplay/wdxGraphicsWindow.h @@ -44,8 +44,8 @@ const int WDXWIN_EVENT = 8; // Description : //////////////////////////////////////////////////////////////////// class EXPCL_PANDADX wdxGraphicsWindow : public GraphicsWindow { - -friend class DXGraphicsStateGuardian; + friend class DXGraphicsStateGuardian; + friend class DXTextureContext; public: wdxGraphicsWindow(GraphicsPipe* pipe); @@ -59,6 +59,9 @@ public: virtual TypeHandle get_gsg_type() const; static GraphicsWindow* make_wdxGraphicsWindow(const FactoryParams ¶ms); + void CreateScreenBuffersAndDevice(DWORD dwRenderWidth, DWORD dwRenderHeight, + LPDIRECTDRAW7 pDD,LPDIRECT3D7 pD3DI, + D3DDEVICEDESC7 *pD3DDevDesc); LONG window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); void process_events(void); @@ -78,10 +81,11 @@ public: void show_frame(); DXGraphicsStateGuardian *_dxgsg; -// virtual void resize(unsigned int xsize,unsigned int ysize); -// virtual unsigned int verify_window_sizes(unsigned int numsizes,unsigned int *dimen); + virtual void resize(unsigned int xsize,unsigned int ysize); + virtual unsigned int verify_window_sizes(unsigned int numsizes,unsigned int *dimen); protected: + void CreateScreenBuffersAndDevice(LPDIRECTDRAW7 pDD,LPDIRECT3D7 pD3DI); ButtonHandle lookup_key(WPARAM wparam) const; virtual void config( void ); void setup_colormap(void); @@ -90,6 +94,7 @@ protected: void enable_mouse_motion(bool val); void enable_mouse_passive_motion(bool val); void enable_mouse_entry(bool val); + DDDEVICEIDENTIFIER2 _DXDeviceID; public: HWND _mwindow; @@ -131,4 +136,8 @@ private: static TypeHandle _type_handle; }; +extern void set_global_parameters(void); +extern void restore_global_parameters(void); + + #endif