Preliminary stencil buffer code.

This commit is contained in:
aignacio_sf 2006-05-19 04:18:09 +00:00
parent 1a8b8f1756
commit 682065a3e8
19 changed files with 1228 additions and 247 deletions

View File

@ -31,7 +31,8 @@
lru.h \
parasiteBuffer.I parasiteBuffer.h \
windowProperties.I windowProperties.h \
renderBuffer.h
renderBuffer.h \
stencilRenderStates.h
#define INCLUDED_SOURCES \
standardMunger.cxx \
@ -50,7 +51,8 @@
graphicsDevice.cxx \
parasiteBuffer.cxx \
windowProperties.cxx \
lru.cxx
lru.cxx \
stencilRenderStates.cxx
#define INSTALL_HEADERS \
standardMunger.I standardMunger.h \
@ -72,7 +74,8 @@
lru.h \
parasiteBuffer.I parasiteBuffer.h \
windowProperties.I windowProperties.h \
renderBuffer.h
renderBuffer.h \
stencilRenderStates.h
#define IGATESCAN all

View File

@ -9,3 +9,4 @@
#include "graphicsOutput.cxx"
#include "parasiteBuffer.cxx"
#include "lru.cxx"
#include "stencilRenderStates.cxx"

View File

@ -538,6 +538,17 @@ get_supports_basic_shaders() const {
return _supports_basic_shaders;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_supports_two_sided_stencil
// Access: Published
// Description: Returns true if this particular GSG supports
// two sided stencil.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsStateGuardian::
get_supports_two_sided_stencil() const {
return _supports_two_sided_stencil;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_color_scale_via_lighting
// Access: Published
@ -739,3 +750,23 @@ set_current_properties(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;
}

View File

@ -152,12 +152,18 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
_supports_depth_texture = false;
_supports_shadow_filter = false;
_supports_basic_shaders = false;
_supports_stencil_wrap = false;
_supports_two_sided_stencil = false;
_supported_geom_rendering = 0;
// If this is true, then we can apply a color and/or color scale by
// twiddling the material and/or ambient light (which could mean
// enabling lighting even without a LightAttrib).
_color_scale_via_lighting = color_scale_via_lighting;
_stencil_render_states = 0;
}
////////////////////////////////////////////////////////////////////
@ -170,6 +176,11 @@ GraphicsStateGuardian::
if (_global_gsg == this) {
_global_gsg = NULL;
}
if (_stencil_render_states) {
delete _stencil_render_states;
_stencil_render_states = 0;
}
}
////////////////////////////////////////////////////////////////////
@ -280,7 +291,7 @@ reset() {
_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.0f;
_stencil_clear_value = 0;
_accum_clear_value.set(0.0f, 0.0f, 0.0f, 0.0f);
_has_scene_graph_color = false;
@ -305,6 +316,12 @@ 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);
}
////////////////////////////////////////////////////////////////////
@ -881,6 +898,14 @@ fetch_specified_part(ShaderContext::ShaderMatInput part, InternalName *name, LMa
}
case ShaderContext::SMO_view_x_to_view: {
const ShaderInput *input = _target._shader->get_shader_input(name);
if (input->get_nodepath().is_empty()) {
gsg_cat.error()
<< "SHADER INPUT ASSERT: "
<< name
<< "\n";
}
nassertr(!input->get_nodepath().is_empty(), &LMatrix4f::ident_mat());
t = input->get_nodepath().get_net_transform()->get_mat() *
get_scene()->get_world_transform()->get_mat();
@ -888,6 +913,14 @@ fetch_specified_part(ShaderContext::ShaderMatInput part, InternalName *name, LMa
}
case ShaderContext::SMO_view_to_view_x: {
const ShaderInput *input = _target._shader->get_shader_input(name);
if (input->get_nodepath().is_empty()) {
gsg_cat.error()
<< "SHADER INPUT ASSERT: "
<< name
<< "\n";
}
nassertr(!input->get_nodepath().is_empty(), &LMatrix4f::ident_mat());
t = get_scene()->get_camera_transform()->get_mat() *
invert(input->get_nodepath().get_net_transform()->get_mat());

View File

@ -47,6 +47,7 @@
#include "bitMask.h"
#include "texture.h"
#include "occlusionQueryContext.h"
#include "stencilRenderStates.h"
class DrawableRegion;
class GraphicsEngine;
@ -120,6 +121,7 @@ PUBLISHED:
INLINE bool get_supports_depth_texture() const;
INLINE bool get_supports_shadow_filter() const;
INLINE bool get_supports_basic_shaders() const;
INLINE bool get_supports_two_sided_stencil() const;
virtual int get_supported_geom_rendering() const;
@ -235,6 +237,9 @@ 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();
protected:
INLINE NodePath get_light(int light_id) const;
virtual void enable_lighting(bool enable);
@ -282,7 +287,7 @@ protected:
unsigned int _color_write_mask;
Colorf _color_clear_value;
float _depth_clear_value;
bool _stencil_clear_value;
unsigned int _stencil_clear_value;
Colorf _accum_clear_value;
CPT(DisplayRegion) _current_display_region;
@ -359,11 +364,17 @@ protected:
bool _supports_depth_texture;
bool _supports_shadow_filter;
bool _supports_basic_shaders;
bool _supports_stencil_wrap;
bool _supports_two_sided_stencil;
int _supported_geom_rendering;
bool _color_scale_via_lighting;
int _stereo_buffer_mask;
StencilRenderStates *_stencil_render_states;
public:
// Statistics
static PStatCollector _vertex_buffer_switch_pcollector;

View File

@ -0,0 +1,85 @@
// Filename: stencilRenderStates.cxx
// Created by: aignacio (17May06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2006, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "graphicsStateGuardian.h"
#include "stencilRenderStates.h"
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_clear_value, 0);
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;
}
StencilRenderStates::
~StencilRenderStates (void) {
}
void StencilRenderStates::
set_stencil_render_state (bool execute_function, StencilRenderStates::StencilRenderState stencil_render_state, StencilType 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);
}
}
}
StencilType StencilRenderStates::
get_stencil_render_state (StencilRenderStates::StencilRenderState stencil_render_state) {
return _stencil_render_state_array [stencil_render_state];
}
void StencilRenderStates::
set_stencil_function (StencilRenderStates::StencilRenderState stencil_render_state, StencilFunction stencil_function) {
_stencil_function_array [stencil_render_state] = stencil_function;
}

