diff --git a/panda/src/display/Sources.pp b/panda/src/display/Sources.pp index 118e87be77..98c9e3d24e 100644 --- a/panda/src/display/Sources.pp +++ b/panda/src/display/Sources.pp @@ -43,7 +43,6 @@ windowHandle.I windowHandle.h \ windowProperties.I windowProperties.h \ renderBuffer.h \ - stencilRenderStates.h \ stereoDisplayRegion.I stereoDisplayRegion.h \ displaySearchParameters.h \ displayInformation.h \ @@ -80,7 +79,6 @@ parasiteBuffer.cxx \ windowHandle.cxx \ windowProperties.cxx \ - stencilRenderStates.cxx \ stereoDisplayRegion.cxx \ subprocessWindow.cxx \ touchInfo.cxx @@ -118,7 +116,6 @@ windowHandle.I windowHandle.h \ windowProperties.I windowProperties.h \ renderBuffer.h \ - stencilRenderStates.h \ stereoDisplayRegion.I stereoDisplayRegion.h \ subprocessWindow.h subprocessWindow.I \ subprocessWindowBuffer.h subprocessWindowBuffer.I \ diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 1e8131e6b4..65ca18054b 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -258,8 +258,6 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system, // it is rendered. _runtime_color_scale = false; - _stencil_render_states = 0; - // The default is no shader support. _auto_detect_shader_model = SM_00; _shader_model = SM_00; @@ -279,11 +277,6 @@ GraphicsStateGuardian:: ~GraphicsStateGuardian() { remove_gsg(this); - if (_stencil_render_states) { - delete _stencil_render_states; - _stencil_render_states = 0; - } - if (_shader_generator) { delete _shader_generator; _shader_generator = 0; @@ -1988,12 +1981,6 @@ reset() { _last_max_stage_index = 0; _is_valid = true; - - if (_stencil_render_states) { - delete _stencil_render_states; - _stencil_render_states = 0; - } - _stencil_render_states = new StencilRenderStates(this); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 8484ee1be6..0cc5a3a587 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -45,7 +45,6 @@ #include "texture.h" #include "occlusionQueryContext.h" #include "timerQueryContext.h" -#include "stencilRenderStates.h" #include "loader.h" #include "shaderAttrib.h" #include "texGenAttrib.h" @@ -532,8 +531,6 @@ protected: int _stereo_buffer_mask; - StencilRenderStates *_stencil_render_states; - int _auto_detect_shader_model; int _shader_model; diff --git a/panda/src/display/p3display_composite2.cxx b/panda/src/display/p3display_composite2.cxx index 35755515f4..4d613bb588 100644 --- a/panda/src/display/p3display_composite2.cxx +++ b/panda/src/display/p3display_composite2.cxx @@ -12,7 +12,6 @@ #include "nativeWindowHandle.cxx" #include "parasiteBuffer.cxx" #include "standardMunger.cxx" -#include "stencilRenderStates.cxx" #include "touchInfo.cxx" #include "stereoDisplayRegion.cxx" #include "subprocessWindow.cxx" diff --git a/panda/src/display/stencilRenderStates.cxx b/panda/src/display/stencilRenderStates.cxx deleted file mode 100644 index 76773e3dfd..0000000000 --- a/panda/src/display/stencilRenderStates.cxx +++ /dev/null @@ -1,111 +0,0 @@ -// Filename: stencilRenderStates.cxx -// Created by: aignacio (17May06) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised BSD -// license. You should have received a copy of this license along -// with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// - -#include "graphicsStateGuardian.h" -#include "stencilRenderStates.h" - -//////////////////////////////////////////////////////////////////// -// Function: StencilRenderStates::Constructor -// Description: Constructor. All data is set to the default. -//////////////////////////////////////////////////////////////////// -StencilRenderStates:: -StencilRenderStates (GraphicsStateGuardian *gsg) { - - int index; - - // clear all - for (index = 0; index < SRS_total; index++) { - _stencil_render_state_array [index] = 0; - _stencil_function_array [index] = 0; - } - - // set default render states - set_stencil_render_state (false, SRS_reference, 0); - - set_stencil_render_state (false, SRS_read_mask, ~0); - set_stencil_render_state (false, SRS_write_mask, ~0); - - set_stencil_render_state (false, SRS_front_enable, 0); - set_stencil_render_state (false, SRS_front_comparison_function, SCF_always); - set_stencil_render_state (false, SRS_front_stencil_fail_operation, SO_keep); - set_stencil_render_state (false, SRS_front_stencil_pass_z_fail_operation, SO_keep); - set_stencil_render_state (false, SRS_front_stencil_pass_z_pass_operation, SO_keep); - - set_stencil_render_state (false, SRS_back_enable, 0); - set_stencil_render_state (false, SRS_back_comparison_function, SCF_always); - set_stencil_render_state (false, SRS_back_stencil_fail_operation, SO_keep); - set_stencil_render_state (false, SRS_back_stencil_pass_z_fail_operation, SO_keep); - set_stencil_render_state (false, SRS_back_stencil_pass_z_pass_operation, SO_keep); - - _gsg = gsg; -} - -//////////////////////////////////////////////////////////////////// -// Function: StencilRenderStates::Destructor -// Description: -//////////////////////////////////////////////////////////////////// -StencilRenderStates:: -~StencilRenderStates (void) { - -} - -//////////////////////////////////////////////////////////////////// -// Function: StencilRenderStates::set_stencil_render_state -// Description: Sets the current render state for the specified -// stencil render state. The execute_function -// parameter can be used to defer the actual setting -// of the render state at the API level. This is -// useful for the OpenGL API where certain render -// states are not independent/atomic (i.e. -// glStencilFunc and glStencilOp). -//////////////////////////////////////////////////////////////////// -void StencilRenderStates:: -set_stencil_render_state (bool execute_function, StencilRenderStates::StencilRenderState stencil_render_state, StencilType value) { - - // DEBUG - if (false) { - printf ("SRS %d %d %d \n", execute_function, stencil_render_state, value); - } - - _stencil_render_state_array [stencil_render_state] = value; - - if (execute_function) { - StencilFunction stencil_function; - - stencil_function = _stencil_function_array [stencil_render_state]; - if (stencil_function) { - stencil_function (stencil_render_state, this); - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: StencilRenderStates::get_stencil_render_state -// Description: Gets the current render state for the specified -// stencil render state. -//////////////////////////////////////////////////////////////////// -StencilType StencilRenderStates:: -get_stencil_render_state (StencilRenderStates::StencilRenderState stencil_render_state) { - return _stencil_render_state_array [stencil_render_state]; -} - -//////////////////////////////////////////////////////////////////// -// Function: StencilRenderStates::set_stencil_function -// Description: Registers an API specific callback for setting a -// specified stencil render state. -//////////////////////////////////////////////////////////////////// -void StencilRenderStates:: -set_stencil_function (StencilRenderStates::StencilRenderState stencil_render_state, StencilFunction stencil_function) { - _stencil_function_array [stencil_render_state] = stencil_function; -} diff --git a/panda/src/display/stencilRenderStates.h b/panda/src/display/stencilRenderStates.h deleted file mode 100644 index 6afb0b77fa..0000000000 --- a/panda/src/display/stencilRenderStates.h +++ /dev/null @@ -1,101 +0,0 @@ -// Filename: stencilRenderStates.h -// Created by: aignacio (17May06) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised BSD -// license. You should have received a copy of this license along -// with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// - -#ifndef STENCILRENDERSTATES_H -#define STENCILRENDERSTATES_H - -class GraphicsStateGuardian; -typedef unsigned int StencilType; - -//////////////////////////////////////////////////////////////////// -// Class : StencilRenderStates -// Description : An abstract cross-platform class for setting stencil -// buffer render states. Each gsg needs to create its -// own low-level API specific functions on how to set -// each render state. The "set_stencil_render_state" -// function can be used in an immediate-mode fashion. -//////////////////////////////////////////////////////////////////// -class EXPCL_PANDA_DISPLAY StencilRenderStates { - -PUBLISHED: - enum StencilRenderState - { - SRS_front_enable, - SRS_back_enable, - - SRS_front_comparison_function, - SRS_front_stencil_fail_operation, - SRS_front_stencil_pass_z_fail_operation, - SRS_front_stencil_pass_z_pass_operation, - - SRS_reference, - SRS_read_mask, - SRS_write_mask, - - SRS_back_comparison_function, - SRS_back_stencil_fail_operation, - SRS_back_stencil_pass_z_fail_operation, - SRS_back_stencil_pass_z_pass_operation, - - SRS_clear, - SRS_clear_value, - - SRS_total, - - SRS_first = 0, - }; - - enum StencilComparisonFunction - { - SCF_never, - SCF_less_than, - SCF_equal, - SCF_less_than_or_equal, - SCF_greater_than, - SCF_not_equal, - SCF_greater_than_or_equal, - SCF_always, - }; - - enum StencilOperation - { - SO_keep, - SO_zero, - SO_replace, - SO_increment, - SO_decrement, - SO_invert, - SO_increment_saturate, - SO_decrement_saturate, - }; - -public: - typedef void (*StencilFunction) (StencilRenderStates::StencilRenderState stencil_render_state, StencilRenderStates *stencil_render_states); - - StencilRenderStates (GraphicsStateGuardian *gsg); - ~StencilRenderStates (void); - - void set_stencil_render_state (bool execute_function, StencilRenderStates::StencilRenderState stencil_render_state, StencilType value); - StencilType get_stencil_render_state (StencilRenderStates::StencilRenderState stencil_render_state); - - void set_stencil_function (StencilRenderStates::StencilRenderState stencil_render_state, StencilFunction stencil_function); - - GraphicsStateGuardian *_gsg; - -private: - StencilType _stencil_render_state_array [SRS_total]; - StencilFunction _stencil_function_array [SRS_total]; -}; - -#endif diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index c8b0730ea4..039111a9d3 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -2074,9 +2074,6 @@ reset() { PRINT_REFCNT(dxgsg8, _d3d_device); - void dx_set_stencil_functions (StencilRenderStates *stencil_render_states); - dx_set_stencil_functions (_stencil_render_states); - // Now that the GSG has been initialized, make it available for // optimizations. add_gsg(this); @@ -4310,9 +4307,7 @@ draw_indexed_primitive_up(D3DPRIMITIVETYPE primitive_type, //////////////////////////////////////////////////////////////////// // DX stencil code section //////////////////////////////////////////////////////////////////// - -static int dx_stencil_comparison_function_array [ ] = -{ +static int dx_stencil_comparison_function_array[] = { D3DCMP_NEVER, D3DCMP_LESS, D3DCMP_EQUAL, @@ -4323,8 +4318,7 @@ static int dx_stencil_comparison_function_array [ ] = D3DCMP_ALWAYS, }; -static int dx_stencil_operation_array [ ] = -{ +static int dx_stencil_operation_array[] = { D3DSTENCILOP_KEEP, D3DSTENCILOP_ZERO, D3DSTENCILOP_REPLACE, @@ -4336,84 +4330,6 @@ static int dx_stencil_operation_array [ ] = D3DSTENCILOP_DECRSAT, }; -void dx_stencil_function (StencilRenderStates::StencilRenderState stencil_render_state, StencilRenderStates *stencil_render_states) { - StencilType render_state_value; - - DXGraphicsStateGuardian8 *gsg; - LPDIRECT3DDEVICE8 device; - - gsg = (DXGraphicsStateGuardian8 *) stencil_render_states -> _gsg; - device = gsg->get_d3d_device(); - - render_state_value = stencil_render_states -> get_stencil_render_state (stencil_render_state); - - if (dxgsg8_cat.is_debug()) { - dxgsg8_cat.debug() - << "SRS: " << StencilAttrib::stencil_render_state_name_array [stencil_render_state] << ", " << render_state_value << "\n"; - } - - switch (stencil_render_state) - { - case StencilRenderStates::SRS_front_enable: - device->SetRenderState (D3DRS_STENCILENABLE, render_state_value); - break; - - case StencilRenderStates::SRS_back_enable: - // not supported in DX8 - break; - - case StencilRenderStates::SRS_front_comparison_function: - device->SetRenderState (D3DRS_STENCILFUNC, dx_stencil_comparison_function_array [render_state_value]); - break; - case StencilRenderStates::SRS_front_stencil_fail_operation: - device->SetRenderState (D3DRS_STENCILFAIL, dx_stencil_operation_array [render_state_value]); - break; - case StencilRenderStates::SRS_front_stencil_pass_z_fail_operation: - device->SetRenderState (D3DRS_STENCILZFAIL, dx_stencil_operation_array [render_state_value]); - break; - case StencilRenderStates::SRS_front_stencil_pass_z_pass_operation: - device->SetRenderState (D3DRS_STENCILPASS, dx_stencil_operation_array [render_state_value]); - break; - - case StencilRenderStates::SRS_reference: - device->SetRenderState (D3DRS_STENCILREF, render_state_value); - break; - - case StencilRenderStates::SRS_read_mask: - device->SetRenderState (D3DRS_STENCILMASK, render_state_value); - break; - case StencilRenderStates::SRS_write_mask: - device->SetRenderState (D3DRS_STENCILWRITEMASK, render_state_value); - break; - - case StencilRenderStates::SRS_back_comparison_function: - // not supported in DX8 - break; - case StencilRenderStates::SRS_back_stencil_fail_operation: - // not supported in DX8 - break; - case StencilRenderStates::SRS_back_stencil_pass_z_fail_operation: - // not supported in DX8 - break; - case StencilRenderStates::SRS_back_stencil_pass_z_pass_operation: - // not supported in DX8 - break; - - default: - break; - } -} - -void dx_set_stencil_functions (StencilRenderStates *stencil_render_states) { - if (stencil_render_states) { - StencilRenderStates::StencilRenderState stencil_render_state; - - for (stencil_render_state = StencilRenderStates::SRS_first; stencil_render_state < StencilRenderStates::SRS_total; stencil_render_state = (StencilRenderStates::StencilRenderState) ((int) stencil_render_state + 1)) { - stencil_render_states -> set_stencil_function (stencil_render_state, dx_stencil_function); - } - } -} - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian8::do_issue_stencil // Access: Protected @@ -4421,48 +4337,56 @@ void dx_set_stencil_functions (StencilRenderStates *stencil_render_states) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: do_issue_stencil() { - if (!_supports_stencil) { return; } - StencilRenderStates *stencil_render_states; - const StencilAttrib *stencil = DCAST(StencilAttrib, _target_rs->get_attrib_def(StencilAttrib::get_class_slot())); - stencil_render_states = this -> _stencil_render_states; - if (stencil && stencil_render_states) { + const StencilAttrib *stencil = DCAST(StencilAttrib, _target_rs->get_attrib(StencilAttrib::get_class_slot())); - if (dxgsg8_cat.is_debug()) { + if (stencil != (const StencilAttrib *)NULL) { + // DEBUG + if (false) { dxgsg8_cat.debug() << "STENCIL STATE CHANGE\n"; dxgsg8_cat.debug() << "\n" - << "SRS_front_enable " << stencil -> get_render_state (StencilAttrib::SRS_front_enable) << "\n" - << "SRS_front_comparison_function " << stencil -> get_render_state (StencilAttrib::SRS_front_comparison_function) << "\n" - << "SRS_front_stencil_fail_operation " << stencil -> get_render_state (StencilAttrib::SRS_front_stencil_fail_operation) << "\n" - << "SRS_front_stencil_pass_z_fail_operation " << stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_fail_operation) << "\n" - << "SRS_front_stencil_pass_z_pass_operation " << stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_pass_operation) << "\n" - << "SRS_reference " << stencil -> get_render_state (StencilAttrib::SRS_reference) << "\n" - << "SRS_read_mask " << stencil -> get_render_state (StencilAttrib::SRS_read_mask) << "\n" - << "SRS_write_mask " << stencil -> get_render_state (StencilAttrib::SRS_write_mask) << "\n"; + << "SRS_front_comparison_function " << stencil->get_render_state(StencilAttrib::SRS_front_comparison_function) << "\n" + << "SRS_front_stencil_fail_operation " << stencil->get_render_state(StencilAttrib::SRS_front_stencil_fail_operation) << "\n" + << "SRS_front_stencil_pass_z_fail_operation " << stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation) << "\n" + << "SRS_front_stencil_pass_z_pass_operation " << stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation) << "\n" + << "SRS_reference " << stencil->get_render_state(StencilAttrib::SRS_reference) << "\n" + << "SRS_read_mask " << stencil->get_render_state(StencilAttrib::SRS_read_mask) << "\n" + << "SRS_write_mask " << stencil->get_render_state(StencilAttrib::SRS_write_mask) << "\n"; } - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_enable, stencil -> get_render_state (StencilAttrib::SRS_front_enable)); - if (stencil -> get_render_state (StencilAttrib::SRS_front_enable)) { - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_comparison_function, stencil -> get_render_state (StencilAttrib::SRS_front_comparison_function)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_stencil_fail_operation, stencil -> get_render_state (StencilAttrib::SRS_front_stencil_fail_operation)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_stencil_pass_z_fail_operation, stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_fail_operation)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_stencil_pass_z_pass_operation, stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_pass_operation)); + unsigned int front_compare; + front_compare = stencil->get_render_state(StencilAttrib::SRS_front_comparison_function); + if (front_compare != RenderAttrib::M_none) { + set_render_state(D3DRS_STENCILENABLE, TRUE); + set_render_state(D3DRS_STENCILFUNC, dx_stencil_comparison_function_array[front_compare]); + set_render_state(D3DRS_STENCILFAIL, dx_stencil_operation_array[ + stencil->get_render_state(StencilAttrib::SRS_front_stencil_fail_operation)]); + set_render_state(D3DRS_STENCILZFAIL, dx_stencil_operation_array[ + stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation)]); + set_render_state(D3DRS_STENCILPASS, dx_stencil_operation_array[ + stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation)]); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_reference, stencil -> get_render_state (StencilAttrib::SRS_reference)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_read_mask, stencil -> get_render_state (StencilAttrib::SRS_read_mask)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_write_mask, stencil -> get_render_state (StencilAttrib::SRS_write_mask)); - } - } - else { - - if (dxgsg8_cat.is_debug()) { - dxgsg8_cat.debug() << "STENCIL STATE CHANGE TO OFF \n"; + set_render_state(D3DRS_STENCILREF, stencil->get_render_state(StencilAttrib::SRS_reference)); + set_render_state(D3DRS_STENCILMASK, stencil->get_render_state(StencilAttrib::SRS_read_mask)); + set_render_state(D3DRS_STENCILWRITEMASK, stencil->get_render_state(StencilAttrib::SRS_write_mask)); + } else { + set_render_state(D3DRS_STENCILENABLE, FALSE); } - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_enable, 0); + if (stencil->get_render_state(StencilAttrib::SRS_clear)) { + _d3d_device->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 0.0f, stencil->get_render_state(StencilAttrib::SRS_clear_value)); + } + + } else { + // DEBUG + if (false) { + dxgsg8_cat.debug() << "STENCIL STATE CHANGE TO OFF\n"; + } + + set_render_state(D3DRS_STENCILENABLE, FALSE); } } diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index de152695ce..40b19a40ec 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -2769,9 +2769,6 @@ reset() { PRINT_REFCNT(dxgsg9, _d3d_device); - void dx_set_stencil_functions (StencilRenderStates *stencil_render_states); - dx_set_stencil_functions (_stencil_render_states); - // Now that the GSG has been initialized, make it available for // optimizations. add_gsg(this); @@ -5261,9 +5258,7 @@ check_dx_allocation (HRESULT result, int allocation_size, int attempts) //////////////////////////////////////////////////////////////////// // DX stencil code section //////////////////////////////////////////////////////////////////// - -static int dx_stencil_comparison_function_array [ ] = -{ +static int dx_stencil_comparison_function_array[] = { D3DCMP_NEVER, D3DCMP_LESS, D3DCMP_EQUAL, @@ -5274,8 +5269,7 @@ static int dx_stencil_comparison_function_array [ ] = D3DCMP_ALWAYS, }; -static int dx_stencil_operation_array [ ] = -{ +static int dx_stencil_operation_array[] = { D3DSTENCILOP_KEEP, D3DSTENCILOP_ZERO, D3DSTENCILOP_REPLACE, @@ -5287,93 +5281,6 @@ static int dx_stencil_operation_array [ ] = D3DSTENCILOP_DECRSAT, }; -void dx_stencil_function (StencilRenderStates::StencilRenderState stencil_render_state, StencilRenderStates *stencil_render_states) { - StencilType render_state_value; - - DXGraphicsStateGuardian9 *gsg; - - gsg = (DXGraphicsStateGuardian9 *) stencil_render_states -> _gsg; - - render_state_value = stencil_render_states -> get_stencil_render_state (stencil_render_state); - - // DEBUG - if (false) { - dxgsg9_cat.debug() - << "SRS: " << StencilAttrib::stencil_render_state_name_array [stencil_render_state] << ", " << render_state_value << "\n"; - } - - switch (stencil_render_state) - { - case StencilRenderStates::SRS_front_enable: - gsg -> set_render_state (D3DRS_STENCILENABLE, render_state_value); - break; - - case StencilRenderStates::SRS_back_enable: - if (gsg -> get_supports_two_sided_stencil()) { - gsg -> set_render_state (D3DRS_TWOSIDEDSTENCILMODE, render_state_value); - } - break; - - case StencilRenderStates::SRS_front_comparison_function: - gsg -> set_render_state (D3DRS_STENCILFUNC, dx_stencil_comparison_function_array [render_state_value]); - break; - case StencilRenderStates::SRS_front_stencil_fail_operation: - gsg -> set_render_state (D3DRS_STENCILFAIL, dx_stencil_operation_array [render_state_value]); - break; - case StencilRenderStates::SRS_front_stencil_pass_z_fail_operation: - gsg -> set_render_state (D3DRS_STENCILZFAIL, dx_stencil_operation_array [render_state_value]); - break; - case StencilRenderStates::SRS_front_stencil_pass_z_pass_operation: - gsg -> set_render_state (D3DRS_STENCILPASS, dx_stencil_operation_array [render_state_value]); - break; - - case StencilRenderStates::SRS_reference: - gsg -> set_render_state (D3DRS_STENCILREF, render_state_value); - break; - - case StencilRenderStates::SRS_read_mask: - gsg -> set_render_state (D3DRS_STENCILMASK, render_state_value); - break; - case StencilRenderStates::SRS_write_mask: - gsg -> set_render_state (D3DRS_STENCILWRITEMASK, render_state_value); - break; - - case StencilRenderStates::SRS_back_comparison_function: - if (gsg -> get_supports_two_sided_stencil()) { - gsg -> set_render_state (D3DRS_CCW_STENCILFUNC, dx_stencil_comparison_function_array [render_state_value]); - } - break; - case StencilRenderStates::SRS_back_stencil_fail_operation: - if (gsg -> get_supports_two_sided_stencil()) { - gsg -> set_render_state (D3DRS_CCW_STENCILFAIL, dx_stencil_operation_array [render_state_value]); - } - break; - case StencilRenderStates::SRS_back_stencil_pass_z_fail_operation: - if (gsg -> get_supports_two_sided_stencil()) { - gsg -> set_render_state (D3DRS_CCW_STENCILZFAIL, dx_stencil_operation_array [render_state_value]); - } - break; - case StencilRenderStates::SRS_back_stencil_pass_z_pass_operation: - if (gsg -> get_supports_two_sided_stencil()) { - gsg -> set_render_state (D3DRS_CCW_STENCILPASS, dx_stencil_operation_array [render_state_value]); - } - break; - - default: - break; - } -} - -void dx_set_stencil_functions (StencilRenderStates *stencil_render_states) { - if (stencil_render_states) { - StencilRenderStates::StencilRenderState stencil_render_state; - - for (stencil_render_state = StencilRenderStates::SRS_first; stencil_render_state < StencilRenderStates::SRS_total; stencil_render_state = (StencilRenderStates::StencilRenderState) ((int) stencil_render_state + 1)) { - stencil_render_states -> set_stencil_function (stencil_render_state, dx_stencil_function); - } - } -} - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian9::do_issue_stencil // Access: Protected @@ -5385,70 +5292,84 @@ do_issue_stencil() { return; } - StencilRenderStates *stencil_render_states; - const StencilAttrib *stencil = DCAST(StencilAttrib, _target_rs->get_attrib_def(StencilAttrib::get_class_slot())); - stencil_render_states = this -> _stencil_render_states; - if (stencil && stencil_render_states) { + const StencilAttrib *stencil = DCAST(StencilAttrib, _target_rs->get_attrib(StencilAttrib::get_class_slot())); + if (stencil != (const StencilAttrib *)NULL) { // DEBUG if (false) { dxgsg9_cat.debug() << "STENCIL STATE CHANGE\n"; dxgsg9_cat.debug() << "\n" - << "SRS_front_enable " << stencil -> get_render_state (StencilAttrib::SRS_front_enable) << "\n" - << "SRS_back_enable " << stencil -> get_render_state (StencilAttrib::SRS_back_enable) << "\n" - << "SRS_front_comparison_function " << stencil -> get_render_state (StencilAttrib::SRS_front_comparison_function) << "\n" - << "SRS_front_stencil_fail_operation " << stencil -> get_render_state (StencilAttrib::SRS_front_stencil_fail_operation) << "\n" - << "SRS_front_stencil_pass_z_fail_operation " << stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_fail_operation) << "\n" - << "SRS_front_stencil_pass_z_pass_operation " << stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_pass_operation) << "\n" - << "SRS_reference " << stencil -> get_render_state (StencilAttrib::SRS_reference) << "\n" - << "SRS_read_mask " << stencil -> get_render_state (StencilAttrib::SRS_read_mask) << "\n" - << "SRS_write_mask " << stencil -> get_render_state (StencilAttrib::SRS_write_mask) << "\n" - << "SRS_back_comparison_function " << stencil -> get_render_state (StencilAttrib::SRS_back_comparison_function) << "\n" - << "SRS_back_stencil_fail_operation " << stencil -> get_render_state (StencilAttrib::SRS_back_stencil_fail_operation) << "\n" - << "SRS_back_stencil_pass_z_fail_operation " << stencil -> get_render_state (StencilAttrib::SRS_back_stencil_pass_z_fail_operation) << "\n" - << "SRS_back_stencil_pass_z_pass_operation " << stencil -> get_render_state (StencilAttrib::SRS_back_stencil_pass_z_pass_operation) << "\n"; + << "SRS_front_comparison_function " << stencil->get_render_state(StencilAttrib::SRS_front_comparison_function) << "\n" + << "SRS_front_stencil_fail_operation " << stencil->get_render_state(StencilAttrib::SRS_front_stencil_fail_operation) << "\n" + << "SRS_front_stencil_pass_z_fail_operation " << stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation) << "\n" + << "SRS_front_stencil_pass_z_pass_operation " << stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation) << "\n" + << "SRS_reference " << stencil->get_render_state(StencilAttrib::SRS_reference) << "\n" + << "SRS_read_mask " << stencil->get_render_state(StencilAttrib::SRS_read_mask) << "\n" + << "SRS_write_mask " << stencil->get_render_state(StencilAttrib::SRS_write_mask) << "\n" + << "SRS_back_comparison_function " << stencil->get_render_state(StencilAttrib::SRS_back_comparison_function) << "\n" + << "SRS_back_stencil_fail_operation " << stencil->get_render_state(StencilAttrib::SRS_back_stencil_fail_operation) << "\n" + << "SRS_back_stencil_pass_z_fail_operation " << stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation) << "\n" + << "SRS_back_stencil_pass_z_pass_operation " << stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation) << "\n"; } - bool on; + bool on = false; - on = false; - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_enable, stencil -> get_render_state (StencilAttrib::SRS_front_enable)); - if (stencil -> get_render_state (StencilAttrib::SRS_front_enable)) { - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_comparison_function, stencil -> get_render_state (StencilAttrib::SRS_front_comparison_function)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_stencil_fail_operation, stencil -> get_render_state (StencilAttrib::SRS_front_stencil_fail_operation)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_stencil_pass_z_fail_operation, stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_fail_operation)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_stencil_pass_z_pass_operation, stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_pass_operation)); + unsigned int front_compare; + front_compare = stencil->get_render_state(StencilAttrib::SRS_front_comparison_function); + + if (front_compare != RenderAttrib::M_none) { + set_render_state(D3DRS_STENCILENABLE, TRUE); + set_render_state(D3DRS_STENCILFUNC, dx_stencil_comparison_function_array[front_compare]); + set_render_state(D3DRS_STENCILFAIL, dx_stencil_operation_array[ + stencil->get_render_state(StencilAttrib::SRS_front_stencil_fail_operation)]); + set_render_state(D3DRS_STENCILZFAIL, dx_stencil_operation_array[ + stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation)]); + set_render_state(D3DRS_STENCILPASS, dx_stencil_operation_array[ + stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation)]); on = true; + } else { + set_render_state(D3DRS_STENCILENABLE, FALSE); } - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_enable, stencil -> get_render_state (StencilAttrib::SRS_back_enable)); - if (stencil -> get_render_state (StencilAttrib::SRS_back_enable)) { - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_comparison_function, stencil -> get_render_state (StencilAttrib::SRS_back_comparison_function)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_stencil_fail_operation, stencil -> get_render_state (StencilAttrib::SRS_back_stencil_fail_operation)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_stencil_pass_z_fail_operation, stencil -> get_render_state (StencilAttrib::SRS_back_stencil_pass_z_fail_operation)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_stencil_pass_z_pass_operation, stencil -> get_render_state (StencilAttrib::SRS_back_stencil_pass_z_pass_operation)); - on = true; + if (_supports_two_sided_stencil) { + unsigned int back_compare; + back_compare = stencil->get_render_state(StencilAttrib::SRS_back_comparison_function); + + if (back_compare != RenderAttrib::M_none) { + set_render_state(D3DRS_TWOSIDEDSTENCILMODE, TRUE); + set_render_state(D3DRS_CCW_STENCILFUNC, dx_stencil_comparison_function_array[back_compare]); + set_render_state(D3DRS_CCW_STENCILFAIL, dx_stencil_operation_array[ + stencil->get_render_state(StencilAttrib::SRS_back_stencil_fail_operation)]); + set_render_state(D3DRS_CCW_STENCILZFAIL, dx_stencil_operation_array[ + stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation)]); + set_render_state(D3DRS_CCW_STENCILPASS, dx_stencil_operation_array[ + stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation)]); + on = true; + } else { + set_render_state(D3DRS_TWOSIDEDSTENCILMODE, FALSE); + } } if (on) { - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_reference, stencil -> get_render_state (StencilAttrib::SRS_reference)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_read_mask, stencil -> get_render_state (StencilAttrib::SRS_read_mask)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_write_mask, stencil -> get_render_state (StencilAttrib::SRS_write_mask)); + set_render_state(D3DRS_STENCILREF, stencil->get_render_state(StencilAttrib::SRS_reference)); + set_render_state(D3DRS_STENCILMASK, stencil->get_render_state(StencilAttrib::SRS_read_mask)); + set_render_state(D3DRS_STENCILWRITEMASK, stencil->get_render_state(StencilAttrib::SRS_write_mask)); } - if (stencil -> get_render_state (StencilAttrib::SRS_clear)) { - _d3d_device->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 0.0f, stencil -> get_render_state (StencilAttrib::SRS_clear_value)); + if (stencil->get_render_state(StencilAttrib::SRS_clear)) { + _d3d_device->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 0.0f, stencil->get_render_state(StencilAttrib::SRS_clear_value)); } - } - else { + } else { // DEBUG if (false) { - dxgsg9_cat.debug() << "STENCIL STATE CHANGE TO OFF \n"; + dxgsg9_cat.debug() << "STENCIL STATE CHANGE TO OFF\n"; } - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_enable, 0); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_enable, 0); + set_render_state(D3DRS_STENCILENABLE, FALSE); + if (_supports_two_sided_stencil) { + set_render_state(D3DRS_TWOSIDEDSTENCILMODE, FALSE); + } } } diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 6adcb3b4c0..cdd186cef4 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -337,11 +337,6 @@ CLP(GraphicsStateGuardian):: } close_gsg(); - - if (_stencil_render_states) { - delete _stencil_render_states; - _stencil_render_states = 0; - } } //////////////////////////////////////////////////////////////////// @@ -2103,9 +2098,6 @@ reset() { report_my_gl_errors(); - void gl_set_stencil_functions (StencilRenderStates *stencil_render_states); - gl_set_stencil_functions(_stencil_render_states); - #if defined(HAVE_CG) && !defined(OPENGLES) typedef struct { @@ -11511,18 +11503,7 @@ bind_fbo(GLuint fbo) { // GL stencil code section //////////////////////////////////////////////////////////////////// -static int gl_stencil_comparison_function_array [ ] = { - GL_NEVER, - GL_LESS, - GL_EQUAL, - GL_LEQUAL, - GL_GREATER, - GL_NOTEQUAL, - GL_GEQUAL, - GL_ALWAYS, -}; - -static int gl_stencil_operations_array [ ] = { +static int gl_stencil_operations_array[] = { GL_KEEP, GL_ZERO, GL_REPLACE, @@ -11539,144 +11520,6 @@ static int gl_stencil_operations_array [ ] = { GL_DECR, }; -void __glActiveStencilFace (GraphicsStateGuardian *gsg, GLenum face) { - CLP(GraphicsStateGuardian) *glgsg; - - glgsg = (CLP(GraphicsStateGuardian) *) gsg; - if (gsg -> get_supports_two_sided_stencil ( ) && - glgsg -> _glActiveStencilFaceEXT) { - if (face == GL_FRONT) { - // glActiveStencilFaceEXT (GL_FRONT); - glgsg -> _glActiveStencilFaceEXT (GL_FRONT); - } - else { - // glActiveStencilFaceEXT (GL_BACK); - glgsg -> _glActiveStencilFaceEXT (GL_BACK); - } - } -} - -void gl_front_stencil_function (StencilRenderStates::StencilRenderState stencil_render_state, StencilRenderStates *stencil_render_states) { - - __glActiveStencilFace (stencil_render_states -> _gsg, GL_FRONT); - glStencilFunc - ( - gl_stencil_comparison_function_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_front_comparison_function)], - stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_reference), - stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_read_mask) - ); -} -void gl_front_stencil_operation (StencilRenderStates::StencilRenderState stencil_render_state, StencilRenderStates *stencil_render_states) { - __glActiveStencilFace (stencil_render_states -> _gsg, GL_FRONT); - glStencilOp - ( - gl_stencil_operations_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_front_stencil_fail_operation)], - gl_stencil_operations_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_front_stencil_pass_z_fail_operation)], - gl_stencil_operations_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_front_stencil_pass_z_pass_operation)] - ); -} - -void gl_back_stencil_function (StencilRenderStates::StencilRenderState stencil_render_state, StencilRenderStates *stencil_render_states) { - - bool supports_two_sided_stencil; - - supports_two_sided_stencil = stencil_render_states -> _gsg -> get_supports_two_sided_stencil ( ); - if (supports_two_sided_stencil) { - __glActiveStencilFace (stencil_render_states -> _gsg, GL_BACK); - glStencilFunc - ( - gl_stencil_comparison_function_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_back_comparison_function)], - stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_reference), - stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_read_mask) - ); - } -} - -void gl_back_stencil_operation (StencilRenderStates::StencilRenderState stencil_render_state, StencilRenderStates *stencil_render_states) { - - bool supports_two_sided_stencil; - - supports_two_sided_stencil = stencil_render_states -> _gsg -> get_supports_two_sided_stencil ( ); - if (supports_two_sided_stencil) { - __glActiveStencilFace (stencil_render_states -> _gsg, GL_BACK); - glStencilOp - ( - gl_stencil_operations_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_back_stencil_fail_operation)], - gl_stencil_operations_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_back_stencil_pass_z_fail_operation)], - gl_stencil_operations_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_back_stencil_pass_z_pass_operation)] - ); - } -} - -void gl_front_back_stencil_function (StencilRenderStates::StencilRenderState stencil_render_state, StencilRenderStates *stencil_render_states) { - gl_front_stencil_function (stencil_render_state, stencil_render_states); - gl_back_stencil_function (stencil_render_state, stencil_render_states); -} - -void gl_stencil_function (StencilRenderStates::StencilRenderState stencil_render_state, StencilRenderStates *stencil_render_states) { - - StencilType render_state_value; - bool supports_two_sided_stencil; - - supports_two_sided_stencil = stencil_render_states -> _gsg -> get_supports_two_sided_stencil ( ); - - render_state_value = stencil_render_states -> get_stencil_render_state (stencil_render_state); - switch (stencil_render_state) { - case StencilRenderStates::SRS_front_enable: - if (render_state_value) { - glEnable (GL_STENCIL_TEST); - } - else { - glDisable (GL_STENCIL_TEST); - } - break; -#ifndef OPENGLES - case StencilRenderStates::SRS_back_enable: - if (supports_two_sided_stencil) { - if (render_state_value) { - glEnable (GL_STENCIL_TEST_TWO_SIDE_EXT); - } - else { - glDisable (GL_STENCIL_TEST_TWO_SIDE_EXT); - } - } - break; -#endif - - case StencilRenderStates::SRS_write_mask: - glStencilMask (render_state_value); - break; - - default: - break; - } -} - -void gl_set_stencil_functions (StencilRenderStates *stencil_render_states) { - - if (stencil_render_states) { - stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_front_enable, gl_stencil_function); - stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_back_enable, gl_stencil_function); - - stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_front_comparison_function, gl_front_stencil_function); - stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_front_stencil_fail_operation, gl_front_stencil_operation); - stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_front_stencil_pass_z_fail_operation, gl_front_stencil_operation); - stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_front_stencil_pass_z_pass_operation, gl_front_stencil_operation); - - // GL seems to support different read masks and/or reference values for front and back, but DX does not. - // This needs to be cross-platform so do it the DX way by setting the same read mask and reference for both front and back. - stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_reference, gl_front_back_stencil_function); - stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_read_mask, gl_front_back_stencil_function); - - stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_write_mask, gl_stencil_function); - - stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_back_comparison_function, gl_back_stencil_function); - stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_back_stencil_fail_operation, gl_back_stencil_operation); - stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_back_stencil_pass_z_fail_operation, gl_back_stencil_operation); - stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_back_stencil_pass_z_pass_operation, gl_back_stencil_operation); - } -} - //////////////////////////////////////////////////////////////////// // Function: GLGraphicsStateGuardian::do_issue_stencil // Access: Protected @@ -11688,72 +11531,84 @@ do_issue_stencil() { return; } - const StencilAttrib *stencil = DCAST(StencilAttrib, _target_rs->get_attrib_def(StencilAttrib::get_class_slot())); - - StencilRenderStates *stencil_render_states; - stencil_render_states = this -> _stencil_render_states; - if (stencil && stencil_render_states) { + const StencilAttrib *stencil = DCAST(StencilAttrib, _target_rs->get_attrib(StencilAttrib::get_class_slot())); + if (stencil != (const StencilAttrib *)NULL) { // DEBUG if (false) { GLCAT.debug() << "STENCIL STATE CHANGE\n"; GLCAT.debug() << "\n" - << "SRS_front_enable " << (int)stencil -> get_render_state (StencilAttrib::SRS_front_enable) << "\n" - << "SRS_back_enable " << (int)stencil -> get_render_state (StencilAttrib::SRS_back_enable) << "\n" - << "SRS_front_comparison_function " << (int)stencil -> get_render_state (StencilAttrib::SRS_front_comparison_function) << "\n" - << "SRS_front_stencil_fail_operation " << (int)stencil -> get_render_state (StencilAttrib::SRS_front_stencil_fail_operation) << "\n" - << "SRS_front_stencil_pass_z_fail_operation " << (int)stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_fail_operation) << "\n" - << "SRS_front_stencil_pass_z_pass_operation " << (int)stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_pass_operation) << "\n" - << "SRS_reference " << (int)stencil -> get_render_state (StencilAttrib::SRS_reference) << "\n" - << "SRS_read_mask " << (int)stencil -> get_render_state (StencilAttrib::SRS_read_mask) << "\n" - << "SRS_write_mask " << (int)stencil -> get_render_state (StencilAttrib::SRS_write_mask) << "\n" - << "SRS_back_comparison_function " << (int)stencil -> get_render_state (StencilAttrib::SRS_back_comparison_function) << "\n" - << "SRS_back_stencil_fail_operation " << (int)stencil -> get_render_state (StencilAttrib::SRS_back_stencil_fail_operation) << "\n" - << "SRS_back_stencil_pass_z_fail_operation " << (int)stencil -> get_render_state (StencilAttrib::SRS_back_stencil_pass_z_fail_operation) << "\n" - << "SRS_back_stencil_pass_z_pass_operation " << (int)stencil -> get_render_state (StencilAttrib::SRS_back_stencil_pass_z_pass_operation) << "\n"; + << "SRS_front_comparison_function " << (int)stencil->get_render_state(StencilAttrib::SRS_front_comparison_function) << "\n" + << "SRS_front_stencil_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_front_stencil_fail_operation) << "\n" + << "SRS_front_stencil_pass_z_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation) << "\n" + << "SRS_front_stencil_pass_z_pass_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation) << "\n" + << "SRS_reference " << (int)stencil->get_render_state(StencilAttrib::SRS_reference) << "\n" + << "SRS_read_mask " << (int)stencil->get_render_state(StencilAttrib::SRS_read_mask) << "\n" + << "SRS_write_mask " << (int)stencil->get_render_state(StencilAttrib::SRS_write_mask) << "\n" + << "SRS_back_comparison_function " << (int)stencil->get_render_state(StencilAttrib::SRS_back_comparison_function) << "\n" + << "SRS_back_stencil_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_fail_operation) << "\n" + << "SRS_back_stencil_pass_z_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation) << "\n" + << "SRS_back_stencil_pass_z_pass_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation) << "\n"; } - { - bool on; + if (_supports_two_sided_stencil) { + //TODO: add support for OpenGL 2.0-style glStencilFuncSeparate. + unsigned int back_compare; + back_compare = stencil->get_render_state(StencilAttrib::SRS_back_comparison_function); - on = false; - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_enable, stencil -> get_render_state (StencilAttrib::SRS_front_enable)); - if (stencil -> get_render_state (StencilAttrib::SRS_front_enable)) { - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_comparison_function, stencil -> get_render_state (StencilAttrib::SRS_front_comparison_function)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_stencil_fail_operation, stencil -> get_render_state (StencilAttrib::SRS_front_stencil_fail_operation)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_stencil_pass_z_fail_operation, stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_fail_operation)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_stencil_pass_z_pass_operation, stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_pass_operation)); - on = true; + if (back_compare != RenderAttrib::M_none) { + glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); + _glActiveStencilFaceEXT(GL_BACK); + + glStencilFunc( + PANDA_TO_GL_COMPAREFUNC(back_compare), + stencil->get_render_state(StencilAttrib::SRS_reference), + stencil->get_render_state(StencilAttrib::SRS_read_mask)); + + glStencilOp( + gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_back_stencil_fail_operation)], + gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation)], + gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation)] + ); + glStencilMask(stencil->get_render_state(StencilAttrib::SRS_write_mask)); + } else { + glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); } - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_enable, stencil -> get_render_state (StencilAttrib::SRS_back_enable)); - if (stencil -> get_render_state (StencilAttrib::SRS_back_enable)) { - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_comparison_function, stencil -> get_render_state (StencilAttrib::SRS_back_comparison_function)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_stencil_fail_operation, stencil -> get_render_state (StencilAttrib::SRS_back_stencil_fail_operation)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_stencil_pass_z_fail_operation, stencil -> get_render_state (StencilAttrib::SRS_back_stencil_pass_z_fail_operation)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_stencil_pass_z_pass_operation, stencil -> get_render_state (StencilAttrib::SRS_back_stencil_pass_z_pass_operation)); - on = true; - } - - if (on) { - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_reference, stencil -> get_render_state (StencilAttrib::SRS_reference)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_read_mask, stencil -> get_render_state (StencilAttrib::SRS_read_mask)); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_write_mask, stencil -> get_render_state (StencilAttrib::SRS_write_mask)); - } + _glActiveStencilFaceEXT(GL_FRONT); } - if (stencil -> get_render_state (StencilAttrib::SRS_clear)) { - GLbitfield mask = 0; + unsigned int front_compare; + front_compare = stencil->get_render_state(StencilAttrib::SRS_front_comparison_function); + if (front_compare != RenderAttrib::M_none) { + glEnable(GL_STENCIL_TEST); + + glStencilFunc( + PANDA_TO_GL_COMPAREFUNC(front_compare), + stencil->get_render_state(StencilAttrib::SRS_reference), + stencil->get_render_state(StencilAttrib::SRS_read_mask)); + + glStencilOp( + gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_front_stencil_fail_operation)], + gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation)], + gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation)] + ); + glStencilMask(stencil->get_render_state(StencilAttrib::SRS_write_mask)); + } else { + glDisable(GL_STENCIL_TEST); + } + + if (stencil->get_render_state(StencilAttrib::SRS_clear)) { // clear stencil buffer - glClearStencil(stencil -> get_render_state (StencilAttrib::SRS_clear_value)); - mask |= GL_STENCIL_BUFFER_BIT; - glClear(mask); + glClearStencil(stencil->get_render_state(StencilAttrib::SRS_clear_value)); + glClear(GL_STENCIL_BUFFER_BIT); + } + } else { + glDisable(GL_STENCIL_TEST); + if (_supports_two_sided_stencil) { + glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); } - } - else { - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_enable, 0); - stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_enable, 0); } } diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index d417221be8..03262e26c7 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -37,7 +37,7 @@ #include "thread.h" #include "renderAttribRegistry.h" #include "py_panda.h" - + LightReMutex *RenderState::_states_lock = NULL; RenderState::States *RenderState::_states = NULL; CPT(RenderState) RenderState::_empty_state; @@ -67,7 +67,7 @@ TypeHandle RenderState::_type_handle; // spurious warning if all constructors are private. //////////////////////////////////////////////////////////////////// RenderState:: -RenderState() : +RenderState() : _flags(0), _auto_shader_state(NULL), _lock("RenderState") @@ -230,6 +230,31 @@ compare_sort(const RenderState &other) const { return 0; } +//////////////////////////////////////////////////////////////////// +// Function: RenderState::compare_mask +// Access: Published +// Description: This version of compare_to takes a slot mask that +// indicates which attributes to include in the +// comparison. Unlike compare_to, this method +// compares the attributes by pointer. +//////////////////////////////////////////////////////////////////// +int RenderState:: +compare_mask(const RenderState &other, SlotMask compare_mask) const { + SlotMask mask = (_filled_slots | other._filled_slots) & compare_mask; + int slot = mask.get_lowest_on_bit(); + while (slot >= 0) { + const RenderAttrib *a = _attributes[slot]._attrib; + const RenderAttrib *b = other._attributes[slot]._attrib; + if (a != b) { + return a < b ? -1 : 1; + } + mask.clear_bit(slot); + slot = mask.get_lowest_on_bit(); + } + + return 0; +} + //////////////////////////////////////////////////////////////////// // Function: RenderState::cull_callback // Access: Published @@ -464,7 +489,7 @@ compose(const RenderState *other) const { // to decrement it again later, when the composition entry is // removed from the cache. result->cache_ref(); - + // (If the result was just this again, we still store the // result, but we don't increment the reference count, since // that would be a self-referential leak.) @@ -558,7 +583,7 @@ invert_compose(const RenderState *other) const { // to decrement it again later, when the composition entry is // removed from the cache. result->cache_ref(); - + // (If the result was just this again, we still store the // result, but we don't increment the reference count, since // that would be a self-referential leak.) @@ -759,7 +784,7 @@ get_auto_shader_state() const { //////////////////////////////////////////////////////////////////// // Function: RenderState::output // Access: Published -// Description: +// Description: //////////////////////////////////////////////////////////////////// void RenderState:: output(ostream &out) const { @@ -789,12 +814,12 @@ output(ostream &out) const { //////////////////////////////////////////////////////////////////// // Function: RenderState::write // Access: Published -// Description: +// Description: //////////////////////////////////////////////////////////////////// void RenderState:: write(ostream &out, int indent_level) const { if (is_empty()) { - indent(out, indent_level) + indent(out, indent_level) << "(empty)\n"; } @@ -804,7 +829,7 @@ write(ostream &out, int indent_level) const { const Attribute &attrib = _attributes[slot]; nassertv(attrib._attrib != (RenderAttrib *)NULL); attrib._attrib->write(out, indent_level); - + mask.clear_bit(slot); slot = mask.get_lowest_on_bit(); } @@ -927,7 +952,7 @@ get_num_unused_states() { if (pgraph_cat.is_debug()) { pgraph_cat.debug() - << "Unused state: " << (void *)state << ":" + << "Unused state: " << (void *)state << ":" << state->get_ref_count() << " =\n"; state->write(pgraph_cat.debug(false), 2); } @@ -1062,7 +1087,7 @@ garbage_collect() { } num_this_pass = min(num_this_pass, size); int stop_at_element = (_garbage_index + num_this_pass) % size; - + int num_elements = 0; int si = _garbage_index; do { @@ -1092,7 +1117,7 @@ garbage_collect() { state->cache_unref(); delete state; } - } + } si = (si + 1) % size; } while (si != stop_at_element); @@ -1193,7 +1218,7 @@ list_cycles(ostream &out) { if (r_detect_reverse_cycles(state, state, 1, _last_cycle_detect, &cycle_desc)) { // This state begins a cycle. CompositionCycleDesc::iterator csi; - + out << "\nReverse cycle detected of length " << cycle_desc.size() + 1 << ":\n" << "state "; for (csi = cycle_desc.begin(); csi != cycle_desc.end(); ++csi) { @@ -1209,7 +1234,7 @@ list_cycles(ostream &out) { out << (void *)state << ":" << state->get_ref_count() << " =\n"; state->write(out, 2); - + cycle_desc.clear(); } } @@ -1272,7 +1297,7 @@ validate_states() { pgraph_cat.error() << "RenderState::_states cache is invalid!\n"; return false; - } + } int size = _states->get_size(); int si = 0; @@ -1447,7 +1472,7 @@ do_calc_auto_shader_state() { state->_attributes[slot].set(new_attrib, 0); state->_filled_slots.set_bit(slot); } - + mask.clear_bit(slot); slot = mask.get_lowest_on_bit(); } @@ -1455,7 +1480,7 @@ do_calc_auto_shader_state() { return return_new(state); } - + //////////////////////////////////////////////////////////////////// // Function: RenderState::return_new // Access: Private, Static @@ -1553,7 +1578,7 @@ return_unique(RenderState *state) { attrib._attrib = attrib._attrib->get_unique(); mask.clear_bit(slot); slot = mask.get_lowest_on_bit(); - } + } } int si = _states->find(state); @@ -1561,7 +1586,7 @@ return_unique(RenderState *state) { // There's an equivalent state already in the set. Return it. return _states->get_key(si); } - + // Not already in the set; add it. if (garbage_collect_states) { // If we'll be garbage collecting states explicitly, we'll @@ -1627,11 +1652,11 @@ do_compose(const RenderState *other) const { // with B's override value. result.set(a._attrib->compose(b._attrib), b._override); } - + mask.clear_bit(slot); slot = mask.get_lowest_on_bit(); } - + // If we have any ShaderAttrib with auto-shader enabled, // remove any shader inputs on it. This is a workaround for an // issue that makes the shader-generator regenerate the shader @@ -1640,7 +1665,7 @@ do_compose(const RenderState *other) const { if (sattrib->auto_shader()) { sattrib = DCAST(ShaderAttrib, sattrib->clear_all_shader_inputs()); } - + return return_new(new_state); } @@ -1680,7 +1705,7 @@ do_invert_compose(const RenderState *other) const { // Compose. result.set(a._attrib->invert_compose(b._attrib), 0); } - + mask.clear_bit(slot); slot = mask.get_lowest_on_bit(); } @@ -1697,7 +1722,7 @@ do_invert_compose(const RenderState *other) const { void RenderState:: detect_and_break_cycles() { PStatTimer timer(_state_break_cycles_pcollector); - + ++_last_cycle_detect; if (r_detect_cycles(this, this, 1, _last_cycle_detect, NULL)) { // Ok, we have a cycle. This will be a leak unless we break the @@ -1706,7 +1731,7 @@ detect_and_break_cycles() { pgraph_cat.debug() << "Breaking cycle involving " << (*this) << "\n"; } - + ((RenderState *)this)->remove_cache_pointers(); } else { ++_last_cycle_detect; @@ -1715,12 +1740,12 @@ detect_and_break_cycles() { pgraph_cat.debug() << "Breaking cycle involving " << (*this) << "\n"; } - + ((RenderState *)this)->remove_cache_pointers(); } } } - + //////////////////////////////////////////////////////////////////// // Function: RenderState::r_detect_cycles // Access: Private, Static @@ -1747,14 +1772,14 @@ r_detect_cycles(const RenderState *start_state, return (current_state == start_state && length > 2); } ((RenderState *)current_state)->_cycle_detect = this_seq; - + int i; int cache_size = current_state->_composition_cache.get_size(); for (i = 0; i < cache_size; ++i) { if (current_state->_composition_cache.has_element(i)) { const RenderState *result = current_state->_composition_cache.get_data(i)._result; if (result != (const RenderState *)NULL) { - if (r_detect_cycles(start_state, result, length + 1, + if (r_detect_cycles(start_state, result, length + 1, this_seq, cycle_desc)) { // Cycle detected. if (cycle_desc != (CompositionCycleDesc *)NULL) { @@ -1826,7 +1851,7 @@ r_detect_reverse_cycles(const RenderState *start_state, const RenderState *result = other->_composition_cache.get_data(oi)._result; if (result != (const RenderState *)NULL) { - if (r_detect_reverse_cycles(start_state, result, length + 1, + if (r_detect_reverse_cycles(start_state, result, length + 1, this_seq, cycle_desc)) { // Cycle detected. if (cycle_desc != (CompositionCycleDesc *)NULL) { @@ -1851,7 +1876,7 @@ r_detect_reverse_cycles(const RenderState *start_state, const RenderState *result = other->_invert_composition_cache.get_data(oi)._result; if (result != (const RenderState *)NULL) { - if (r_detect_reverse_cycles(start_state, result, length + 1, + if (r_detect_reverse_cycles(start_state, result, length + 1, this_seq, cycle_desc)) { // Cycle detected. if (cycle_desc != (CompositionCycleDesc *)NULL) { @@ -1975,11 +2000,11 @@ remove_cache_pointers() { if (oi != -1) { // Hold a copy of the other composition result, too. Composition ocomp = other->_composition_cache.get_data(oi); - + other->_composition_cache.remove_element(oi); _cache_stats.add_total_size(-1); _cache_stats.inc_dels(); - + // It's finally safe to let our held pointers go away. This may // have cascading effects as other RenderState objects are // destructed, but there will be no harm done if they destruct @@ -2071,7 +2096,7 @@ determine_bin_index() { } } } - + CullBinManager *bin_manager = CullBinManager::get_global_ptr(); _bin_index = bin_manager->find_bin(bin_name); if (_bin_index == -1) { @@ -2104,7 +2129,7 @@ determine_cull_callback() { _flags |= F_has_cull_callback; break; } - + mask.clear_bit(slot); slot = mask.get_lowest_on_bit(); } @@ -2210,7 +2235,7 @@ write_datagram(BamWriter *manager, Datagram &dg) { nassertv(attrib._attrib != (RenderAttrib *)NULL); manager->write_pointer(dg, attrib._attrib); dg.add_int32(attrib._override); - + mask.clear_bit(slot); slot = mask.get_lowest_on_bit(); } @@ -2276,7 +2301,7 @@ change_this(TypedWritable *old_ptr, BamReader *manager) { pointer->ref(); manager->register_finalize(state); } - + // We have to cast the pointer back to non-const, because the bam // reader expects that. return (RenderState *)pointer.p(); diff --git a/panda/src/pgraph/renderState.h b/panda/src/pgraph/renderState.h index 0100049c1c..9b87926045 100644 --- a/panda/src/pgraph/renderState.h +++ b/panda/src/pgraph/renderState.h @@ -67,6 +67,7 @@ public: PUBLISHED: int compare_to(const RenderState &other) const; int compare_sort(const RenderState &other) const; + int compare_mask(const RenderState &other, SlotMask compare_mask) const; INLINE size_t get_hash() const; INLINE bool is_empty() const; @@ -88,7 +89,7 @@ PUBLISHED: const RenderAttrib *attrib4, int override = 0); static CPT(RenderState) make(const RenderAttrib * const *attrib, int num_attribs, int override = 0); - + CPT(RenderState) compose(const RenderState *other) const; CPT(RenderState) invert_compose(const RenderState *other) const; @@ -152,10 +153,10 @@ PUBLISHED: INLINE int get_draw_order() const; INLINE int get_bin_index() const; int get_geom_rendering(int geom_rendering) const; - + public: static void bin_removed(int bin_index); - + INLINE static void flush_level(); private: @@ -339,7 +340,7 @@ public: protected: static TypedWritable *make_from_bam(const FactoryParams ¶ms); void fillin(DatagramIterator &scan, BamReader *manager); - + public: static TypeHandle get_class_type() { return _type_handle; diff --git a/panda/src/pgraph/stencilAttrib.I b/panda/src/pgraph/stencilAttrib.I index f1ef860cbf..39f3a7f026 100644 --- a/panda/src/pgraph/stencilAttrib.I +++ b/panda/src/pgraph/stencilAttrib.I @@ -18,6 +18,6 @@ // Description: Returns render state. //////////////////////////////////////////////////////////////////// INLINE unsigned int StencilAttrib:: -get_render_state(unsigned int render_state_identifier) const { - return _stencil_render_states [render_state_identifier]; +get_render_state(StencilRenderState render_state_identifier) const { + return _stencil_render_states[(int)render_state_identifier]; } diff --git a/panda/src/pgraph/stencilAttrib.cxx b/panda/src/pgraph/stencilAttrib.cxx index 584c809abe..07657fbf96 100644 --- a/panda/src/pgraph/stencilAttrib.cxx +++ b/panda/src/pgraph/stencilAttrib.cxx @@ -24,11 +24,8 @@ TypeHandle StencilAttrib::_type_handle; int StencilAttrib::_attrib_slot; const char *StencilAttrib:: -stencil_render_state_name_array [StencilAttrib::SRS_total] = +stencil_render_state_name_array[StencilAttrib::SRS_total] = { - "SRS_front_enable", - "SRS_back_enable", - "SRS_front_comparison_function", "SRS_front_stencil_fail_operation", "SRS_front_stencil_pass_z_fail_operation", @@ -55,11 +52,7 @@ stencil_render_state_name_array [StencilAttrib::SRS_total] = //////////////////////////////////////////////////////////////////// StencilAttrib:: StencilAttrib() { - - _stencil_render_states [SRS_front_enable] = 0; - _stencil_render_states [SRS_back_enable] = 0; - - _stencil_render_states [SRS_front_comparison_function] = SCF_always; + _stencil_render_states [SRS_front_comparison_function] = M_none; _stencil_render_states [SRS_front_stencil_fail_operation] = SO_keep; _stencil_render_states [SRS_front_stencil_pass_z_fail_operation] = SO_keep; _stencil_render_states [SRS_front_stencil_pass_z_pass_operation] = SO_keep; @@ -68,7 +61,7 @@ StencilAttrib() { _stencil_render_states [SRS_read_mask] = ~0; _stencil_render_states [SRS_write_mask] = ~0; - _stencil_render_states [SRS_back_comparison_function] = SCF_always; + _stencil_render_states [SRS_back_comparison_function] = M_none; _stencil_render_states [SRS_back_stencil_fail_operation] = SO_keep; _stencil_render_states [SRS_back_stencil_pass_z_fail_operation] = SO_keep; _stencil_render_states [SRS_back_stencil_pass_z_pass_operation] = SO_keep; @@ -80,14 +73,12 @@ StencilAttrib() { //////////////////////////////////////////////////////////////////// // Function: StencilAttrib::make_off // Access: Published, Static -// Description: Constructs a StencilAttrib that has stenciling +// Description: Constructs a StencilAttrib that has stenciling // turned off. //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) StencilAttrib:: -make_off() -{ +make_off() { StencilAttrib *attrib = new StencilAttrib; - return return_new(attrib); } @@ -110,19 +101,20 @@ make_default() { //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) StencilAttrib:: make( - unsigned int front_enable, - unsigned int front_comparison_function, - unsigned int stencil_fail_operation, - unsigned int stencil_pass_z_fail_operation, - unsigned int front_stencil_pass_z_pass_operation, + bool front_enable, + PandaCompareFunc front_comparison_function, + StencilOperation stencil_fail_operation, + StencilOperation stencil_pass_z_fail_operation, + StencilOperation front_stencil_pass_z_pass_operation, unsigned int reference, unsigned int read_mask, unsigned int write_mask) { StencilAttrib *attrib = new StencilAttrib; - attrib->_stencil_render_states [SRS_front_enable] = front_enable; - attrib->_stencil_render_states [SRS_back_enable] = 0; + if (!front_enable) { + front_comparison_function = M_none; + } attrib->_stencil_render_states [SRS_front_comparison_function] = front_comparison_function; attrib->_stencil_render_states [SRS_front_stencil_fail_operation] = stencil_fail_operation; @@ -133,7 +125,7 @@ make( attrib->_stencil_render_states [SRS_read_mask] = read_mask; attrib->_stencil_render_states [SRS_write_mask] = write_mask; - attrib->_stencil_render_states [SRS_back_comparison_function] = SCF_always; + attrib->_stencil_render_states [SRS_back_comparison_function] = M_none; attrib->_stencil_render_states [SRS_back_stencil_fail_operation] = SO_keep; attrib->_stencil_render_states [SRS_back_stencil_pass_z_fail_operation] = SO_keep; attrib->_stencil_render_states [SRS_back_stencil_pass_z_pass_operation] = SO_keep; @@ -148,24 +140,29 @@ make( //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) StencilAttrib:: make_2_sided( - unsigned int front_enable, - unsigned int back_enable, - unsigned int front_comparison_function, - unsigned int stencil_fail_operation, - unsigned int stencil_pass_z_fail_operation, - unsigned int front_stencil_pass_z_pass_operation, + bool front_enable, + bool back_enable, + PandaCompareFunc front_comparison_function, + StencilOperation stencil_fail_operation, + StencilOperation stencil_pass_z_fail_operation, + StencilOperation front_stencil_pass_z_pass_operation, unsigned int reference, unsigned int read_mask, unsigned int write_mask, - unsigned int back_comparison_function, - unsigned int back_stencil_fail_operation, - unsigned int back_stencil_pass_z_fail_operation, - unsigned int back_stencil_pass_z_pass_operation) + PandaCompareFunc back_comparison_function, + StencilOperation back_stencil_fail_operation, + StencilOperation back_stencil_pass_z_fail_operation, + StencilOperation back_stencil_pass_z_pass_operation) { StencilAttrib *attrib = new StencilAttrib; - attrib->_stencil_render_states [SRS_front_enable] = front_enable; - attrib->_stencil_render_states [SRS_back_enable] = back_enable; + if (!front_enable) { + front_comparison_function = M_none; + } + + if (!back_enable) { + back_comparison_function = M_none; + } attrib->_stencil_render_states [SRS_front_comparison_function] = front_comparison_function; attrib->_stencil_render_states [SRS_front_stencil_fail_operation] = stencil_fail_operation; @@ -191,21 +188,22 @@ make_2_sided( //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) StencilAttrib:: make_with_clear( - unsigned int front_enable, - unsigned int front_comparison_function, - unsigned int stencil_fail_operation, - unsigned int stencil_pass_z_fail_operation, - unsigned int front_stencil_pass_z_pass_operation, + bool front_enable, + PandaCompareFunc front_comparison_function, + StencilOperation stencil_fail_operation, + StencilOperation stencil_pass_z_fail_operation, + StencilOperation front_stencil_pass_z_pass_operation, unsigned int reference, unsigned int read_mask, unsigned int write_mask, - unsigned int clear, + bool clear, unsigned int clear_value) { StencilAttrib *attrib = new StencilAttrib; - attrib->_stencil_render_states [SRS_front_enable] = front_enable; - attrib->_stencil_render_states [SRS_back_enable] = 0; + if (!front_enable) { + front_comparison_function = M_none; + } attrib->_stencil_render_states [SRS_front_comparison_function] = front_comparison_function; attrib->_stencil_render_states [SRS_front_stencil_fail_operation] = stencil_fail_operation; @@ -216,7 +214,7 @@ make_with_clear( attrib->_stencil_render_states [SRS_read_mask] = read_mask; attrib->_stencil_render_states [SRS_write_mask] = write_mask; - attrib->_stencil_render_states [SRS_back_comparison_function] = SCF_always; + attrib->_stencil_render_states [SRS_back_comparison_function] = M_none; attrib->_stencil_render_states [SRS_back_stencil_fail_operation] = SO_keep; attrib->_stencil_render_states [SRS_back_stencil_pass_z_fail_operation] = SO_keep; attrib->_stencil_render_states [SRS_back_stencil_pass_z_pass_operation] = SO_keep; @@ -234,26 +232,31 @@ make_with_clear( //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) StencilAttrib:: make_2_sided_with_clear( - unsigned int front_enable, - unsigned int back_enable, - unsigned int front_comparison_function, - unsigned int stencil_fail_operation, - unsigned int stencil_pass_z_fail_operation, - unsigned int front_stencil_pass_z_pass_operation, + bool front_enable, + bool back_enable, + PandaCompareFunc front_comparison_function, + StencilOperation stencil_fail_operation, + StencilOperation stencil_pass_z_fail_operation, + StencilOperation front_stencil_pass_z_pass_operation, unsigned int reference, unsigned int read_mask, unsigned int write_mask, - unsigned int back_comparison_function, - unsigned int back_stencil_fail_operation, - unsigned int back_stencil_pass_z_fail_operation, - unsigned int back_stencil_pass_z_pass_operation, - unsigned int clear, + PandaCompareFunc back_comparison_function, + StencilOperation back_stencil_fail_operation, + StencilOperation back_stencil_pass_z_fail_operation, + StencilOperation back_stencil_pass_z_pass_operation, + bool clear, unsigned int clear_value) { StencilAttrib *attrib = new StencilAttrib; - attrib->_stencil_render_states [SRS_front_enable] = front_enable; - attrib->_stencil_render_states [SRS_back_enable] = back_enable; + if (!front_enable) { + front_comparison_function = M_none; + } + + if (!back_enable) { + back_comparison_function = M_none; + } attrib->_stencil_render_states [SRS_front_comparison_function] = front_comparison_function; attrib->_stencil_render_states [SRS_front_stencil_fail_operation] = stencil_fail_operation; @@ -316,9 +319,9 @@ compare_to_impl(const RenderAttrib *other) const { int index; int compare_result = 0; - for (index = 0; index < SRS_total; index++) { - a = (int) sa -> _stencil_render_states [index]; - b = (int) _stencil_render_states [index]; + for (index = 0; index < SRS_total; ++index) { + a = (int) sa -> _stencil_render_states[index]; + b = (int) _stencil_render_states[index]; compare_result = (a - b); if (compare_result) { break; @@ -368,9 +371,8 @@ void StencilAttrib:: write_datagram(BamWriter *manager, Datagram &dg) { RenderAttrib::write_datagram(manager, dg); - int index; - for (index = 0; index < SRS_total; index++) { - dg.add_int32(_stencil_render_states [index]); + for (int index = 0; index < SRS_total; ++index) { + dg.add_uint32(_stencil_render_states[index]); } } @@ -405,8 +407,29 @@ void StencilAttrib:: fillin(DatagramIterator &scan, BamReader *manager) { RenderAttrib::fillin(scan, manager); - int index; - for (index = 0; index < SRS_total; index++) { - _stencil_render_states [index] = scan.get_int32(); + if (manager->get_file_minor_ver() < 35) { + unsigned int front_enable, back_enable; + front_enable = scan.get_int32(); + back_enable = scan.get_int32(); + + for (int index = 0; index < SRS_total; ++index) { + _stencil_render_states[index] = scan.get_int32(); + } + + if (front_enable) { + _stencil_render_states[SRS_front_comparison_function]++; + } else { + _stencil_render_states[SRS_front_comparison_function] = M_none; + } + + if (back_enable) { + _stencil_render_states[SRS_back_comparison_function]++; + } else { + _stencil_render_states[SRS_back_comparison_function] = M_none; + } + } else { + for (int index = 0; index < SRS_total; ++index) { + _stencil_render_states[index] = scan.get_uint32(); + } } } diff --git a/panda/src/pgraph/stencilAttrib.h b/panda/src/pgraph/stencilAttrib.h index aa30985bd9..5e456b29d6 100644 --- a/panda/src/pgraph/stencilAttrib.h +++ b/panda/src/pgraph/stencilAttrib.h @@ -23,9 +23,9 @@ class FactoryParams; //////////////////////////////////////////////////////////////////// // Class : StencilAttrib // Description : A StencilAttrib is a collection of all stencil render -// states. The render states in a StencilAttrib are -// read-only. A StencilAttrib is created with make or -// make_2_sided. To determine if two sided stencil is +// states. The render states in a StencilAttrib are +// read-only. A StencilAttrib is created with make or +// make_2_sided. To determine if two sided stencil is // supported, call the function GraphicsStateGuardian:: // get_supports_two_sided_stencil. //////////////////////////////////////////////////////////////////// @@ -35,13 +35,8 @@ private: StencilAttrib(); PUBLISHED: - // enums are duplicated here from class StencilRenderStates for use in Python - enum StencilRenderState - { - SRS_front_enable, - SRS_back_enable, - + enum StencilRenderState { SRS_front_comparison_function, SRS_front_stencil_fail_operation, SRS_front_stencil_pass_z_fail_operation, @@ -58,26 +53,23 @@ PUBLISHED: SRS_clear, SRS_clear_value, - + SRS_total, - - SRS_first = 0, }; - enum StencilComparisonFunction - { - SCF_never, - SCF_less_than, - SCF_equal, - SCF_less_than_or_equal, - SCF_greater_than, - SCF_not_equal, - SCF_greater_than_or_equal, - SCF_always, + // Exists purely for backward compatibility. + enum StencilComparisonFunction { + SCF_never = M_never, + SCF_less_than = M_less, + SCF_equal = M_equal, + SCF_less_than_or_equal = M_less_equal, + SCF_greater_than = M_greater, + SCF_not_equal = M_not_equal, + SCF_greater_than_or_equal = M_greater_equal, + SCF_always = M_always, }; - enum StencilOperation - { + enum StencilOperation { SO_keep, SO_zero, SO_replace, @@ -88,73 +80,68 @@ PUBLISHED: SO_decrement_saturate, }; - enum StencilMask - { - SM_default = ~0, - }; - static CPT(RenderAttrib) make_off(); static CPT(RenderAttrib) make_default(); static CPT(RenderAttrib) make( - unsigned int front_enable, - unsigned int front_comparison_function, - unsigned int stencil_fail_operation, - unsigned int stencil_pass_z_fail_operation, - unsigned int front_stencil_pass_z_pass_operation, + bool front_enable, + PandaCompareFunc front_comparison_function, + StencilOperation stencil_fail_operation, + StencilOperation stencil_pass_z_fail_operation, + StencilOperation front_stencil_pass_z_pass_operation, unsigned int reference, unsigned int read_mask, unsigned int write_mask); static CPT(RenderAttrib) make_2_sided( - unsigned int front_enable, - unsigned int back_enable, - unsigned int front_comparison_function, - unsigned int stencil_fail_operation, - unsigned int stencil_pass_z_fail_operation, - unsigned int front_stencil_pass_z_pass_operation, + bool front_enable, + bool back_enable, + PandaCompareFunc front_comparison_function, + StencilOperation stencil_fail_operation, + StencilOperation stencil_pass_z_fail_operation, + StencilOperation front_stencil_pass_z_pass_operation, unsigned int reference, unsigned int read_mask, unsigned int write_mask, - unsigned int back_comparison_function, - unsigned int back_stencil_fail_operation, - unsigned int back_stencil_pass_z_fail_operation, - unsigned int back_stencil_pass_z_pass_operation); + PandaCompareFunc back_comparison_function, + StencilOperation back_stencil_fail_operation, + StencilOperation back_stencil_pass_z_fail_operation, + StencilOperation back_stencil_pass_z_pass_operation); static CPT(RenderAttrib) make_with_clear( - unsigned int front_enable, - unsigned int front_comparison_function, - unsigned int stencil_fail_operation, - unsigned int stencil_pass_z_fail_operation, - unsigned int front_stencil_pass_z_pass_operation, + bool front_enable, + PandaCompareFunc front_comparison_function, + StencilOperation stencil_fail_operation, + StencilOperation stencil_pass_z_fail_operation, + StencilOperation front_stencil_pass_z_pass_operation, unsigned int reference, unsigned int read_mask, unsigned int write_mask, - unsigned int clear, + bool clear, unsigned int clear_value); static CPT(RenderAttrib) make_2_sided_with_clear( - unsigned int front_enable, - unsigned int back_enable, - unsigned int front_comparison_function, - unsigned int stencil_fail_operation, - unsigned int stencil_pass_z_fail_operation, - unsigned int front_stencil_pass_z_pass_operation, + bool front_enable, + bool back_enable, + PandaCompareFunc front_comparison_function, + StencilOperation stencil_fail_operation, + StencilOperation stencil_pass_z_fail_operation, + StencilOperation front_stencil_pass_z_pass_operation, unsigned int reference, unsigned int read_mask, unsigned int write_mask, - unsigned int back_comparison_function, - unsigned int back_stencil_fail_operation, - unsigned int back_stencil_pass_z_fail_operation, - unsigned int back_stencil_pass_z_pass_operation, - unsigned int clear, + PandaCompareFunc back_comparison_function, + StencilOperation back_stencil_fail_operation, + StencilOperation back_stencil_pass_z_fail_operation, + StencilOperation back_stencil_pass_z_pass_operation, + bool clear, unsigned int clear_value); - INLINE unsigned int get_render_state (unsigned int render_state_identifier) const; + INLINE unsigned int get_render_state(StencilRenderState render_state_identifier) const; public: static const char *stencil_render_state_name_array [SRS_total]; - + virtual void output(ostream &out) const; protected: diff --git a/panda/src/putil/bam.h b/panda/src/putil/bam.h index cbc4e583f4..7930a7f62c 100644 --- a/panda/src/putil/bam.h +++ b/panda/src/putil/bam.h @@ -33,7 +33,7 @@ static const unsigned short _bam_major_ver = 6; // Bumped to major version 6 on 2/11/06 to factor out PandaNode::CData. static const unsigned short _bam_first_minor_ver = 14; -static const unsigned short _bam_minor_ver = 34; +static const unsigned short _bam_minor_ver = 35; // Bumped to minor version 14 on 12/19/07 to change default ColorAttrib. // Bumped to minor version 15 on 4/9/08 to add TextureAttrib::_implicit_sort. // Bumped to minor version 16 on 5/13/08 to add Texture::_quality_level. @@ -55,5 +55,6 @@ static const unsigned short _bam_minor_ver = 34; // Bumped to minor version 32 on 6/11/12 to add Texture::_has_read_mipmaps. // Bumped to minor version 33 on 8/17/13 to add UvScrollNode::_w_speed. // Bumped to minor version 34 on 9/16/14 to add ScissorAttrib::_off. +// Bumped to minor version 35 on 12/3/14 to change StencilAttrib. #endif