diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 62db722673..3221e37a96 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -1556,3 +1556,10 @@ read_priorities(void) { } } } + +void GraphicsStateGuardian::start_rendering(void) { +} + +void GraphicsStateGuardian::finish_rendering(void) { +} + diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index c809524648..8bee8d14e4 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -104,6 +104,9 @@ public: virtual void begin_frame(); virtual void end_frame(); + virtual void start_rendering(void); + virtual void finish_rendering(void); + // These functions will be queried by the GeomIssuer to determine if // it should issue normals, texcoords, and/or colors, based on the // GSG's current state. diff --git a/panda/src/display/graphicsWindow.cxx b/panda/src/display/graphicsWindow.cxx index 01255789f3..39234db110 100644 --- a/panda/src/display/graphicsWindow.cxx +++ b/panda/src/display/graphicsWindow.cxx @@ -477,8 +477,13 @@ register_idle_function(GraphicsWindow::vfn f) { // whatever setup is required. //////////////////////////////////////////////////////////////////// void GraphicsWindow:: -begin_frame() { +begin_frame(bool bStartRendering) { _gsg->begin_frame(); + + // app may not want to automatically call start_rendering() if + // it wants to switch the rendertarget buffer first + if(bStartRendering) + _gsg->start_rendering(); } //////////////////////////////////////////////////////////////////// @@ -510,7 +515,11 @@ clear() { // do whatever finalization is required. //////////////////////////////////////////////////////////////////// void GraphicsWindow:: -end_frame() { +end_frame(void) { + // finish_rendering not called here since gsg's own end_frame + // will usually want to finish_rendering() itself, + // then swap double buffers, then call GraphicsStateGuardian::end_frame + _gsg->end_frame(); _frame_number++; } diff --git a/panda/src/display/graphicsWindow.h b/panda/src/display/graphicsWindow.h index 34a8d50d84..aab6adfd3b 100644 --- a/panda/src/display/graphicsWindow.h +++ b/panda/src/display/graphicsWindow.h @@ -197,7 +197,7 @@ PUBLISHED: virtual void register_idle_function(GraphicsWindow::vfn); public: - virtual void begin_frame(); + virtual void begin_frame(bool bStartRendering = true); void clear(); virtual void end_frame(); diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.cxx b/panda/src/dxgsg/dxGraphicsStateGuardian.cxx index 5bf24578c0..1df2e7407f 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.cxx +++ b/panda/src/dxgsg/dxGraphicsStateGuardian.cxx @@ -4357,17 +4357,9 @@ bind_light(Spotlight *light, int light_id) { HRESULT res = scrn.pD3DDevice->SetLight(light_id, &alight); } -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::begin_frame -// Access: Public, Virtual -// Description: Called before each frame is rendered, to allow the -// GSG a chance to do any internal cleanup before -// beginning the frame. -//////////////////////////////////////////////////////////////////// +// Note: default gsg begin_frame() now calls start_rendering() void DXGraphicsStateGuardian:: -begin_frame() { - GraphicsStateGuardian::begin_frame(); - +start_rendering(void) { HRESULT hr = scrn.pD3DDevice->BeginScene(); if(FAILED(hr)) { @@ -4384,6 +4376,24 @@ begin_frame() { } } +void DXGraphicsStateGuardian:: +finish_rendering(void) { + HRESULT hr = scrn.pD3DDevice->EndScene(); + + if(FAILED(hr)) { + if((hr==DDERR_SURFACELOST)||(hr==DDERR_SURFACEBUSY)) { + if(dxgsg_cat.is_debug()) + dxgsg_cat.debug() << "EndScene returns " << ConvD3DErrorToString(hr) << endl; + + CheckCooperativeLevel(); + } else { + dxgsg_cat.error() << "EndScene failed, unhandled error hr == " << ConvD3DErrorToString(hr) << endl; + exit(1); + } + return; + } +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::end_frame // Access: Public, Virtual @@ -4393,8 +4403,6 @@ begin_frame() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: end_frame() { - GraphicsStateGuardian::end_frame(); - HRESULT hr; // draw new tri-based FPS meter @@ -4549,22 +4557,9 @@ end_frame() { scrn.pD3DDevice->SetTexture(0, ((_pCurTexContext != NULL) ? _pCurTexContext->_surface : NULL)); } - hr = scrn.pD3DDevice->EndScene(); + DXGraphicsStateGuardian::finish_rendering(); - // any GDI operations MUST occur after EndScene - - if(FAILED(hr)) { - if((hr==DDERR_SURFACELOST)||(hr==DDERR_SURFACEBUSY)) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "EndScene returns " << ConvD3DErrorToString(hr) << endl; - - CheckCooperativeLevel(); - } else { - dxgsg_cat.error() << "EndScene failed, unhandled error hr == " << ConvD3DErrorToString(hr) << endl; - exit(1); - } - return; - } + // any GDI operations (which are mega-slow per-frame) MUST occur after EndScene if(_bShowFPSMeter) { DO_PSTATS_STUFF(PStatTimer timer(_win->_show_fps_pcollector)); @@ -4646,6 +4641,11 @@ end_frame() { } } #endif + + // Note: regular GraphicsWindow::end_frame is being called, + // but we override gsg::end_frame, so need to explicitly call it here + // (currently it's an empty fn) + GraphicsStateGuardian::end_frame(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.h b/panda/src/dxgsg/dxGraphicsStateGuardian.h index 8de16a18fc..4c8b03eb76 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.h +++ b/panda/src/dxgsg/dxGraphicsStateGuardian.h @@ -126,9 +126,12 @@ public: virtual void bind_light(DirectionalLight *light, int light_id); virtual void bind_light(Spotlight *light, int light_id); - virtual void begin_frame(); + // default gsg begin_frame() used virtual void end_frame(); + virtual void start_rendering(); + virtual void finish_rendering(); + virtual bool wants_normals(void) const; virtual bool wants_texcoords(void) const; diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index ec274a2b05..af40579f38 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -3990,17 +3990,10 @@ bind_light(Spotlight *light, int light_id) { HRESULT res = scrn.pD3DDevice->SetLight(light_id, &alight); } -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::begin_frame -// Access: Public, Virtual -// Description: Called before each frame is rendered, to allow the -// GSG a chance to do any internal cleanup before -// beginning the frame. -//////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian:: -begin_frame() { - GraphicsStateGuardian::begin_frame(); +// Note: default gsg begin_frame() now calls start_rendering() +void DXGraphicsStateGuardian:: +start_rendering(void) { HRESULT hr = scrn.pD3DDevice->BeginScene(); if(FAILED(hr)) { @@ -4016,6 +4009,23 @@ begin_frame() { } } +void DXGraphicsStateGuardian:: +finish_rendering(void) { + HRESULT hr = scrn.pD3DDevice->EndScene(); + + if(FAILED(hr)) { + if(hr==D3DERR_DEVICELOST) { + if(dxgsg_cat.is_debug()) + dxgsg_cat.debug() << "EndScene returns DeviceLost\n"; + CheckCooperativeLevel(); + } else { + dxgsg_cat.error() << "EndScene failed, unhandled error hr == " << D3DERRORSTRING(hr); + exit(1); + } + return; + } +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::end_frame // Access: Public, Virtual @@ -4027,6 +4037,7 @@ void DXGraphicsStateGuardian:: end_frame() { HRESULT hr; + // draw fps meter stuff before calling EndScene if(_bShowFPSMeter) { DO_PSTATS_STUFF(PStatTimer timer(_win->_show_fps_pcollector)); @@ -4049,23 +4060,11 @@ end_frame() { _bShowFPSMeter=false; } - hr = scrn.pD3DDevice->EndScene(); + DXGraphicsStateGuardian::finish_rendering(); // any GDI operations MUST occur after EndScene - if(FAILED(hr)) { - if(hr==D3DERR_DEVICELOST) { - if(dxgsg_cat.is_debug()) - dxgsg_cat.debug() << "EndScene returns DeviceLost\n"; - CheckCooperativeLevel(); - } else { - dxgsg_cat.error() << "EndScene failed, unhandled error hr == " << D3DERRORSTRING(hr); - exit(1); - } - return; - } - - if(_bShowFPSMeter) { + if(_bShowFPSMeter) { // update frame stats DO_PSTATS_STUFF(PStatTimer timer(_win->_show_fps_pcollector)); @@ -4086,19 +4085,20 @@ end_frame() { } _cur_frame_count++; // only used by fps meter right now - } + } - show_frame(); + show_frame(); #ifdef COUNT_DRAWPRIMS { #define FRAMES_PER_DPINFO 90 static DWORD LastDPInfoFrame=0; static DWORD LastTickCount=0; + const float one_thousandth = 1.0f/1000.0f; if (_cur_frame_count-LastDPInfoFrame > FRAMES_PER_DPINFO) { DWORD CurTickCount=GetTickCount(); - float delta_secs=(CurTickCount-LastTickCount)/1000.0f; + float delta_secs=(CurTickCount-LastTickCount)*one_thousandth; float numframes=_cur_frame_count-LastDPInfoFrame; float verts_per_frame = cVertcount/numframes; @@ -4148,6 +4148,9 @@ end_frame() { } #endif + // Note: regular GraphicsWindow::end_frame is being called, + // but we override gsg::end_frame, so need to explicitly call it here + // (currently it's an empty fn) GraphicsStateGuardian::end_frame(); } diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 6c5f612b5f..a164ef7731 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -134,9 +134,12 @@ public: virtual void bind_light(DirectionalLight *light, int light_id); virtual void bind_light(Spotlight *light, int light_id); - virtual void begin_frame(); + // default gsg begin_frame() used virtual void end_frame(); + virtual void start_rendering(); + virtual void finish_rendering(); + virtual bool wants_normals(void) const; virtual bool wants_texcoords(void) const; diff --git a/panda/src/wdxdisplay/wdxGraphicsWindow.cxx b/panda/src/wdxdisplay/wdxGraphicsWindow.cxx index bc5d409ce9..c335677ec0 100644 --- a/panda/src/wdxdisplay/wdxGraphicsWindow.cxx +++ b/panda/src/wdxdisplay/wdxGraphicsWindow.cxx @@ -325,7 +325,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { PAINTSTRUCT ps; BeginPaint(hwnd, &ps); if(DXREADY) - show_frame(); + _dxgsg->show_frame(); EndPaint(hwnd, &ps); return 0; } @@ -2515,28 +2515,6 @@ void wdxGraphicsWindow::setup_colormap(void) { RealizePalette(_hdc); } - -//////////////////////////////////////////////////////////////////// -// Function: begin_frame -// Access: -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow::begin_frame(void) { - GraphicsWindow::begin_frame(); -} - -void wdxGraphicsWindow::show_frame(void) { - _dxgsg->show_frame(); -} - -//////////////////////////////////////////////////////////////////// -// Function: end_frame -// Access: -// Description: timer info, incs frame # -//////////////////////////////////////////////////////////////////// -void wdxGraphicsWindow::end_frame(void) { - GraphicsWindow::end_frame(); -} - //////////////////////////////////////////////////////////////////// // Function: handle_window_move // Access: diff --git a/panda/src/wdxdisplay/wdxGraphicsWindow.h b/panda/src/wdxdisplay/wdxGraphicsWindow.h index 9eb1fa8e80..fb268c5163 100644 --- a/panda/src/wdxdisplay/wdxGraphicsWindow.h +++ b/panda/src/wdxdisplay/wdxGraphicsWindow.h @@ -60,7 +60,6 @@ public: wdxGraphicsWindow(GraphicsPipe* pipe,const GraphicsWindow::Properties& props,wdxGraphicsWindowGroup *pParentGroup); virtual ~wdxGraphicsWindow(void); - virtual void end_frame( void ); virtual TypeHandle get_gsg_type() const; static GraphicsWindow* make_wdxGraphicsWindow(const FactoryParams ¶ms); @@ -76,8 +75,6 @@ public: INLINE void handle_keyrelease(ButtonHandle key); void handle_window_move(int x, int y); void dx_setup(); - virtual void begin_frame( void ); - void show_frame(); virtual bool resize(unsigned int xsize,unsigned int ysize); virtual unsigned int verify_window_sizes(unsigned int numsizes,unsigned int *dimen); bool special_check_fullscreen_resolution(UINT xsize,UINT ysize);