From b98c5f0bf5839f4b9d2a8f0da5ff1eb68f1649a8 Mon Sep 17 00:00:00 2001 From: Josh Yelon Date: Thu, 21 Feb 2008 19:55:40 +0000 Subject: [PATCH] Refactored code for glClear - added aux bitplane clears --- panda/src/display/drawableRegion.I | 129 +++++++++----- panda/src/display/drawableRegion.h | 45 +++-- panda/src/display/frameBufferProperties.I | 3 + panda/src/display/frameBufferProperties.cxx | 35 ++-- panda/src/display/frameBufferProperties.h | 1 + panda/src/display/graphicsOutput.h | 22 --- panda/src/display/graphicsStateGuardian.I | 20 --- panda/src/display/graphicsStateGuardian.cxx | 76 ++------- panda/src/display/graphicsStateGuardian.h | 15 +- panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx | 48 +++--- panda/src/dxgsg8/dxGraphicsStateGuardian8.h | 6 +- panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 50 +++--- panda/src/dxgsg9/dxGraphicsStateGuardian9.h | 6 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 160 ++++++++++++------ .../src/glstuff/glGraphicsStateGuardian_src.h | 15 +- panda/src/movies/webcamVideo.I | 10 -- panda/src/movies/webcamVideo.h | 3 - panda/src/movies/webcamVideoDS.cxx | 4 +- 18 files changed, 319 insertions(+), 329 deletions(-) diff --git a/panda/src/display/drawableRegion.I b/panda/src/display/drawableRegion.I index 040c2d2778..f4c3d92436 100644 --- a/panda/src/display/drawableRegion.I +++ b/panda/src/display/drawableRegion.I @@ -25,12 +25,13 @@ INLINE DrawableRegion:: DrawableRegion() : _screenshot_buffer_type(RenderBuffer::T_front), - _draw_buffer_type(RenderBuffer::T_back), - _flags(0), - _clear_color(0.0f, 0.0f, 0.0f, 0.0f), - _clear_depth(1.0f), - _clear_stencil(0) + _draw_buffer_type(RenderBuffer::T_back) { + for (int i=0; i= 0)&&(id < RTP_COUNT)); + _clear_active[id] = clear_active; +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawableRegion::get_clear_active +// Access: Published +// Description: Gets the clear-active flag for any bitplane. +//////////////////////////////////////////////////////////////////// +INLINE bool DrawableRegion:: +get_clear_active(int id) const { + nassertr((id >= 0)&&(id < RTP_COUNT), false); + return _clear_active[id]; } //////////////////////////////////////////////////////////////////// @@ -179,7 +190,7 @@ get_clear_stencil_active() const { //////////////////////////////////////////////////////////////////// INLINE void DrawableRegion:: set_clear_color(const Colorf &color) { - _clear_color = color; + _clear_value[RTP_color] = color; } //////////////////////////////////////////////////////////////////// @@ -193,7 +204,7 @@ set_clear_color(const Colorf &color) { //////////////////////////////////////////////////////////////////// INLINE const Colorf &DrawableRegion:: get_clear_color() const { - return _clear_color; + return _clear_value[RTP_color]; } //////////////////////////////////////////////////////////////////// @@ -207,7 +218,7 @@ get_clear_color() const { //////////////////////////////////////////////////////////////////// INLINE void DrawableRegion:: set_clear_depth(float depth) { - _clear_depth = depth; + _clear_value[RTP_depth] = Colorf(depth,depth,depth,depth); } //////////////////////////////////////////////////////////////////// @@ -221,7 +232,7 @@ set_clear_depth(float depth) { //////////////////////////////////////////////////////////////////// INLINE float DrawableRegion:: get_clear_depth() const { - return _clear_depth; + return _clear_value[RTP_depth][0]; } //////////////////////////////////////////////////////////////////// // Function: DrawableRegion::set_clear_stencil @@ -234,7 +245,7 @@ get_clear_depth() const { //////////////////////////////////////////////////////////////////// INLINE void DrawableRegion:: set_clear_stencil(const unsigned int stencil) { - _clear_stencil = stencil; + _clear_value[RTP_stencil] = Colorf(stencil,stencil,stencil,stencil); } //////////////////////////////////////////////////////////////////// @@ -248,7 +259,30 @@ set_clear_stencil(const unsigned int stencil) { //////////////////////////////////////////////////////////////////// INLINE unsigned int DrawableRegion:: get_clear_stencil() const { - return _clear_stencil; + return (int)(_clear_value[RTP_stencil][0]); +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawableRegion::set_clear_value +// Access: Published +// Description: Sets the clear value for any bitplane. +//////////////////////////////////////////////////////////////////// +INLINE void DrawableRegion:: +set_clear_value(int id, const Colorf &color) { + nassertv((id >= 0) && (id < RTP_COUNT)); + _clear_value[id] = color; +} + +//////////////////////////////////////////////////////////////////// +// Function: DrawableRegion::get_clear_value +// Access: Published +// Description: Returns the clear value for any bitplane. +//////////////////////////////////////////////////////////////////// +INLINE const Colorf &DrawableRegion:: +get_clear_value(int id) const { + static Colorf blank(0.5,0.5,0.5,0.0); + nassertr((id >= 0) && (id < RTP_COUNT), blank); + return _clear_value[id]; } //////////////////////////////////////////////////////////////////// @@ -259,9 +293,9 @@ get_clear_stencil() const { //////////////////////////////////////////////////////////////////// INLINE void DrawableRegion:: disable_clears() { - set_clear_color_active(false); - set_clear_depth_active(false); - set_clear_stencil_active(false); + for (int i=0; i 0) { mask |= RenderBuffer::T_stencil; } - for (int aux_rgba=0; aux_rgba < _property[FBP_aux_rgba]; ++aux_rgba) { - mask |= (RenderBuffer::T_aux_rgba_0 << aux_rgba); - } - for (int aux_hrgba=0; aux_hrgba < _property[FBP_aux_hrgba]; ++aux_hrgba) { - mask |= (RenderBuffer::T_aux_hrgba_0 << aux_hrgba); - } - for (int aux_float=0; aux_float < _property[FBP_aux_float]; ++aux_float) { - mask |= (RenderBuffer::T_aux_float_0 << aux_float); - } - return mask; } diff --git a/panda/src/display/frameBufferProperties.h b/panda/src/display/frameBufferProperties.h index 0b96502aba..35769ad850 100644 --- a/panda/src/display/frameBufferProperties.h +++ b/panda/src/display/frameBufferProperties.h @@ -118,6 +118,7 @@ PUBLISHED: int get_quality(const FrameBufferProperties &reqs) const; bool is_any_specified() const; bool is_basic() const; + int get_aux_mask() const; int get_buffer_mask() const; bool verify_hardware_software(const FrameBufferProperties &props, const string &renderer) const; }; diff --git a/panda/src/display/graphicsOutput.h b/panda/src/display/graphicsOutput.h index 3094ba8201..2506d09d9c 100644 --- a/panda/src/display/graphicsOutput.h +++ b/panda/src/display/graphicsOutput.h @@ -83,28 +83,6 @@ PUBLISHED: RTM_triggered_copy_ram, }; - // It seems awkward to have this type, and also - // RenderBuffer::Type. However, the fact that RenderBuffer::Type - // is a bitmask makes it awfully awkward to work with. - enum RenderTexturePlane { - RTP_depth_stencil=1, - RTP_depth=1, - RTP_color, - RTP_aux_rgba_0, - RTP_aux_rgba_1, - RTP_aux_rgba_2, - RTP_aux_rgba_3, - RTP_aux_hrgba_0, - RTP_aux_hrgba_1, - RTP_aux_hrgba_2, - RTP_aux_hrgba_3, - RTP_aux_float_0, - RTP_aux_float_1, - RTP_aux_float_2, - RTP_aux_float_3, - RTP_COUNT - }; - // There are many reasons to call begin_frame/end_frame. enum FrameMode { FM_render, // We are rendering a frame. diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I index 6afe207c70..b2ae299ceb 100644 --- a/panda/src/display/graphicsStateGuardian.I +++ b/panda/src/display/graphicsStateGuardian.I @@ -747,23 +747,3 @@ set_current_properties(const FrameBufferProperties *prop) { _current_properties = prop; } -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::set_stencil_clear_value -// Access: Public -// Description: Set current stencil clear value. -//////////////////////////////////////////////////////////////////// -INLINE void GraphicsStateGuardian:: -set_stencil_clear_value(unsigned int stencil_clear_value) { - _stencil_clear_value = stencil_clear_value; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::get_stencil_clear_value -// Access: Public -// Description: Get current stencil clear value. -//////////////////////////////////////////////////////////////////// -INLINE unsigned int GraphicsStateGuardian:: -get_stencil_clear_value() { - return _stencil_clear_value; -} - diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 7c6a33708f..ff31694c2a 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -333,10 +333,6 @@ reset() { _scene_setup = _scene_null; _color_write_mask = ColorWriteAttrib::C_all; - _color_clear_value.set(0.0f, 0.0f, 0.0f, 0.0f); - _depth_clear_value = 1.0f; - _stencil_clear_value = 0; - _accum_clear_value.set(0.0f, 0.0f, 0.0f, 0.0f); _has_scene_graph_color = false; _transform_stale = true; @@ -389,6 +385,21 @@ set_state_and_transform(const RenderState *state, const TransformState *trans) { } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::clear +// Access: Public +// Description: Clears the framebuffer within the current +// DisplayRegion, according to the flags indicated by +// the given DrawableRegion object. +// +// This does not set the DisplayRegion first. You +// should call prepare_display_region() to specify the +// region you wish the clear operation to apply to. +//////////////////////////////////////////////////////////////////// +void GraphicsStateGuardian:: +clear(DrawableRegion *clearable) { +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::get_render_buffer // Access: Public @@ -731,63 +742,6 @@ compute_distance_to(const LPoint3f &point) const { } } -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::set_color_clear_value -// Access: Public -// Description: Sets the color that the next do_clear() command will set -// the color buffer to -//////////////////////////////////////////////////////////////////// -void GraphicsStateGuardian:: -set_color_clear_value(const Colorf& value) { - _color_clear_value = value; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::set_depth_clear_value -// Access: Public -// Description: Sets the depth that the next do_clear() command will set -// the depth buffer to -//////////////////////////////////////////////////////////////////// -void GraphicsStateGuardian:: -set_depth_clear_value(const float value) { - _depth_clear_value = value; -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::clear -// Access: Public -// Description: Clears the framebuffer within the current -// DisplayRegion, according to the flags indicated by -// the given DrawableRegion object. -// -// This does not set the DisplayRegion first. You -// should call prepare_display_region() to specify the -// region you wish the clear operation to apply to. -//////////////////////////////////////////////////////////////////// -void GraphicsStateGuardian:: -clear(DrawableRegion *clearable) { - PStatTimer timer(_clear_pcollector); - - int clear_buffer_type = 0; - if (clearable->get_clear_color_active()) { - clear_buffer_type |= clearable->get_draw_buffer_type(); - set_color_clear_value(clearable->get_clear_color()); - } - if (clearable->get_clear_depth_active()) { - clear_buffer_type |= RenderBuffer::T_depth; - set_depth_clear_value(clearable->get_clear_depth()); - } - if (clearable->get_clear_stencil_active()) { - clear_buffer_type |= RenderBuffer::T_stencil; - set_stencil_clear_value(clearable->get_clear_stencil()); - } - - if (clear_buffer_type != 0) { - do_clear(get_render_buffer(clear_buffer_type, - *_current_properties)); - } -} - //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::fetch_specified_value // Access: Public diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 3b8e0863c1..b95accf2e7 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -189,12 +189,8 @@ public: virtual float compute_distance_to(const LPoint3f &point) const; - virtual void set_color_clear_value(const Colorf &value); - virtual void set_depth_clear_value(const float value); - virtual void do_clear(const RenderBuffer &buffer)=0; - - void clear(DrawableRegion *clearable); - + virtual void clear(DrawableRegion *clearable); + const LMatrix4f *fetch_specified_value(Shader::ShaderMatSpec &spec, int altered); const LMatrix4f *fetch_specified_part(Shader::ShaderMatInput input, InternalName *name, LMatrix4f &t); @@ -263,9 +259,6 @@ public: virtual void bind_light(Spotlight *light_obj, const NodePath &light, int light_id); - INLINE void set_stencil_clear_value(unsigned int stencil_clear_value); - INLINE unsigned int get_stencil_clear_value(); - static void create_gamma_table (float gamma, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table); #ifdef DO_PSTATS @@ -320,10 +313,6 @@ protected: const GeomVertexDataPipelineReader *_data_reader; unsigned int _color_write_mask; - Colorf _color_clear_value; - float _depth_clear_value; - unsigned int _stencil_clear_value; - Colorf _accum_clear_value; CPT(DisplayRegion) _current_display_region; Lens::StereoChannel _current_stereo_channel; diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index a0b4313736..a7b3dcfa1f 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -103,7 +103,6 @@ DXGraphicsStateGuardian8(GraphicsPipe *pipe) : _d3d_ident_mat._11 = _d3d_ident_mat._22 = _d3d_ident_mat._33 = _d3d_ident_mat._44 = 1.0f; _cur_read_pixel_buffer = RenderBuffer::T_front; - set_color_clear_value(_color_clear_value); // DirectX drivers seem to consistently invert the texture when // they copy framebuffer-to-texture. Ok. @@ -485,17 +484,6 @@ make_geom_munger(const RenderState *state, Thread *current_thread) { return GeomMunger::register_munger(munger, current_thread); } -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian8::set_color_clear_value -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian8:: -set_color_clear_value(const Colorf& value) { - _color_clear_value = value; - _d3dcolor_clear_value = Colorf_to_D3DCOLOR(value); -} - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian8::do_clear // Access: Public, Virtual @@ -503,24 +491,26 @@ set_color_clear_value(const Colorf& value) { // colors. //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: -do_clear(const RenderBuffer &buffer) { - nassertv(buffer._gsg == this); - int buffer_type = buffer._buffer_type; +clear(DrawableRegion *clearable) { DWORD main_flags = 0; DWORD aux_flags = 0; + D3DCOLOR color_clear_value = Colorf_to_D3DCOLOR(clearable->get_clear_color()); + float depth_clear_value = clearable->get_clear_depth(); + DWORD stencil_clear_value = (DWORD)(clearable->get_clear_stencil()); + //set appropriate flags - if (buffer_type & RenderBuffer::T_color) { + if (clearable->get_clear_color_active()) { main_flags |= D3DCLEAR_TARGET; } - if (buffer_type & RenderBuffer::T_depth) { + if (clearable->get_clear_depth_active()) { aux_flags |= D3DCLEAR_ZBUFFER; nassertv(_screen->_presentation_params.EnableAutoDepthStencil); } - if (buffer_type & RenderBuffer::T_stencil) { + if (clearable->get_clear_stencil_active()) { // clear only if there is a stencil buffer if (_screen->_presentation_params.EnableAutoDepthStencil && IS_STENCIL_FORMAT(_screen->_presentation_params.AutoDepthStencilFormat)) { @@ -529,20 +519,20 @@ do_clear(const RenderBuffer &buffer) { } if ((main_flags | aux_flags) != 0) { - HRESULT hr = _d3d_device->Clear(0, NULL, main_flags | aux_flags, _d3dcolor_clear_value, - _depth_clear_value, (DWORD)_stencil_clear_value); + HRESULT hr = _d3d_device->Clear(0, NULL, main_flags | aux_flags, color_clear_value, + depth_clear_value, stencil_clear_value); if (FAILED(hr) && main_flags == D3DCLEAR_TARGET && aux_flags != 0) { // Maybe there's a problem with the one or more of the auxiliary // buffers. - hr = _d3d_device->Clear(0, NULL, D3DCLEAR_TARGET, _d3dcolor_clear_value, - _depth_clear_value, (DWORD)_stencil_clear_value); + hr = _d3d_device->Clear(0, NULL, D3DCLEAR_TARGET, color_clear_value, + depth_clear_value, stencil_clear_value); if (!FAILED(hr)) { // Yep, it worked without them. That's a problem. Which buffer // poses the problem? - if (buffer_type & RenderBuffer::T_depth) { + if (clearable->get_clear_depth_active()) { aux_flags |= D3DCLEAR_ZBUFFER; - HRESULT hr2 = _d3d_device->Clear(0, NULL, D3DCLEAR_ZBUFFER, _d3dcolor_clear_value, - _depth_clear_value, (DWORD)_stencil_clear_value); + HRESULT hr2 = _d3d_device->Clear(0, NULL, D3DCLEAR_ZBUFFER, color_clear_value, + depth_clear_value, stencil_clear_value); if (FAILED(hr2)) { dxgsg8_cat.error() << "Unable to clear depth buffer; removing.\n"; @@ -550,10 +540,10 @@ do_clear(const RenderBuffer &buffer) { ((FrameBufferProperties *)_current_properties)->set_depth_bits(0); } } - if (buffer_type & RenderBuffer::T_stencil) { + if (clearable->get_clear_stencil_active()) { aux_flags |= D3DCLEAR_STENCIL; - HRESULT hr2 = _d3d_device->Clear(0, NULL, D3DCLEAR_STENCIL, _d3dcolor_clear_value, - _stencil_clear_value, (DWORD)_stencil_clear_value); + HRESULT hr2 = _d3d_device->Clear(0, NULL, D3DCLEAR_STENCIL, color_clear_value, + stencil_clear_value, stencil_clear_value); if (FAILED(hr2)) { dxgsg8_cat.error() << "Unable to clear stencil buffer; removing.\n"; @@ -563,7 +553,7 @@ do_clear(const RenderBuffer &buffer) { } } } - + if (FAILED(hr)) { dxgsg8_cat.error() << "clear_buffer failed: Clear returned " << D3DERRORSTRING(hr); diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 142c573774..4a407b75a9 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -68,9 +68,7 @@ public: virtual PT(GeomMunger) make_geom_munger(const RenderState *state, Thread *current_thread); - virtual void set_color_clear_value(const Colorf &value); - - virtual void do_clear(const RenderBuffer &buffer); + virtual void clear(DrawableRegion *region); virtual void prepare_display_region(DisplayRegionPipelineReader *dr, Lens::StereoChannel stereo_channel); @@ -226,8 +224,6 @@ protected: RenderBuffer::Type _cur_read_pixel_buffer; // source for copy_pixel_buffer operation bool _auto_rescale_normal; - D3DCOLOR _d3dcolor_clear_value; - float _material_ambient; float _material_diffuse; float _material_specular; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 4332852fe9..45ce20959f 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -121,7 +121,6 @@ DXGraphicsStateGuardian9(GraphicsPipe *pipe) : _d3d_ident_mat._11 = _d3d_ident_mat._22 = _d3d_ident_mat._33 = _d3d_ident_mat._44 = 1.0f; _cur_read_pixel_buffer = RenderBuffer::T_front; - set_color_clear_value(_color_clear_value); // DirectX drivers seem to consistently invert the texture when // they copy framebuffer-to-texture. Ok. @@ -767,43 +766,34 @@ make_geom_munger(const RenderState *state, Thread *current_thread) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian9::set_color_clear_value -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian9:: -set_color_clear_value(const Colorf& value) { - _color_clear_value = value; - _d3dcolor_clear_value = Colorf_to_D3DCOLOR(value); -} - -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian9::do_clear +// Function: DXGraphicsStateGuardian9::clear // Access: Public, Virtual // Description: Clears all of the indicated buffers to their assigned // colors. //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: -do_clear(const RenderBuffer &buffer) { - nassertv(buffer._gsg == this); - int buffer_type = buffer._buffer_type; +clear(DrawableRegion *clearable) { DWORD main_flags = 0; DWORD aux_flags = 0; + D3DCOLOR color_clear_value = Colorf_to_D3DCOLOR(clearable->get_clear_color()); + float depth_clear_value = clearable->get_clear_depth(); + DWORD stencil_clear_value = (DWORD)(clearable->get_clear_stencil()); + DBG_S dxgsg9_cat.debug ( ) << "DXGraphicsStateGuardian9::do_clear\n"; DBG_E //set appropriate flags - if (buffer_type & RenderBuffer::T_color) { + if (clearable->get_clear_color_active()) { main_flags |= D3DCLEAR_TARGET; } - if (buffer_type & RenderBuffer::T_depth) { + if (clearable->get_clear_depth_active()) { aux_flags |= D3DCLEAR_ZBUFFER; nassertv(_screen->_presentation_params.EnableAutoDepthStencil); } - if (buffer_type & RenderBuffer::T_stencil) { + if (clearable->get_clear_stencil_active()) { // clear only if there is a stencil buffer if (_screen->_presentation_params.EnableAutoDepthStencil && IS_STENCIL_FORMAT(_screen->_presentation_params.AutoDepthStencilFormat)) { @@ -811,7 +801,7 @@ do_clear(const RenderBuffer &buffer) { // DEBUG if (false) { - dxgsg9_cat.debug ( ) << "STENCIL CLEAR " << _stencil_clear_value << "\n"; + dxgsg9_cat.debug ( ) << "STENCIL CLEAR " << stencil_clear_value << "\n"; } } } @@ -821,20 +811,20 @@ do_clear(const RenderBuffer &buffer) { DBG_S dxgsg9_cat.debug ( ) << "ccccc DXGraphicsStateGuardian9::really do_clear\n"; DBG_E DBG_S dxgsg9_cat.debug ( ) << "clear flags: main " << main_flags << " aux :" << aux_flags << "\n"; DBG_E - HRESULT hr = _d3d_device->Clear(0, NULL, main_flags | aux_flags, _d3dcolor_clear_value, - _depth_clear_value, (DWORD)_stencil_clear_value); + HRESULT hr = _d3d_device->Clear(0, NULL, main_flags | aux_flags, color_clear_value, + depth_clear_value, stencil_clear_value); if (FAILED(hr) && main_flags == D3DCLEAR_TARGET && aux_flags != 0) { // Maybe there's a problem with the one or more of the auxiliary // buffers. - hr = _d3d_device->Clear(0, NULL, D3DCLEAR_TARGET, _d3dcolor_clear_value, - _depth_clear_value, (DWORD)_stencil_clear_value); + hr = _d3d_device->Clear(0, NULL, D3DCLEAR_TARGET, color_clear_value, + depth_clear_value, stencil_clear_value); if (!FAILED(hr)) { // Yep, it worked without them. That's a problem. Which buffer // poses the problem? - if (buffer_type & RenderBuffer::T_depth) { + if (clearable->get_clear_depth_active()) { aux_flags |= D3DCLEAR_ZBUFFER; - HRESULT hr2 = _d3d_device->Clear(0, NULL, D3DCLEAR_ZBUFFER, _d3dcolor_clear_value, - _depth_clear_value, (DWORD)_stencil_clear_value); + HRESULT hr2 = _d3d_device->Clear(0, NULL, D3DCLEAR_ZBUFFER, color_clear_value, + depth_clear_value, stencil_clear_value); if (FAILED(hr2)) { dxgsg9_cat.error() << "Unable to clear depth buffer; removing.\n"; @@ -842,10 +832,10 @@ do_clear(const RenderBuffer &buffer) { ((FrameBufferProperties *)_current_properties)->set_depth_bits(0); } } - if (buffer_type & RenderBuffer::T_stencil) { + if (clearable->get_clear_stencil_active()) { aux_flags |= D3DCLEAR_STENCIL; - HRESULT hr2 = _d3d_device->Clear(0, NULL, D3DCLEAR_STENCIL, _d3dcolor_clear_value, - _stencil_clear_value, (DWORD)_stencil_clear_value); + HRESULT hr2 = _d3d_device->Clear(0, NULL, D3DCLEAR_STENCIL, color_clear_value, + stencil_clear_value, stencil_clear_value); if (FAILED(hr2)) { dxgsg9_cat.error() << "Unable to clear stencil buffer; removing.\n"; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index 84e039aa9f..420ef7ef68 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -108,9 +108,7 @@ public: virtual PT(GeomMunger) make_geom_munger(const RenderState *state, Thread *current_thread); - virtual void set_color_clear_value(const Colorf &value); - - virtual void do_clear(const RenderBuffer &buffer); + virtual void clear(DrawableRegion *clearable); virtual void prepare_display_region(DisplayRegionPipelineReader *dr, Lens::StereoChannel stereo_channel); @@ -280,8 +278,6 @@ protected: RenderBuffer::Type _cur_read_pixel_buffer; // source for copy_pixel_buffer operation bool _auto_rescale_normal; - D3DCOLOR _d3dcolor_clear_value; - float _material_ambient; float _material_diffuse; float _material_specular; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 432b64c495..afc2a20db1 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1224,45 +1224,89 @@ reset() { //////////////////////////////////////////////////////////////////// -// Function: GLGraphicsStateGuardian::do_clear -// Access: Public, Virtual -// Description: Clears all of the indicated buffers to their assigned -// colors. +// Function: GraphicsStateGuardian::clear +// Access: Public +// Description: Clears the framebuffer within the current +// DisplayRegion, according to the flags indicated by +// the given DrawableRegion object. +// +// This does not set the DisplayRegion first. You +// should call prepare_display_region() to specify the +// region you wish the clear operation to apply to. //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: -do_clear(const RenderBuffer &buffer) { - nassertv(buffer._gsg == this); - int buffer_type = buffer._buffer_type; - GLbitfield mask = 0; +clear(DrawableRegion *clearable) { + PStatTimer timer(_clear_pcollector); + if ((!clearable->get_clear_color_active())&& + (!clearable->get_clear_depth_active())&& + (!clearable->get_clear_stencil_active())) { + return; + } + set_state_and_transform(RenderState::make_empty(), _internal_transform); - if (buffer_type & RenderBuffer::T_color) { - GLP(ClearColor)(_color_clear_value[0], - _color_clear_value[1], - _color_clear_value[2], - _color_clear_value[3]); - mask |= GL_COLOR_BUFFER_BIT; - set_draw_buffer(buffer); - } + int mask = 0; - if (buffer_type & RenderBuffer::T_depth) { - GLP(ClearDepth)(_depth_clear_value); + for (int i=0; i<_current_properties->get_aux_rgba(); i++) { + int layerid = GraphicsOutput::RTP_aux_rgba_0 + i; + int layerbit = RenderBuffer::T_aux_rgba_0 << i; + if (clearable->get_clear_active(layerid)) { + Colorf v = clearable->get_clear_value(layerid); + GLP(ClearColor)(v[0],v[1],v[2],v[3]); + set_draw_buffer(layerbit); + GLP(Clear)(GL_COLOR_BUFFER_BIT); + } + } + for (int i=0; i<_current_properties->get_aux_hrgba(); i++) { + int layerid = GraphicsOutput::RTP_aux_hrgba_0 + i; + int layerbit = RenderBuffer::T_aux_hrgba_0 << i; + if (clearable->get_clear_active(layerid)) { + Colorf v = clearable->get_clear_value(layerid); + GLP(ClearColor)(v[0],v[1],v[2],v[3]); + set_draw_buffer(layerbit); + GLP(Clear)(GL_COLOR_BUFFER_BIT); + } + } + for (int i=0; i<_current_properties->get_aux_float(); i++) { + int layerid = GraphicsOutput::RTP_aux_float_0 + i; + int layerbit = RenderBuffer::T_aux_float_0 << i; + if (clearable->get_clear_active(layerid)) { + Colorf v = clearable->get_clear_value(layerid); + GLP(ClearColor)(v[0],v[1],v[2],v[3]); + set_draw_buffer(layerbit); + GLP(Clear)(GL_COLOR_BUFFER_BIT); + } + } + + if (clearable->get_clear_color_active()) { + Colorf v = clearable->get_clear_color(); + GLP(ClearColor)(v[0],v[1],v[2],v[3]); + mask |= GL_COLOR_BUFFER_BIT; + set_draw_buffer(clearable->get_draw_buffer_type()); + } + + if (clearable->get_clear_depth_active()) { + GLP(ClearDepth)(clearable->get_clear_depth()); mask |= GL_DEPTH_BUFFER_BIT; } - if (buffer_type & RenderBuffer::T_stencil) { - GLP(ClearStencil)(_stencil_clear_value); + if (clearable->get_clear_stencil_active()) { + GLP(ClearStencil)(clearable->get_clear_stencil()); mask |= GL_STENCIL_BUFFER_BIT; } - - if (buffer_type & RenderBuffer::T_accum) { - GLP(ClearAccum)(_accum_clear_value[0], - _accum_clear_value[1], - _accum_clear_value[2], - _accum_clear_value[3]); - mask |= GL_ACCUM_BUFFER_BIT; - } + + GLP(Clear)(mask); + + // In the past, it was possible to set the draw buffer + // once in prepare_display_region and then forget about it. + // Now, with aux layers, it is necessary to occasionally + // change the draw buffer. In time, I think there will need + // to be a draw buffer attrib. Until then, this little hack + // to put things back the way they were after + // prepare_display_region will bdo. + + set_draw_buffer(_draw_buffer_type); if (GLCAT.is_spam()) { GLCAT.spam() << "glClear("; @@ -1281,7 +1325,6 @@ do_clear(const RenderBuffer &buffer) { GLCAT.spam(false) << ")" << endl; } - GLP(Clear)(mask); report_my_gl_errors(); } @@ -1306,8 +1349,10 @@ prepare_display_region(DisplayRegionPipelineReader *dr, GLsizei width = GLsizei(w); GLsizei height = GLsizei(h); - set_draw_buffer(get_render_buffer(dr->get_object()->get_draw_buffer_type(), - *_current_properties)); + _draw_buffer_type = dr->get_object()->get_draw_buffer_type() & _current_properties->get_buffer_mask() & _stereo_buffer_mask; + _draw_buffer_type |= _current_properties->get_aux_mask(); + set_draw_buffer(_draw_buffer_type); + enable_scissor(true); GLP(Scissor)(x, y, width, height); GLP(Viewport)(x, y, width, height); @@ -3276,7 +3321,7 @@ void CLP(GraphicsStateGuardian):: framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb) { nassertv(tex != NULL && dr != NULL); - set_read_buffer(rb); + set_read_buffer(rb._buffer_type); int xo, yo, w, h; dr->get_region_pixels(xo, yo, w, h); @@ -3363,7 +3408,7 @@ bool CLP(GraphicsStateGuardian):: framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb) { nassertr(tex != NULL && dr != NULL, false); - set_read_buffer(rb); + set_read_buffer(rb._buffer_type); GLP(PixelStorei)(GL_PACK_ALIGNMENT, 1); // Bug fix for RE, RE2, and VTX - need to disable texturing in order @@ -4556,30 +4601,43 @@ get_extension_func(const char *, const char *) { // Access: Protected // Description: Sets up the GLP(DrawBuffer) to render into the buffer // indicated by the RenderBuffer object. This only sets -// up the color bits; it does not affect the depth, +// up the color and aux bits; it does not affect the depth, // stencil, accum layers. //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: -set_draw_buffer(const RenderBuffer &rb) { +set_draw_buffer(int rbtype) { if (_current_fbo) { GLuint buffers[16]; - int nbuffers = 0; - if (rb._buffer_type & RenderBuffer::T_front) { - nbuffers += 1; + int nbuffers=0; + if (rbtype & RenderBuffer::T_color) { + buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT; } - nbuffers += _current_properties->get_aux_rgba(); - nbuffers += _current_properties->get_aux_hrgba(); - nbuffers += _current_properties->get_aux_float(); - for (int i=0; iget_aux_rgba(); i++) { + if (rbtype & (RenderBuffer::T_aux_rgba_0 << i)) { + buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index; + } + index += 1; + } + for (int i=0; i<_current_properties->get_aux_hrgba(); i++) { + if (rbtype & (RenderBuffer::T_aux_hrgba_0 << i)) { + buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index; + } + index += 1; + } + for (int i=0; i<_current_properties->get_aux_float(); i++) { + if (rbtype & (RenderBuffer::T_aux_float_0 << i)) { + buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index; + } + index += 1; } _glDrawBuffers(nbuffers, buffers); } else { - switch (rb._buffer_type & RenderBuffer::T_color) { + switch (rbtype & RenderBuffer::T_color) { case RenderBuffer::T_front: GLP(DrawBuffer)(GL_FRONT); break; @@ -4620,7 +4678,7 @@ set_draw_buffer(const RenderBuffer &rb) { break; } } - + // Also ensure that any global color channels are masked out. if (CLP(color_mask)) { GLP(ColorMask)((_color_write_mask & ColorWriteAttrib::C_red) != 0, @@ -4628,7 +4686,7 @@ set_draw_buffer(const RenderBuffer &rb) { (_color_write_mask & ColorWriteAttrib::C_blue) != 0, (_color_write_mask & ColorWriteAttrib::C_alpha) != 0); } - + report_my_gl_errors(); } @@ -4641,26 +4699,26 @@ set_draw_buffer(const RenderBuffer &rb) { // stencil, accum layers. //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: -set_read_buffer(const RenderBuffer &rb) { +set_read_buffer(int rbtype) { if (_current_fbo) { GLuint buffer = GL_COLOR_ATTACHMENT0_EXT; int index = 1; for (int i=0; i<_current_properties->get_aux_rgba(); i++) { - if (rb._buffer_type & (RenderBuffer::T_aux_rgba_0 << i)) { + if (rbtype & (RenderBuffer::T_aux_rgba_0 << i)) { buffer = GL_COLOR_ATTACHMENT0_EXT + index; } index += 1; } for (int i=0; i<_current_properties->get_aux_hrgba(); i++) { - if (rb._buffer_type & (RenderBuffer::T_aux_hrgba_0 << i)) { + if (rbtype & (RenderBuffer::T_aux_hrgba_0 << i)) { buffer = GL_COLOR_ATTACHMENT0_EXT + index; } index += 1; } for (int i=0; i<_current_properties->get_aux_float(); i++) { - if (rb._buffer_type & (RenderBuffer::T_aux_float_0 << i)) { + if (rbtype & (RenderBuffer::T_aux_float_0 << i)) { buffer = GL_COLOR_ATTACHMENT0_EXT + index; } index += 1; @@ -4669,7 +4727,7 @@ set_read_buffer(const RenderBuffer &rb) { } else { - switch (rb._buffer_type & RenderBuffer::T_color) { + switch (rbtype & RenderBuffer::T_color) { case RenderBuffer::T_front: GLP(ReadBuffer)(GL_FRONT); break; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 0d05c5f58e..31acde2617 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -116,8 +116,6 @@ public: virtual void reset(); - virtual void do_clear(const RenderBuffer &buffer); - virtual void prepare_display_region(DisplayRegionPipelineReader *dr, Lens::StereoChannel stereo_channel); virtual CPT(TransformState) calc_projection_mat(const Lens *lens); @@ -185,6 +183,8 @@ public: virtual PT(GeomMunger) make_geom_munger(const RenderState *state, Thread *current_thread); + virtual void clear(DrawableRegion *region); + virtual void framebuffer_copy_to_texture (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb); virtual bool framebuffer_copy_to_ram @@ -293,8 +293,8 @@ protected: INLINE GLenum get_light_id(int index) const; INLINE GLenum get_clip_plane_id(int index) const; - void set_draw_buffer(const RenderBuffer &rb); - void set_read_buffer(const RenderBuffer &rb); + void set_draw_buffer(int rbtype); + void set_read_buffer(int rbtype); static GLenum get_numeric_type(Geom::NumericType numeric_type); GLenum get_texture_target(Texture::TextureType texture_type) const; @@ -357,7 +357,7 @@ protected: MM_alpha_mask = 0x0004, }; - int _multisample_mode; + int _multisample_mode; bool _line_smooth_enabled; bool _point_smooth_enabled; bool _polygon_smooth_enabled; @@ -369,12 +369,13 @@ protected: bool _alpha_test_enabled; bool _polygon_offset_enabled; bool _flat_shade_model; - int _decal_level; + int _decal_level; bool _dithering_enabled; int _viewport_width; int _viewport_height; + int _draw_buffer_type; bool _auto_antialias_mode; RenderModeAttrib::Mode _render_mode; float _point_size; @@ -400,7 +401,7 @@ protected: GLuint _current_ibuffer_index; GLuint _current_fbo; int _num_active_texture_stages; - + int _error_count; string _gl_vendor; diff --git a/panda/src/movies/webcamVideo.I b/panda/src/movies/webcamVideo.I index f0aa484650..66c1398390 100644 --- a/panda/src/movies/webcamVideo.I +++ b/panda/src/movies/webcamVideo.I @@ -17,16 +17,6 @@ //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Function: WebcamVideo::get_name -// Access: Published -// Description: Returns the camera's name / description. -//////////////////////////////////////////////////////////////////// -INLINE const string &WebcamVideo:: -get_name() const { - return _name; -} - //////////////////////////////////////////////////////////////////// // Function: WebcamVideo::get_size_x // Access: Published diff --git a/panda/src/movies/webcamVideo.h b/panda/src/movies/webcamVideo.h index 030443c19f..8e6699ecea 100644 --- a/panda/src/movies/webcamVideo.h +++ b/panda/src/movies/webcamVideo.h @@ -34,7 +34,6 @@ PUBLISHED: static int get_num_options(); static PT(WebcamVideo) get_option(int n); - INLINE const string &get_name() const; INLINE int get_size_x() const; INLINE int get_size_y() const; INLINE int get_fps() const; @@ -43,10 +42,8 @@ PUBLISHED: public: static void find_all_webcams(); - protected: - string _name; int _size_x; int _size_y; int _fps; diff --git a/panda/src/movies/webcamVideoDS.cxx b/panda/src/movies/webcamVideoDS.cxx index 4f6bd7feaf..9215d7bb10 100644 --- a/panda/src/movies/webcamVideoDS.cxx +++ b/panda/src/movies/webcamVideoDS.cxx @@ -329,14 +329,14 @@ add_device(WebcamVideoList &list, IMoniker *pMoniker, AM_MEDIA_TYPE *media) { PT(WebcamVideoDS) wc = new WebcamVideoDS; ostringstream name; name << "DirectShow: " << get_moniker_name(pMoniker) << " @ " << media_x(media) << " x " << media_y(media) << " FPS:" << media_fps(media); - wc->_name = name.str(); + wc->set_name(name.str()); wc->_size_x = media_x(media); wc->_size_y = media_y(media); wc->_fps = media_fps(media); wc->_moniker = pMoniker; wc->_media = media; list.push_back(wc); - cerr << "Added device: " << wc->_name << "\n"; + cerr << "Added device: " << wc->get_name() << "\n"; }