View File

@ -0,0 +1,102 @@
// Filename: stencilRenderStates.h
// Created by: aignacio (17May06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2006, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef STENCILRENDERSTATES_H
#define STENCILRENDERSTATES_H
class GraphicsStateGuardian;
typedef unsigned int StencilType;
////////////////////////////////////////////////////////////////////
// Class : StencilRenderStates
// Description : An abstract cross-platform class for stencil buffer
// render states. Each gsg needs to create its own
// low-level functions on how to set each render state.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA StencilRenderStates {
PUBLISHED:
enum StencilRenderState
{
SRS_clear_value,
SRS_reference,
SRS_read_mask,
SRS_write_mask,
SRS_front_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_back_enable,
SRS_back_comparison_function,
SRS_back_stencil_fail_operation,
SRS_back_stencil_pass_z_fail_operation,
SRS_back_stencil_pass_z_pass_operation,
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

View File

@ -178,6 +178,7 @@ DXGraphicsStateGuardian9::
}
#endif
GraphicsStateGuardian::~GraphicsStateGuardian();
}
////////////////////////////////////////////////////////////////////
@ -230,8 +231,7 @@ apply_texture(int i, TextureContext *tc) {
DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc);
if (_lru)
{
if (_lru) {
_lru -> access_page (dtc -> _lru_page);
}
@ -2356,6 +2356,108 @@ void DXGraphicsStateGuardian9::reset_render_states (void)
_last_fvf = 0;
}
////////////////////////////////////////////////////////////////////
// DX stencil code section
////////////////////////////////////////////////////////////////////
static int dx_stencil_comparison_function_array [ ] =
{
D3DCMP_NEVER,
D3DCMP_LESS,
D3DCMP_EQUAL,
D3DCMP_LESSEQUAL,
D3DCMP_GREATER,
D3DCMP_NOTEQUAL,
D3DCMP_GREATEREQUAL,
D3DCMP_ALWAYS,
};
static int dx_stencil_operation_array [ ] =
{
D3DSTENCILOP_KEEP,
D3DSTENCILOP_ZERO,
D3DSTENCILOP_REPLACE,
D3DSTENCILOP_INCR,
D3DSTENCILOP_DECR,
D3DSTENCILOP_INVERT,
D3DSTENCILOP_INCRSAT,
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);
switch (stencil_render_state)
{
case StencilRenderStates::SRS_clear_value:
gsg -> set_stencil_clear_value (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_front_enable:
gsg -> set_render_state (D3DRS_STENCILENABLE, 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_back_enable:
gsg -> set_render_state (D3DRS_TWOSIDEDSTENCILMODE, render_state_value);
break;
case StencilRenderStates::SRS_back_comparison_function:
gsg -> set_render_state (D3DRS_CCW_STENCILFUNC, dx_stencil_comparison_function_array [render_state_value]);
break;
case StencilRenderStates::SRS_back_stencil_fail_operation:
gsg -> set_render_state (D3DRS_CCW_STENCILFAIL, dx_stencil_operation_array [render_state_value]);
break;
case StencilRenderStates::SRS_back_stencil_pass_z_fail_operation:
gsg -> set_render_state (D3DRS_CCW_STENCILZFAIL, dx_stencil_operation_array [render_state_value]);
break;
case StencilRenderStates::SRS_back_stencil_pass_z_pass_operation:
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::reset
// Access: Public, Virtual
@ -2400,6 +2502,9 @@ reset() {
_screen->_supports_dynamic_textures = ((d3d_caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) != 0);
_screen->_supports_automatic_mipmap_generation = ((d3d_caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0);
_supports_stencil_wrap = (d3d_caps.StencilCaps & D3DSTENCILCAPS_INCR) && (d3d_caps.StencilCaps & D3DSTENCILCAPS_DECR);
_supports_two_sided_stencil = ((d3d_caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) != 0);
if (dxgsg9_cat.is_debug()) {
dxgsg9_cat.debug()
<< "\nHwTransformAndLight = " << ((d3d_caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0)
@ -2428,6 +2533,8 @@ reset() {
<< "\nsupports_stream_offset = " << _supports_stream_offset
<< "\nsupports_dynamic_textures = " << _screen->_supports_dynamic_textures
<< "\nsupports_automatic_mipmap_generation = " << _screen->_supports_automatic_mipmap_generation
<< "\nsupports_stencil_wrap = " << _supports_stencil_wrap
<< "\nsupports_two_sided_stencil = " << _supports_two_sided_stencil
<< "\nMaxAnisotropy = " << d3d_caps.MaxAnisotropy
<< "\nDirectX SDK version " DIRECTX_SDK_VERSION
<< "\n";
@ -2732,6 +2839,8 @@ reset() {
_texture_binding_shader_context = (CLP(ShaderContext) *)NULL;
PRINT_REFCNT(dxgsg9, _d3d_device);
dx_set_stencil_functions (_stencil_render_states);
}
////////////////////////////////////////////////////////////////////

View File

@ -52,6 +52,8 @@
#include <algorithm>
#define DEBUG_BUFFERS false
TypeHandle CLP(GraphicsStateGuardian)::_type_handle;
PStatCollector CLP(GraphicsStateGuardian)::_load_display_list_pcollector("Draw:Transfer data:Display lists");
@ -271,6 +273,183 @@ CLP(GraphicsStateGuardian)(const FrameBufferProperties &properties) :
CLP(GraphicsStateGuardian)::
~CLP(GraphicsStateGuardian)() {
close_gsg();
if (_stencil_render_states) {
delete _stencil_render_states;
_stencil_render_states = 0;
}
GraphicsStateGuardian::~GraphicsStateGuardian();
}
////////////////////////////////////////////////////////////////////
// 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 [ ] =
{
GL_KEEP,
GL_ZERO,
GL_REPLACE,
GL_INCR_WRAP,
GL_DECR_WRAP,
GL_INVERT,
GL_INCR,
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_clear_value:
stencil_render_states -> _gsg -> set_stencil_clear_value (render_state_value);
break;
case StencilRenderStates::SRS_write_mask:
glStencilMask (render_state_value);
break;
case StencilRenderStates::SRS_front_enable:
if (render_state_value) {
glEnable (GL_STENCIL_TEST);
}
else {
glDisable (GL_STENCIL_TEST);
}
break;
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;
default:
break;
}
}
void gl_set_stencil_functions (StencilRenderStates *stencil_render_states) {
if (stencil_render_states) {
stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_clear_value, gl_stencil_function);
// 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_front_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);
stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_back_enable, 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);
}
}
////////////////////////////////////////////////////////////////////
@ -954,6 +1133,16 @@ reset() {
report_my_gl_errors();
_supports_stencil_wrap = has_extension("GL_EXT_stencil_wrap");
_supports_two_sided_stencil = has_extension("GL_EXT_stencil_two_side");
if (_supports_two_sided_stencil) {
_glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)
get_extension_func(GLPREFIX_QUOTED, "ActiveStencilFaceEXT");
}
else {
_glActiveStencilFaceEXT = 0;
}
_auto_rescale_normal = false;
// If we don't have double-buffering, don't attempt to write to the
@ -1074,6 +1263,8 @@ reset() {
_error_count = 0;
report_my_gl_errors();
gl_set_stencil_functions (_stencil_render_states);
}
@ -2590,7 +2781,7 @@ prepare_vertex_buffer(GeomVertexArrayData *data) {
CLP(VertexBufferContext) *gvbc = new CLP(VertexBufferContext)(_prepared_objects, data);
_glGenBuffers(1, &gvbc->_index);
if (GLCAT.is_debug()) {
if (DEBUG_BUFFERS && GLCAT.is_debug()) {
GLCAT.debug()
<< "creating vertex buffer " << gvbc->_index << ": "
<< data->get_num_rows() << " vertices "
@ -2669,7 +2860,7 @@ release_vertex_buffer(VertexBufferContext *vbc) {
CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), vbc);
if (GLCAT.is_debug()) {
if (DEBUG_BUFFERS && GLCAT.is_debug()) {
GLCAT.debug()
<< "deleting vertex buffer " << gvbc->_index << "\n";
}
@ -2758,7 +2949,7 @@ prepare_index_buffer(GeomPrimitive *data) {
CLP(IndexBufferContext) *gibc = new CLP(IndexBufferContext)(_prepared_objects, data);
_glGenBuffers(1, &gibc->_index);
if (GLCAT.is_debug()) {
if (DEBUG_BUFFERS && GLCAT.is_debug()) {
GLCAT.debug()
<< "creating index buffer " << gibc->_index << ": "
<< data->get_num_vertices() << " indices ("
@ -2837,7 +3028,7 @@ release_index_buffer(IndexBufferContext *ibc) {
CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc);
if (GLCAT.is_debug()) {
if (DEBUG_BUFFERS && GLCAT.is_debug()) {
GLCAT.debug()
<< "deleting index buffer " << gibc->_index << "\n";
}
@ -4179,7 +4370,16 @@ report_extensions() const {
////////////////////////////////////////////////////////////////////
bool CLP(GraphicsStateGuardian)::
has_extension(const string &extension) const {
return (_extensions.find(extension) != _extensions.end());
bool state;
state = _extensions.find(extension) != _extensions.end();
if (GLCAT.is_debug()) {
GLCAT.debug()
<< "HAS EXT " << extension << " " << state << "\n";
}
return state;
}
////////////////////////////////////////////////////////////////////

View File

@ -78,6 +78,7 @@ typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint lev
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
typedef void (APIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
#endif // __EDG__
////////////////////////////////////////////////////////////////////
@ -444,6 +445,8 @@ public:
PFNGLDELETEQUERIESPROC _glDeleteQueries;
PFNGLGETQUERYOBJECTUIVPROC _glGetQueryObjectuiv;
PFNGLACTIVESTENCILFACEEXTPROC _glActiveStencilFaceEXT;
GLenum _edge_clamp;
GLenum _border_clamp;
GLenum _mirror_repeat;

View File

@ -100,6 +100,7 @@
showBoundsEffect.I showBoundsEffect.h \
spotlight.I spotlight.h \
stateMunger.I stateMunger.h \
stencilAttrib.I stencilAttrib.h \
switchNode.I switchNode.h \
texMatrixAttrib.I texMatrixAttrib.h \
texProjectorEffect.I texProjectorEffect.h \
@ -202,6 +203,7 @@
showBoundsEffect.cxx \
spotlight.cxx \
stateMunger.cxx \
stencilAttrib.cxx \
switchNode.cxx \
texMatrixAttrib.cxx \
texProjectorEffect.cxx \
@ -301,6 +303,7 @@
showBoundsEffect.I showBoundsEffect.h \
spotlight.I spotlight.h \
stateMunger.I stateMunger.h \
stencilAttrib.I stencilAttrib.h \
switchNode.I switchNode.h \
texMatrixAttrib.I texMatrixAttrib.h \
texProjectorEffect.I texProjectorEffect.h \

View File

@ -43,6 +43,7 @@ clear_to_zero() {
_rescale_normal = NULL;
_shade_model = NULL;
_shader = NULL;
_stencil = NULL;
_tex_gen = NULL;
_tex_matrix = NULL;
_texture = NULL;

View File

@ -51,6 +51,7 @@ initialize_defvals() {
_defvals._rescale_normal = DCAST(RescaleNormalAttrib,RescaleNormalAttrib::make_default());
_defvals._shade_model = DCAST(ShadeModelAttrib,ShadeModelAttrib::make(ShadeModelAttrib::M_smooth));
_defvals._shader = DCAST(ShaderAttrib,ShaderAttrib::make_off());
_defvals._stencil = DCAST(StencilAttrib,StencilAttrib::make());
_defvals._tex_gen = DCAST(TexGenAttrib,TexGenAttrib::make());
_defvals._tex_matrix = DCAST(TexMatrixAttrib,TexMatrixAttrib::make());
_defvals._texture = DCAST(TextureAttrib,TextureAttrib::make_all_off());
@ -77,6 +78,7 @@ initialize_defvals() {
_defvals._rescale_normal = DCAST(RescaleNormalAttrib,_defvals._rescale_normal->make_default());
_defvals._shade_model = DCAST(ShadeModelAttrib,_defvals._shade_model->make_default());
_defvals._shader = DCAST(ShaderAttrib,_defvals._shader->make_default());
_defvals._stencil = DCAST(StencilAttrib,_defvals._stencil->make_default());
_defvals._tex_gen = DCAST(TexGenAttrib,_defvals._tex_gen->make_default());
_defvals._tex_matrix = DCAST(TexMatrixAttrib,_defvals._tex_matrix->make_default());
_defvals._texture = DCAST(TextureAttrib,_defvals._texture->make_default());
@ -118,6 +120,7 @@ AttribSlots(const AttribSlots &copy) :
_rescale_normal(copy._rescale_normal),
_shade_model(copy._shade_model),
_shader(copy._shader),
_stencil(copy._stencil),
_tex_gen(copy._tex_gen),
_tex_matrix(copy._tex_matrix),
_texture(copy._texture),
@ -151,6 +154,7 @@ operator =(const AttribSlots &src) {
_rescale_normal = src._rescale_normal;
_shade_model = src._shade_model;
_shader = src._shader;
_stencil = src._stencil;
_tex_gen = src._tex_gen;
_tex_matrix = src._tex_matrix;
_texture = src._texture;
@ -184,10 +188,11 @@ get_slot(int n) const {
case 16: return DCAST(RenderAttrib, _rescale_normal);
case 17: return DCAST(RenderAttrib, _shade_model);
case 18: return DCAST(RenderAttrib, _shader);
case 19: return DCAST(RenderAttrib, _tex_gen);
case 20: return DCAST(RenderAttrib, _tex_matrix);
case 21: return DCAST(RenderAttrib, _texture);
case 22: return DCAST(RenderAttrib, _transparency);
case 19: return DCAST(RenderAttrib, _stencil);
case 20: return DCAST(RenderAttrib, _tex_gen);
case 21: return DCAST(RenderAttrib, _tex_matrix);
case 22: return DCAST(RenderAttrib, _texture);
case 23: return DCAST(RenderAttrib, _transparency);
default:
nassertr(false, NULL);
return NULL;
@ -221,11 +226,11 @@ set_slot(int n, const RenderAttrib *val) {
case 16: _rescale_normal = DCAST(RescaleNormalAttrib, val); break;
case 17: _shade_model = DCAST(ShadeModelAttrib, val); break;
case 18: _shader = DCAST(ShaderAttrib, val); break;
case 19: _tex_gen = DCAST(TexGenAttrib, val); break;
case 20: _tex_matrix = DCAST(TexMatrixAttrib, val); break;
case 21: _texture = DCAST(TextureAttrib, val); break;
case 22: _transparency = DCAST(TransparencyAttrib, val); break;
case 19: _stencil = DCAST(StencilAttrib, val); break;
case 20: _tex_gen = DCAST(TexGenAttrib, val); break;
case 21: _tex_matrix = DCAST(TexMatrixAttrib, val); break;
case 22: _texture = DCAST(TextureAttrib, val); break;
case 23: _transparency = DCAST(TransparencyAttrib, val); break;
default: nassertv(false);
}
}

View File

@ -43,6 +43,7 @@
#include "rescaleNormalAttrib.h"
#include "shadeModelAttrib.h"
#include "shaderAttrib.h"
#include "stencilAttrib.h"
#include "texMatrixAttrib.h"
#include "texGenAttrib.h"
#include "textureAttrib.h"
@ -76,6 +77,7 @@ class EXPCL_PANDA AttribSlots
CPT(RescaleNormalAttrib) _rescale_normal;
CPT(ShadeModelAttrib) _shade_model;
CPT(ShaderAttrib) _shader;
CPT(StencilAttrib) _stencil;
CPT(TexGenAttrib) _tex_gen;
CPT(TexMatrixAttrib) _tex_matrix;
CPT(TextureAttrib) _texture;
@ -91,7 +93,7 @@ class EXPCL_PANDA AttribSlots
public:
// Each "array" reference requires a switch and a DCAST, so it's not overly fast.
enum { slot_count=23 };
enum { slot_count=24 };
const RenderAttrib *get_slot(int n) const;
void set_slot(int n, const RenderAttrib *attrib);

View File

@ -344,6 +344,7 @@ init_libpgraph() {
ShowBoundsEffect::init_type();
Spotlight::init_type();
StateMunger::init_type();
StencilAttrib::init_type();
SwitchNode::init_type();
TexMatrixAttrib::init_type();
TexProjectorEffect::init_type();

View File

@ -16,6 +16,7 @@
#include "showBoundsEffect.cxx"
#include "spotlight.cxx"
#include "stateMunger.cxx"
#include "stencilAttrib.cxx"
#include "switchNode.cxx"
#include "texMatrixAttrib.cxx"
#include "texProjectorEffect.cxx"

View File

@ -0,0 +1,70 @@
// Filename: stencilAttrib.I
// Created by: aignacio (18May06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2006, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: StencilAttrib::Constructor
// Access: Private
// Description: Use StencilAttrib::make() to construct a new
// StencilAttrib object.
////////////////////////////////////////////////////////////////////
INLINE StencilAttrib::
StencilAttrib() {
_stencil_render_states [SRS_clear_value] = 0;
_stencil_render_states [SRS_reference] = 0;
_stencil_render_states [SRS_read_mask] = ~0;
_stencil_render_states [SRS_write_mask] = ~0;
_stencil_render_states [SRS_front_enable] = 0;
_stencil_render_states [SRS_front_comparison_function] = SCF_always;
_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;
_stencil_render_states [SRS_back_enable] = 0;
_stencil_render_states [SRS_back_comparison_function] = SCF_always;
_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;
_default = true;
}
////////////////////////////////////////////////////////////////////
// Function: StencilAttrib::set_render_state
// Access: Published
// Description: Sets the render state.
////////////////////////////////////////////////////////////////////
INLINE void StencilAttrib::
set_render_state(unsigned int render_state_identifier, unsigned int render_state) {
_stencil_render_states [render_state_identifier] = render_state;
_default = false;
}
////////////////////////////////////////////////////////////////////
// Function: StencilAttrib::get_render_state
// Access: Published
// Description: Returns render state.
////////////////////////////////////////////////////////////////////
INLINE unsigned int StencilAttrib::
get_render_state(unsigned int render_state_identifier) const {
return _stencil_render_states [render_state_identifier];
}

View File

@ -0,0 +1,186 @@
// Filename: stencilAttrib.cxx
// Created by: aignacio (18May06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2006, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "stencilAttrib.h"
#include "attribSlots.h"
#include "graphicsStateGuardianBase.h"
#include "dcast.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "datagram.h"
#include "datagramIterator.h"
TypeHandle StencilAttrib::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: StencilAttrib::make
// Access: Published, Static
// Description: Constructs a new StencilAttrib object.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) StencilAttrib::
make() {
StencilAttrib *attrib = new StencilAttrib;
return return_new(attrib);
}
////////////////////////////////////////////////////////////////////
// Function: StencilAttrib::output
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void StencilAttrib::
output(ostream &out) const {
int index;
for (index = 0; index < SRS_total; index++) {
out << "(" << index << "," << _stencil_render_states [index] << ")";
}
}
////////////////////////////////////////////////////////////////////
// Function: StencilAttrib::compare_to_impl
// Access: Protected, Virtual
// Description: Intended to be overridden by derived StencilAttrib
// types to return a unique number indicating whether
// this StencilAttrib is equivalent to the other one.
//
// This should return 0 if the two StencilAttrib objects
// are equivalent, a number less than zero if this one
// should be sorted before the other one, and a number
// greater than zero otherwise.
//
// This will only be called with two StencilAttrib
// objects whose get_type() functions return the same.
////////////////////////////////////////////////////////////////////
int StencilAttrib::
compare_to_impl(const RenderAttrib *other) const {
const StencilAttrib *sa;
DCAST_INTO_R(sa, other, 0);
int compare_result = 0;
// quick test to see if both are default states
// which should be the most common case
if (_default && (_default == sa -> _default)) {
}
else {
int index;
for (index = 0; index < SRS_total; index++) {
if (_stencil_render_states [index] - sa -> _stencil_render_states [index]) {
// ?????
compare_result = -(index + 1);
break;
}
}
}
return compare_result;
}
////////////////////////////////////////////////////////////////////
// Function: StencilAttrib::make_default_impl
// Access: Protected, Virtual
// Description: Intended to be overridden by derived StencilAttrib
// types to specify what the default property for a
// StencilAttrib of this type should be.
//
// This should return a newly-allocated StencilAttrib of
// the same type that corresponds to whatever the
// standard default for this kind of StencilAttrib is.
////////////////////////////////////////////////////////////////////
RenderAttrib *StencilAttrib::
make_default_impl() const {
return new StencilAttrib;
}
////////////////////////////////////////////////////////////////////
// Function: StencilAttrib::store_into_slot
// Access: Public, Virtual
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void StencilAttrib::
store_into_slot(AttribSlots *slots) const {
slots->_stencil = this;
}
////////////////////////////////////////////////////////////////////
// Function: StencilAttrib::register_with_read_factory
// Access: Public, Static
// Description: Tells the BamReader how to create objects of type
// StencilAttrib.
////////////////////////////////////////////////////////////////////
void StencilAttrib::
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
}
////////////////////////////////////////////////////////////////////
// Function: StencilAttrib::write_datagram
// Access: Public, Virtual
// Description: Writes the contents of this object to the datagram
// for shipping out to a Bam file.
////////////////////////////////////////////////////////////////////
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]);
}
}
////////////////////////////////////////////////////////////////////
// Function: StencilAttrib::make_from_bam
// Access: Protected, Static
// Description: This function is called by the BamReader's factory
// when a new object of type StencilAttrib is encountered
// in the Bam file. It should create the StencilAttrib
// and extract its information from the file.
////////////////////////////////////////////////////////////////////
TypedWritable *StencilAttrib::
make_from_bam(const FactoryParams &params) {
StencilAttrib *attrib = new StencilAttrib;
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
attrib->fillin(scan, manager);
return attrib;
}
////////////////////////////////////////////////////////////////////
// Function: StencilAttrib::fillin
// Access: Protected
// Description: This internal function is called by make_from_bam to
// read in all of the relevant data from the BamFile for
// the new StencilAttrib.
////////////////////////////////////////////////////////////////////
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();
}
_default = false;
}

View File

@ -0,0 +1,134 @@
// Filename: stencilAttrib.h
// Created by: aignacio (18May06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2006, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef STENCILATTRIB_H
#define STENCILATTRIB_H
#include "pandabase.h"
#include "renderAttrib.h"
class FactoryParams;
////////////////////////////////////////////////////////////////////
// Class : StencilAttrib
// Description : Enables or disables writing of pixel to framebuffer
// based on its alpha value relative to a reference alpha value
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA StencilAttrib : public RenderAttrib {
private:
INLINE StencilAttrib();
PUBLISHED:
// enums are duplicated here from class StencilRenderStates for use in Python
enum StencilRenderState
{
SRS_clear_value,
SRS_reference,
SRS_read_mask,
SRS_write_mask,
SRS_front_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_back_enable,
SRS_back_comparison_function,
SRS_back_stencil_fail_operation,
SRS_back_stencil_pass_z_fail_operation,
SRS_back_stencil_pass_z_pass_operation,
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,
};
static CPT(RenderAttrib) make();
INLINE void set_render_state (unsigned int render_state_identifier, unsigned int render_state);
INLINE unsigned int get_render_state (unsigned int render_state_identifier) const;
public:
virtual void output(ostream &out) const;
virtual void store_into_slot(AttribSlots *slots) const;
protected:
virtual int compare_to_impl(const RenderAttrib *other) const;
virtual RenderAttrib *make_default_impl() const;
private:
unsigned int _stencil_render_states [SRS_total];
bool _default;
public:
static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &dg);
protected:
static TypedWritable *make_from_bam(const FactoryParams &params);
void fillin(DatagramIterator &scan, BamReader *manager);
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
RenderAttrib::init_type();
register_type(_type_handle, "StencilAttrib",
RenderAttrib::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "stencilAttrib.I"
#endif