diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index e876930628..c4944a00ec 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -272,12 +272,12 @@ set_color_clear_value(const Colorf& value) { _d3dcolor_clear_value = Colorf_to_D3DCOLOR(value); } -void DXGraphicsStateGuardian::SetFPSMeterPosition(RECT &view_rect) { +void DXGraphicsStateGuardian::SetFPSMeterPosition(void) { if(_fpsmeter_verts==NULL) return; - DWORD renderWid = RECT_XSIZE(view_rect); - DWORD renderHt = RECT_YSIZE(view_rect); + DWORD renderWid = scrn.pProps->_xsize; + DWORD renderHt = scrn.pProps->_ysize; // adjust these to match fontsize (these are hacks for default font, probably should get char width from win32) #define FPSMETER_NUMFONTLETTERS 11 // need 11 letters [0-9.] @@ -415,6 +415,34 @@ void DXGraphicsStateGuardian::FillFPSMeterTexture(void) { */ } +void DXGraphicsStateGuardian:: +reset_panda_gsg(void) { + GraphicsStateGuardian::reset(); + + // overwrite gsg defaults with these values + + // All implementations have the following buffers. + _buffer_mask = (RenderBuffer::T_color | + RenderBuffer::T_back +// RenderBuffer::T_depth | +// RenderBuffer::T_stencil | +// RenderBuffer::T_accum + ); + + // stmt below is incorrect for general mono displays, need both right and left flags set. + // stereo not supported in dx8 + // _buffer_mask &= ~RenderBuffer::T_right; + + if(_render_traverser.is_null()) { + // 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()); + } + } +} + //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::Constructor // Access: Public @@ -422,27 +450,26 @@ void DXGraphicsStateGuardian::FillFPSMeterTexture(void) { //////////////////////////////////////////////////////////////////// DXGraphicsStateGuardian:: DXGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) { - // allocate local buffers used during rendering + reset_panda_gsg(); - GraphicsStateGuardian::reset(); + // allocate local buffers used during rendering ZeroMemory(&scrn,sizeof(DXScreenData)); _bShowFPSMeter = false; - _pCurFvfBufPtr = NULL; - _pFvfBufBasePtr = new BYTE[VERT_BUFFER_SIZE]; // allocate storage for vertex info. - _index_buf = new WORD[PANDA_MAXNUMVERTS]; // allocate storage for vertex index info. - _fpsmeter_verts=NULL; - _fpsmeter_font_surf=NULL; _bDXisReady = false; - _CurFVFType = 0x0; + + _pFvfBufBasePtr = NULL; + _index_buf=NULL; + _fpsmeter_verts=NULL; + _light_enabled = NULL; + _cur_light_enabled = NULL; + _clip_plane_enabled = (bool *)NULL; + _cur_clip_plane_enabled = (bool *)NULL; + + _fpsmeter_font_surf=NULL; + _max_light_range = __D3DLIGHT_RANGE_MAX; - _color_writemask = 0xFFFFFFFF; - -// scrn.pD3DDevicesPrimary = scrn.pD3DDevicesZBuf = scrn.pD3DDevicesBack = NULL; -// _pDD = NULL; -// scrn.pD3DDevice = NULL; - // 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 @@ -452,27 +479,7 @@ DXGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) { 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()); - } - - // All implementations have the following buffers. - _buffer_mask = (RenderBuffer::T_color | - RenderBuffer::T_depth | - RenderBuffer::T_back -// RenderBuffer::T_stencil | -// RenderBuffer::T_accum - ); - - // 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); } @@ -488,8 +495,6 @@ DXGraphicsStateGuardian:: _pCurTexContext = NULL; free_pointers(); - delete [] _pFvfBufBasePtr; - delete [] _index_buf; } //////////////////////////////////////////////////////////////////// @@ -500,9 +505,11 @@ DXGraphicsStateGuardian:: //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: reset(void) { - GraphicsStateGuardian::reset(); - dxgsg_cat.error() << "DXGSG reset() not implemented properly yet!\n"; + reset_panda_gsg(); + dxgsg_cat.error() << "DXGSG reset() not implemented properly yet!\n"; + // what else do we need to do? // delete all the objs too, right? + // need to do a //dx_init(); } @@ -537,23 +544,32 @@ void DXGraphicsStateGuardian:: dx_init(HCURSOR hMouseCursor) { HRESULT hr; + // make sure gsg passes all current state down to us + GraphicsStateGuardian::clear_cached_state(); + // want gsg to pass all state settings down so any non-matching defaults we set here get overwritten + assert(scrn.pD3D8!=NULL); assert(scrn.pD3DDevice!=NULL); ZeroMemory(&_lmodel_ambient,sizeof(Colorf)); scrn.pD3DDevice->SetRenderState(D3DRS_AMBIENT, 0x0); - _light_enabled = (bool *)NULL; - _cur_light_enabled = (bool *)NULL; + if(_pFvfBufBasePtr==NULL) + _pFvfBufBasePtr = new BYTE[VERT_BUFFER_SIZE]; // allocate storage for vertex info. + if(_index_buf==NULL) + _index_buf = new WORD[PANDA_MAXNUMVERTS]; // allocate storage for vertex index info. + + _pCurFvfBufPtr = NULL; - // bugbug: rewrite clipplane stuff - _clip_plane_enabled = (bool *)NULL; - _cur_clip_plane_enabled = (bool *)NULL; scrn.pD3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE , 0x0); scrn.pD3DDevice->SetRenderState(D3DRS_CLIPPING, true); _clipping_enabled = true; + // these both reflect d3d defaults + _color_writemask = 0xFFFFFFFF; + _CurFVFType = 0x0; // guards SetVertexShader fmt + _bGouraudShadingOn = false; scrn.pD3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); @@ -730,8 +746,6 @@ dx_init(HCURSOR hMouseCursor) { } } - SetRect(&scrn.clip_rect, 0,0,0,0); // no clip rect set - // Lighting, let's turn it off by default _lighting_enabled = false; scrn.pD3DDevice->SetRenderState(D3DRS_LIGHTING, _lighting_enabled); @@ -763,9 +777,14 @@ dx_init(HCURSOR hMouseCursor) { _max_lights = min(DXGSG_MAX_LIGHTS,scrn.d3dcaps.MaxActiveLights); } - _available_light_ids = PTA(Light*)::empty_array(_max_lights); - _light_enabled = new bool[_max_lights]; - _cur_light_enabled = new bool[_max_lights]; + if(_available_light_ids.is_null()) + _available_light_ids = PTA(Light*)::empty_array(_max_lights); + + if(_light_enabled==NULL) + _light_enabled = new bool[_max_lights]; + + if(_cur_light_enabled == NULL) + _cur_light_enabled = new bool[_max_lights]; for (int i = 0; i < _max_lights; i++) { _available_light_ids[i] = NULL; @@ -780,22 +799,25 @@ dx_init(HCURSOR hMouseCursor) { _max_clip_planes = D3DMAXUSERCLIPPLANES; else _max_clip_planes = scrn.d3dcaps.MaxUserClipPlanes; - _available_clip_plane_ids = PTA(PlaneNode*)::empty_array(_max_clip_planes); - _clip_plane_enabled = new bool[_max_clip_planes]; - _cur_clip_plane_enabled = new bool[_max_clip_planes]; + if(_available_clip_plane_ids.is_null()) + _available_clip_plane_ids = PTA(PlaneNode*)::empty_array(_max_clip_planes); + + if(_clip_plane_enabled == NULL) + _clip_plane_enabled = new bool[_max_clip_planes]; + + if(_cur_clip_plane_enabled == NULL) + _cur_clip_plane_enabled = new bool[_max_clip_planes]; + for (int i = 0; i < _max_clip_planes; i++) { _available_clip_plane_ids[i] = NULL; _clip_plane_enabled[i] = false; } - // initial clip rect - SetRect(&scrn.clip_rect, 0,0,0,0); // no clip rect set - // 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); + SetTextureBlendMode(_CurTexBlendMode,false); _texturing_enabled = false; scrn.pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE); // disables texturing @@ -957,7 +979,7 @@ dx_init(HCURSOR hMouseCursor) { _fps_u_usedwidth = letterfontareaWidth/(float)texdim_x; _fps_v_usedheight = fontareaHeight/(float)texdim_y; - SetFPSMeterPosition(scrn.view_rect); + SetFPSMeterPosition(); } #else _bShowFPSMeter = false; @@ -1550,7 +1572,7 @@ render_frame() { void DXGraphicsStateGuardian:: report_texmgr_stats() { #if 0 -// not implemented for dx8 +// not implemented for dx8 yet #if defined(DO_PSTATS)||defined(PRINT_TEXSTATS) @@ -2129,10 +2151,10 @@ draw_point(GeomPoint *geom, GeomContext *gc) { } #ifdef _DEBUG - static BOOL bPrintedMsg=FALSE; + static bool bPrintedMsg=false; if (!bPrintedMsg && (geom->get_size()!=1.0f)) { - bPrintedMsg=TRUE; + bPrintedMsg=true; dxgsg_cat.warning() << "D3D does not support drawing points of non-unit size, setting point size to 1.0f!\n"; } #endif @@ -2196,12 +2218,12 @@ draw_line(GeomLine* geom, GeomContext *gc) { DO_PSTATS_STUFF(_vertices_other_pcollector.add_level(geom->get_num_vertices())); #ifdef _DEBUG - static BOOL bPrintedMsg=FALSE; + static bool bPrintedMsg=false; // note: need to implement approximation of non-1.0 width lines with quads if (!bPrintedMsg && (geom->get_width()!=1.0f)) { - bPrintedMsg=TRUE; + bPrintedMsg=true; if(dxgsg_cat.is_debug()) dxgsg_cat.debug() << "DX does not support drawing lines with a non-1.0f pixel width, setting width to 1.0f!\n"; } @@ -2286,10 +2308,10 @@ void DXGraphicsStateGuardian:: draw_linestrip(GeomLinestrip* geom, GeomContext *gc) { #ifdef _DEBUG - static BOOL bPrintedMsg=FALSE; + static BOOL bPrintedMsg=false; if (!bPrintedMsg && (geom->get_width()!=1.0f)) { - bPrintedMsg=TRUE; + bPrintedMsg=true; dxgsg_cat.warning() << "DX does not support drawing lines with a non-1.0f pixel width, setting width to 1.0f!\n"; } #endif @@ -4882,10 +4904,10 @@ enable_texturing(bool val) { // assert(_pCurTexContext!=NULL); we're definitely called with it NULL for both true and false // I'm going to allow enabling texturing even if no tex has been set yet, seems to cause no probs - if (val == FALSE) { + if (val == false) { scrn.pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE); } else { - SetTextureBlendMode(_CurTexBlendMode,TRUE); + SetTextureBlendMode(_CurTexBlendMode,true); } } @@ -5551,27 +5573,13 @@ 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(_fpsmeter_verts!=NULL) { - delete [] _fpsmeter_verts; - _fpsmeter_verts = NULL; - } + SAFE_DELETE_ARRAY(_index_buf); + SAFE_DELETE_ARRAY(_pFvfBufBasePtr); + SAFE_DELETE_ARRAY(_fpsmeter_verts); + SAFE_DELETE_ARRAY(_cur_clip_plane_enabled); + SAFE_DELETE_ARRAY(_clip_plane_enabled); + SAFE_DELETE_ARRAY(_cur_light_enabled); + SAFE_DELETE_ARRAY(_light_enabled); } //////////////////////////////////////////////////////////////////// @@ -5747,135 +5755,6 @@ dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled) { #endif } -//////////////////////////////////////////////////////////////////// -// Function: dx_resize_window -// Description: Recreate the device and render buffers at the new size -//////////////////////////////////////////////////////////////////// -bool DXGraphicsStateGuardian:: -dx_resize_window(HWND mwindow, RECT viewrect) { - if (scrn.pD3DDevice == NULL) // nothing created yet - return true; - - // first need to release any non-D3DPOOL_MANAGED objects. then call Reset. - // then recreate any non-D3DPOOL_MANAGED objects. (textures/VBs/etc) - - // for safety, need some better error-cleanup here -/* - DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd_back); - DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd_zbuf); - - scrn.pD3DDevicesBack->GetSurfaceDesc(&ddsd_back); - scrn.pD3DDevicesZBuf->GetSurfaceDesc(&ddsd_zbuf); - - ULONG refcnt; - - if((scrn.pD3DDevicesBack!=NULL)&&(scrn.pD3DDevicesZBuf!=NULL)) - scrn.pD3DDevicesBack->DeleteAttachedSurface(0x0,scrn.pD3DDevicesZBuf); - - RELEASE(scrn.pD3DDevicesZBuf,dxgsg,"zbuffer",false); - RELEASE(scrn.pD3DDevicesBack,dxgsg,"backbuffer",false); - RELEASE(scrn.pD3DDevicesPrimary,dxgsg,"primary surface",false); - - assert((scrn.pD3DDevicesPrimary == NULL) && (scrn.pD3DDevicesBack == NULL) && (scrn.pD3DDevicesZBuf == NULL)); - scrn.view_rect = viewrect; - - DWORD renderWid = scrn.view_rect.right - scrn.view_rect.left; - DWORD renderHt = scrn.view_rect.bottom - scrn.view_rect.top; - - ddsd_back.dwWidth = ddsd_zbuf.dwWidth = renderWid; - ddsd_back.dwHeight = ddsd_zbuf.dwHeight = renderHt; - - DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd); - - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - ddsd.dwFlags = DDSD_CAPS; - - PRINTVIDMEM(scrn.pD3DDevice,&ddsd.ddsCaps,"resize primary surf"); - HRESULT hr; - - if (FAILED(hr = scrn.pD3DDevice->CreateSurface( &ddsd, &scrn.pD3DDevicesPrimary, NULL ))) { - dxgsg_cat.fatal() << "resize() - CreateSurface failed for primary : result = " << D3DERRORSTRING(hr); - exit(1); - } - - if(!dx_full_screen) { - // 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 = scrn.pD3DDevice->CreateClipper( 0, &Clipper, NULL ))) { - dxgsg_cat.fatal() - << "CreateClipper after resize failed : result = " << D3DERRORSTRING(hr); - 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 ); - scrn.pD3DDevicesPrimary->SetClipper( Clipper ); - Clipper->Release(); - } - - // 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(scrn.pD3DDevice,&ddsd_back.ddsCaps,"resize backbuffer surf"); - - if (FAILED(hr = scrn.pD3DDevice->CreateSurface( &ddsd_back, &scrn.pD3DDevicesBack, NULL ))) { - dxgsg_cat.fatal() << "resize() - CreateSurface failed for backbuffer : result = " << D3DERRORSTRING(hr); - exit(1); - } - - PRINTVIDMEM(scrn.pD3DDevice,&ddsd_back.ddsCaps,"resize zbuffer surf"); - - // Recreate and attach a z-buffer. - if (FAILED(hr = scrn.pD3DDevice->CreateSurface( &ddsd_zbuf, &scrn.pD3DDevicesZBuf, NULL ))) { - dxgsg_cat.fatal() << "resize() - CreateSurface failed for Z buffer: result = " << D3DERRORSTRING(hr); - exit(1); - } - - // Attach the z-buffer to the back buffer. - if ((hr = scrn.pD3DDevicesBack->AddAttachedSurface( scrn.pD3DDevicesZBuf ) ) != DD_OK) { - dxgsg_cat.fatal() << "resize() - AddAttachedSurface failed : result = " << D3DERRORSTRING(hr); - exit(1); - } - - if ((hr = scrn.pD3DDevice->SetRenderTarget(scrn.pD3DDevicesBack,0x0) ) != DD_OK) { - dxgsg_cat.fatal() << "resize() - SetRenderTarget failed : result = " << D3DERRORSTRING(hr); - exit(1); - } -*/ - - scrn.PresParams.BackBufferWidth = RECT_XSIZE(viewrect); - scrn.PresParams.BackBufferHeight = RECT_YSIZE(viewrect); - HRESULT hr=scrn.pD3DDevice->Reset(&scrn.PresParams); - - if(FAILED(hr)) { - if(hr==D3DERR_OUTOFVIDEOMEMORY) - return false; - dxgsg_cat.error() << "dx_resize_window Reset() failed, hr = " << D3DERRORSTRING(hr); - exit(1); - } - - // Create the viewport - D3DVIEWPORT8 vp = {0, 0, - scrn.PresParams.BackBufferWidth,scrn.PresParams.BackBufferHeight, - 0.0f, 1.0f}; - - hr = scrn.pD3DDevice->SetViewport( &vp ); - if(FAILED(hr)) { - dxgsg_cat.fatal() << "SetViewport failed! hr = " << D3DERRORSTRING(hr); - exit(1); - } - - if(_bShowFPSMeter) - SetFPSMeterPosition(scrn.view_rect); - - return true; -} - bool refill_tex_callback(TextureContext *tc,void *void_dxgsg_ptr) { DXTextureContext *dtc = DCAST(DXTextureContext, tc); // DXGraphicsStateGuardian *dxgsg = (DXGraphicsStateGuardian *)void_dxgsg_ptr; not needed? @@ -6089,7 +5968,7 @@ bool DXGraphicsStateGuardian::CheckCooperativeLevel(bool bDoReactivateWindow) { switch(hr) { case D3DERR_DEVICENOTRESET: - _bDXisReady = FALSE; + _bDXisReady = false; ReleaseAllDeviceObjects(); hr=scrn.pD3DDevice->Reset(&scrn.PresParams); if(bDoReactivateWindow) @@ -6103,7 +5982,7 @@ bool DXGraphicsStateGuardian::CheckCooperativeLevel(bool bDoReactivateWindow) { if(SUCCEEDED(_last_testcooplevel_result)) { if(_bDXisReady) { _win->deactivate_window(); - _bDXisReady = FALSE; + _bDXisReady = false; if(dxgsg_cat.is_debug()) dxgsg_cat.debug() << "D3D Device was Lost, waiting...\n"; } @@ -6177,8 +6056,9 @@ bool DXGraphicsStateGuardian::CheckCooperativeLevel(bool bDoReactivateWindow) { return SUCCEEDED(hr); } +/* //////////////////////////////////////////////////////////////////// -// Function: handle_window_move +// Function: adjust_view_rect // Access: // Description: we receive the new x and y position of the client //////////////////////////////////////////////////////////////////// @@ -6193,6 +6073,7 @@ void DXGraphicsStateGuardian::adjust_view_rect(int x, int y) { // set_clipper(clip_rect); } } +*/ #if 0 @@ -6929,7 +6810,7 @@ HRESULT CreateDX8Cursor(LPDIRECT3DDEVICE8 pd3dDevice, HCURSOR hCursor,BOOL bAddW COLORREF* pcrArrayMask = NULL; DWORD* pBitmap; HGDIOBJ hgdiobjOld; - BOOL bBWCursor; + bool bBWCursor; ZeroMemory( &iconinfo, sizeof(iconinfo) ); if( !GetIconInfo( hCursor, &iconinfo ) ) @@ -6941,10 +6822,10 @@ HRESULT CreateDX8Cursor(LPDIRECT3DDEVICE8 pd3dDevice, HCURSOR hCursor,BOOL bAddW dwHeightSrc = bm.bmHeight; if( iconinfo.hbmColor == NULL ) { - bBWCursor = TRUE; + bBWCursor = true; dwHeightDest = dwHeightSrc / 2; } else { - bBWCursor = FALSE; + bBWCursor = false; dwHeightDest = dwHeightSrc; } diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 8c4b5b0426..b16ae29dca 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -376,7 +376,7 @@ protected: void *_fpsmeter_font_surf; float _fps_u_usedwidth,_fps_v_usedheight; // fraction of fps font texture actually used DWORD _fps_vertexsize; // size of verts used to render fps meter - void SetFPSMeterPosition(RECT &view_rect); + void SetFPSMeterPosition(void); void FillFPSMeterTexture(void); public: @@ -387,17 +387,16 @@ public: static void init_type(void); virtual TypeHandle get_type(void) const; virtual TypeHandle force_init_type() {init_type(); return get_class_type();} - void adjust_view_rect(int x, int y); INLINE void SetDXReady(bool status) { _bDXisReady = status; } INLINE bool GetDXReady(void) { return _bDXisReady;} void DXGraphicsStateGuardian::SetTextureBlendMode(TextureApplyProperty::Mode TexBlendMode,bool bJustEnable); void dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled); + void reset_panda_gsg(void); #define DO_REACTIVATE_WINDOW true bool CheckCooperativeLevel(bool bDoReactivateWindow = false); - bool dx_resize_window(HWND hWnd, RECT viewrect) ; void show_frame(); void dx_init(HCURSOR hMouseCursor); diff --git a/panda/src/dxgsg8/dxgsg8base.h b/panda/src/dxgsg8/dxgsg8base.h index 7e5588a3e7..fdab40ebaa 100644 --- a/panda/src/dxgsg8/dxgsg8base.h +++ b/panda/src/dxgsg8/dxgsg8base.h @@ -20,6 +20,7 @@ #define DXGSG8BASE_H #include +#include // include win32 defns for everything up to XP, and assume I'm smart enough to // use GetProcAddress for backward compat on newer fns @@ -160,7 +161,7 @@ typedef struct { LPDIRECT3D8 pD3D8; HWND hWnd; HMONITOR hMon; - RECT view_rect,clip_rect; + GraphicsWindow::Properties *pProps; // can get window rect here (or from GetWindowRect(hWnd), can also get window size in PresParams DWORD MaxAvailVidMem; ushort CardIDNum; // adapter ID ushort depth_buffer_bitdepth; //GetSurfaceDesc is not reliable so must store this explicitly diff --git a/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx b/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx index 53e814cb65..e470ba0239 100644 --- a/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx +++ b/panda/src/wdxdisplay8/wdxGraphicsWindow8.cxx @@ -640,6 +640,25 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { return DefWindowProc(hwnd, msg, wparam, lparam); } +// should be used by both fullscrn and windowed resize +bool wdxGraphicsWindow::reset_device_resize_window(RECT &viewrect) { + DXScreenData *pScrn=&_dxgsg->scrn; + + pScrn->PresParams.BackBufferWidth = RECT_XSIZE(viewrect); + pScrn->PresParams.BackBufferHeight = RECT_YSIZE(viewrect); + HRESULT hr=pScrn->pD3DDevice->Reset(&pScrn->PresParams); + + if(FAILED(hr)) { + if(hr==D3DERR_OUTOFVIDEOMEMORY) + return false; + wdxdisplay_cat.error() << "reset_device_resize_window Reset() failed, hr = " << D3DERRORSTRING(hr); + exit(1); + } + + init_resized_window(); + return true; +} + //////////////////////////////////////////////////////////////////// // Function: handle_reshape @@ -657,89 +676,8 @@ void wdxGraphicsWindow::handle_windowed_resize(HWND hWnd,bool bDoDxReset) { //assume this is initial creation reshape, so ignore this call return; } - -/* bugbug: dont we need this? dx8 clear() just clears the backbuf. try BitBlt, or an erase-backgnd GDI flag? - HRESULT hr; - - // Clear the back/primary surface to black - DX_DECLARE_CLEAN(DDBLTFX, bltfx) - bltfx.dwDDFX |= DDBLTFX_NOTEARING; - hr = _dxgsg->scrn.pddsPrimary->Blt(NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&bltfx); - if(FAILED( hr )) { - wdxdisplay_cat.fatal() << "Blt to Black of Primary Surf failed! : result = " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - - if(FAILED(hr = _dxgsg->scrn.pDD->TestCooperativeLevel())) { - wdxdisplay_cat.error() << "TestCooperativeLevel failed : result = " << ConvD3DErrorToString(hr) << endl; - return; - } -*/ -// _dxgsg->SetDXReady(false); // disable rendering whilst we mess with surfs - - /* this stuff should all be done be d3ddev Reset() now - - // 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 - - _dxgsg->RestoreAllDeviceObjects(); // right now this doesnt do anything - - - - LPDIRECTDRAWSURFACE7 pddsDummy = NULL, pddsDummyZ = NULL; - ULONG refcnt; - - DX_DECLARE_CLEAN( DDSURFACEDESC2, ddsd ); - - _dxgsg->scrn.pddsBack->GetSurfaceDesc(&ddsd); - LPDIRECTDRAW7 pDD = _dxgsg->scrn.pDD; - - 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); - } - - if(_dxgsg->scrn.pddsZBuf!=NULL) { - DX_DECLARE_CLEAN( DDSURFACEDESC2, ddsdZ ); - _dxgsg->scrn.pddsZBuf->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->scrn.pD3DDevice->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); - */ } - - if(_dxgsg!=NULL) _dxgsg->SetDXReady(false); @@ -758,11 +696,11 @@ void wdxGraphicsWindow::handle_windowed_resize(HWND hWnd,bool bDoDxReset) { DWORD ysize= RECT_YSIZE(view_rect); do { - // change _props xsize,ysize + // change _props xsize,ysize (need to do this here in case _dxgsg==NULL) resized(xsize,ysize); if((_dxgsg!=NULL)&& bDoDxReset) { - bResizeSucceeded=_dxgsg->dx_resize_window(hWnd,view_rect); // create the new resized rendertargets + bResizeSucceeded=reset_device_resize_window(view_rect); // create the new resized rendertargets if(!bResizeSucceeded) { // size was too large. try a smaller size if(wdxdisplay_cat.is_debug()) { @@ -1102,6 +1040,8 @@ void wdxGraphicsWindowGroup::CreateWindows(void) { } _windows[devnum]->_dxgsg->scrn.hWnd = hWin; + _windows[devnum]->_dxgsg->scrn.pProps = &_windows[devnum]->_props; + if(devnum==0) _hParentWindow=hWin; } @@ -1395,7 +1335,7 @@ void wdxGraphicsWindow::resize(unsigned int xsize,unsigned int ysize) { if(FAILED(hr = _dxgsg->scrn.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"; + wdxdisplay_cat.error() << "Full screen app failed to get exclusive mode on resize, exiting...\n"; return; } @@ -1656,38 +1596,11 @@ bool wdxGraphicsWindow::search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevIn wdxdisplay_cat.info() << "Warning: video driver is a pre-DX8-class driver\n"; } - if(bWantStencil & (d3dcaps.StencilCaps==0x0)) { - wdxdisplay_cat.fatal() << "Stencil ability requested, but device #" << pDevInfo->cardID << " (" << _dxgsg->scrn.DXDeviceID.Description<<"), has no stencil capability!\n"; - exit(1); + if((bWantStencil) && (d3dcaps.StencilCaps==0x0)) { + wdxdisplay_cat.fatal() << "Stencil ability requested, but device #" << pDevInfo->cardID << " (" << _dxgsg->scrn.DXDeviceID.Description<<"), has no stencil capability!\n"; + exit(1); } -/* - LPDIRECTDRAW7 pDD; - 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 - - ZeroMemory(d3ddevs,2*sizeof(D3DDEVICEDESC7)); - - hr = _dxgsg->scrn.pD3D->EnumDevices(EnumDevicesCallback,d3ddevs); - if(hr != DD_OK) { - wdxdisplay_cat.fatal() << "EnumDevices failed : result = " << ConvD3DErrorToString(hr) << endl; - goto error_exit; - } - - WORD DeviceIdx; - DeviceIdx=REGHALIDX; - - if(!(d3ddevs[REGHALIDX].dwDevCaps & D3DDEVCAPS_HWRASTERIZATION )) { - // should never get here because enum devices should filter out non-HAL devices - wdxdisplay_cat.error() << "No 3D HW present on device #"<scrn.DXDeviceID.szDescription<<")\n"; - goto error_exit; - } - - memcpy(&_dxgsg->scrn.D3DDevDesc,&d3ddevs[DeviceIdx],sizeof(D3DDEVICEDESC7)); -*/ - _dxgsg->scrn.bIsTNLDevice=((d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)!=0); #ifdef DO_LOWVIDMEM_CHKS @@ -1967,7 +1880,6 @@ CreateScreenBuffersAndDevice(DXScreenData &Display) { LPDIRECT3D8 pD3D8=Display.pD3D8; D3DCAPS8 *pD3DCaps = &Display.d3dcaps; D3DPRESENT_PARAMETERS* pPresParams = &Display.PresParams; - D3DVIEWPORT8 vp; RECT view_rect; HRESULT hr; bool bWantStencil = ((_props._mask & W_STENCIL)!=0); @@ -2165,23 +2077,8 @@ CreateScreenBuffersAndDevice(DXScreenData &Display) { } else { pPresParams->SwapEffect = D3DSWAPEFFECT_DISCARD; } - - // Get the dimensions of the viewport and screen bounds - GetClientRect( Display.hWnd, &view_rect ); - POINT ul,lr; - ul.x=view_rect.left; ul.y=view_rect.top; - lr.x=view_rect.right; lr.y=view_rect.bottom; - ClientToScreen(Display.hWnd, &ul ); - ClientToScreen(Display.hWnd, &lr ); - view_rect.left=ul.x; view_rect.top=ul.y; - view_rect.right=lr.x; view_rect.bottom=lr.y; - dwRenderWidth = RECT_XSIZE(view_rect); - dwRenderHeight = RECT_YSIZE(view_rect); - _props._xorg = view_rect.left; // _props should reflect view rectangle - _props._yorg = view_rect.top; - _props._xsize = dwRenderWidth; - _props._ysize = dwRenderHeight; + assert((dwRenderWidth==pPresParams->BackBufferWidth)&&(dwRenderHeight==pPresParams->BackBufferHeight)); hr = pD3D8->CreateDevice(Display.CardIDNum, D3DDEVTYPE_HAL, _pParentWindowGroup->_hParentWindow, dwBehaviorFlags, pPresParams, &Display.pD3DDevice); @@ -2194,32 +2091,13 @@ CreateScreenBuffersAndDevice(DXScreenData &Display) { // ======================================================== - // clear window to black - HDC hDC=GetDC(Display.hWnd); - PatBlt(hDC,_props._xorg,_props._yorg,_props._xsize,_props._ysize,BLACKNESS); - ReleaseDC(Display.hWnd,hDC); - - hr = Display.pD3DDevice->ResourceManagerDiscardBytes(0); - if(FAILED(hr)) { - wdxdisplay_cat.error() << "ResourceManagerDiscardBytes failed for device #" << Display.CardIDNum << ", hr=" << D3DERRORSTRING(hr); + if(pPresParams->EnableAutoDepthStencil) { + _dxgsg->_buffer_mask |= RenderBuffer::T_depth; + if(IS_STENCIL_FORMAT(pPresParams->AutoDepthStencilFormat)) + _dxgsg->_buffer_mask |= RenderBuffer::T_stencil; } - resized(dwRenderWidth,dwRenderHeight); // update panda channel/display rgn info - - // Create the viewport - vp.X=0; vp.Y=0; - vp.Width=_props._xsize; vp.Height=_props._ysize; - vp.MinZ=0.0f; vp.MaxZ =1.0f; - hr = Display.pD3DDevice->SetViewport( &vp ); - if(FAILED(hr)) { - wdxdisplay_cat.fatal() << "SetViewport failed for device #" << Display.CardIDNum << ", " << D3DERRORSTRING(hr); - exit(1); - } - - Display.view_rect = view_rect; - - _dxgsg->dx_init(_pParentWindowGroup->_hMouseCursor); - // do not SetDXReady() yet since caller may want to do more work before letting rendering proceed + init_resized_window(); return; @@ -2243,6 +2121,58 @@ Fallback_to_16bpp_buffers: } } +// assumes CreateDevice or Device->Reset() has just been called, +// and the new size is specified in pDisplay->PresParams +void wdxGraphicsWindow::init_resized_window(void) { + DXScreenData *pDisplay=&_dxgsg->scrn; + HRESULT hr; + + DWORD newWidth = pDisplay->PresParams.BackBufferWidth; + DWORD newHeight = pDisplay->PresParams.BackBufferHeight; + + if(pDisplay->PresParams.Windowed) { + POINT ul,lr; + RECT view_rect; + + // need to figure out x,y origin offset of window (we already know the client area size) + GetClientRect( pDisplay->hWnd, &view_rect ); + ul.x=view_rect.left; ul.y=view_rect.top; + lr.x=view_rect.right; lr.y=view_rect.bottom; + ClientToScreen(pDisplay->hWnd, &ul ); + ClientToScreen(pDisplay->hWnd, &lr ); + view_rect.left=ul.x; view_rect.top=ul.y; + view_rect.right=lr.x; view_rect.bottom=lr.y; + _props._xorg = view_rect.left; // _props should reflect view rectangle + _props._yorg = view_rect.top; + + // make sure GDI and DX agree on window client area size + assert((RECT_XSIZE(view_rect)==newWidth)&&(RECT_YSIZE(view_rect)==newHeight)); + } + + resized(newWidth,newHeight); // update panda channel/display rgn info, _props.xsize, _props.ysize + + // clear window to black ASAP + HDC hDC=GetDC(pDisplay->hWnd); + PatBlt(hDC,_props._xorg,_props._yorg,_props._xsize,_props._ysize,BLACKNESS); + ReleaseDC(pDisplay->hWnd,hDC); + + hr = pDisplay->pD3DDevice->ResourceManagerDiscardBytes(0); + if(FAILED(hr)) { + wdxdisplay_cat.error() << "ResourceManagerDiscardBytes failed for device #" << pDisplay->CardIDNum << ", hr=" << D3DERRORSTRING(hr); + } + + // Create the viewport + D3DVIEWPORT8 vp = {0,0,_props._xsize,_props._ysize,0.0f,1.0f}; + hr = pDisplay->pD3DDevice->SetViewport( &vp ); + if(FAILED(hr)) { + wdxdisplay_cat.fatal() << "SetViewport failed for device #" << pDisplay->CardIDNum << ", " << D3DERRORSTRING(hr); + exit(1); + } + + _dxgsg->dx_init(_pParentWindowGroup->_hMouseCursor); + // do not SetDXReady() yet since caller may want to do more work before letting rendering proceed +} + //////////////////////////////////////////////////////////////////// // Function: setup_colormap // Access: @@ -2334,7 +2264,6 @@ void wdxGraphicsWindow::end_frame(void) { // Description: we receive the new x and y position of the client //////////////////////////////////////////////////////////////////// void wdxGraphicsWindow::handle_window_move(int x, int y) { - _dxgsg->adjust_view_rect(x,y); _props._xorg = x; _props._yorg = y; } diff --git a/panda/src/wdxdisplay8/wdxGraphicsWindow8.h b/panda/src/wdxdisplay8/wdxGraphicsWindow8.h index dc789897af..3c390f5cad 100644 --- a/panda/src/wdxdisplay8/wdxGraphicsWindow8.h +++ b/panda/src/wdxdisplay8/wdxGraphicsWindow8.h @@ -92,6 +92,8 @@ protected: void finish_window_setup(void); bool search_for_device(LPDIRECT3D8 pD3D8,DXDeviceInfo *pDevinfo); bool FindBestDepthFormat(DXScreenData &Display,D3DDISPLAYMODE &TestDisplayMode,D3DFORMAT *pBestFmt,bool bWantStencil) const; + void init_resized_window(void); + bool reset_device_resize_window(RECT &viewrect); void setup_colormap(void); INLINE void track_mouse_leaving(HWND hwnd);