Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/display/graphicsStateGuardian.cxx

Go to the documentation of this file.
00001 // Filename: graphicsStateGuardian.cxx
00002 // Created by:  drose (02Feb99)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 
00020 #include "graphicsStateGuardian.h"
00021 #include "config_display.h"
00022 #include "textureContext.h"
00023 #include "renderBuffer.h"
00024 #include "colorAttrib.h"
00025 #include "colorScaleAttrib.h"
00026 #include "lightAttrib.h"
00027 #include "textureAttrib.h"
00028 #include "renderState.h"
00029 #include "depthWriteAttrib.h"
00030 #include "colorWriteAttrib.h"
00031 #include "textureAttrib.h"
00032 #include "lightAttrib.h"
00033 #include "clipPlaneAttrib.h"
00034 #include "light.h"
00035 #include "planeNode.h"
00036 #include "ambientLight.h"
00037 
00038 #include "clockObject.h"
00039 #include "pStatTimer.h"
00040 
00041 #include <algorithm>
00042 
00043 #ifndef CPPPARSER
00044 PStatCollector GraphicsStateGuardian::_total_texusage_pcollector("Texture usage");
00045 PStatCollector GraphicsStateGuardian::_active_texusage_pcollector("Texture usage:Active");
00046 PStatCollector GraphicsStateGuardian::_total_geom_pcollector("Prepared Geoms");
00047 PStatCollector GraphicsStateGuardian::_active_geom_pcollector("Prepared Geoms:Active");
00048 PStatCollector GraphicsStateGuardian::_total_geom_node_pcollector("Prepared GeomNodes");
00049 PStatCollector GraphicsStateGuardian::_active_geom_node_pcollector("Prepared GeomNodes:Active");
00050 PStatCollector GraphicsStateGuardian::_total_texmem_pcollector("Texture memory");
00051 PStatCollector GraphicsStateGuardian::_used_texmem_pcollector("Texture memory:In use");
00052 PStatCollector GraphicsStateGuardian::_texmgrmem_total_pcollector("Texture manager");
00053 PStatCollector GraphicsStateGuardian::_texmgrmem_resident_pcollector("Texture manager:Resident");
00054 PStatCollector GraphicsStateGuardian::_vertices_pcollector("Vertices");
00055 PStatCollector GraphicsStateGuardian::_vertices_tristrip_pcollector("Vertices:Triangle strips");
00056 PStatCollector GraphicsStateGuardian::_vertices_trifan_pcollector("Vertices:Triangle fans");
00057 PStatCollector GraphicsStateGuardian::_vertices_tri_pcollector("Vertices:Triangles");
00058 PStatCollector GraphicsStateGuardian::_vertices_other_pcollector("Vertices:Other");
00059 PStatCollector GraphicsStateGuardian::_state_changes_pcollector("State changes");
00060 PStatCollector GraphicsStateGuardian::_transform_state_pcollector("State changes:Transforms");
00061 PStatCollector GraphicsStateGuardian::_texture_state_pcollector("State changes:Textures");
00062 PStatCollector GraphicsStateGuardian::_nodes_pcollector("Nodes");
00063 PStatCollector GraphicsStateGuardian::_geom_nodes_pcollector("Nodes:GeomNodes");
00064 PStatCollector GraphicsStateGuardian::_frustum_cull_volumes_pcollector("Cull volumes");
00065 PStatCollector GraphicsStateGuardian::_frustum_cull_transforms_pcollector("Cull volumes:Transforms");
00066 
00067 PStatCollector GraphicsStateGuardian::_set_state_pcollector("Draw:Set state");
00068 PStatCollector GraphicsStateGuardian::_draw_primitive_pcollector("Draw:Primitive");
00069 PStatCollector GraphicsStateGuardian::_transform_states_pcollector("TransformStates");
00070 PStatCollector GraphicsStateGuardian::_transform_states_unused_pcollector("TransformStates:Unused");
00071 PStatCollector GraphicsStateGuardian::_render_states_pcollector("RenderStates");
00072 PStatCollector GraphicsStateGuardian::_render_states_unused_pcollector("RenderStates:Unused");
00073 
00074 #endif
00075 
00076 TypeHandle GraphicsStateGuardian::_type_handle;
00077 
00078 ////////////////////////////////////////////////////////////////////
00079 //     Function: GraphicsStateGuardian::Constructor
00080 //       Access: Public
00081 //  Description:
00082 ////////////////////////////////////////////////////////////////////
00083 GraphicsStateGuardian::
00084 GraphicsStateGuardian(const FrameBufferProperties &properties) {
00085   _properties = properties;
00086   _coordinate_system = default_coordinate_system;
00087   _current_display_region = (DisplayRegion*)0L;
00088   _current_lens = (Lens *)NULL;
00089   _needs_reset = true;
00090   _closing_gsg = false;
00091 }
00092 
00093 ////////////////////////////////////////////////////////////////////
00094 //     Function: GraphicsStateGuardian::Destructor
00095 //       Access: Public, Virtual
00096 //  Description:
00097 ////////////////////////////////////////////////////////////////////
00098 GraphicsStateGuardian::
00099 ~GraphicsStateGuardian() {
00100 }
00101 
00102 ////////////////////////////////////////////////////////////////////
00103 //     Function: GraphicsStateGuardian::reset
00104 //       Access: Public, Virtual
00105 //  Description: Resets all internal state as if the gsg were newly
00106 //               created.
00107 ////////////////////////////////////////////////////////////////////
00108 void GraphicsStateGuardian::
00109 reset() {
00110   _needs_reset = false;
00111 
00112   _display_region_stack_level = 0;
00113   _frame_buffer_stack_level = 0;
00114   _lens_stack_level = 0;
00115 
00116   _state = RenderState::make_empty();
00117   _transform = TransformState::make_identity();
00118 
00119   _buffer_mask = 0;
00120   _color_clear_value.set(0.0f, 0.0f, 0.0f, 0.0f);
00121   _depth_clear_value = 1.0f;
00122   _stencil_clear_value = 0.0f;
00123   _accum_clear_value.set(0.0f, 0.0f, 0.0f, 0.0f);
00124   _clear_buffer_type = RenderBuffer::T_back | RenderBuffer::T_depth;
00125   _normals_enabled = false;
00126 
00127   //Color and alpha transform variables
00128   _color_transform_enabled = 0;
00129   _current_color_offset.set(0.0f, 0.0f, 0.0f, 0.0f);
00130   _current_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
00131 
00132   _color_write_mode = ColorWriteAttrib::M_on;
00133   _color_blend_mode = ColorBlendAttrib::M_none;
00134   _transparency_mode = TransparencyAttrib::M_none;
00135 
00136   _has_scene_graph_color = false;
00137   _scene_graph_color_stale = false;
00138   _vertex_colors_enabled = true;
00139   _lighting_enabled = false;
00140   _lighting_enabled_this_frame = false;
00141 
00142   _clip_planes_enabled = false;
00143   _clip_planes_enabled_this_frame = false;
00144 }
00145 
00146 ////////////////////////////////////////////////////////////////////
00147 //     Function: GraphicsStateGuardian::get_render_buffer
00148 //       Access: Public
00149 //  Description: Returns a RenderBuffer object suitable for operating
00150 //               on the requested set of buffers.  buffer_type is the
00151 //               union of all the desired RenderBuffer::Type values.
00152 ////////////////////////////////////////////////////////////////////
00153 RenderBuffer GraphicsStateGuardian::
00154 get_render_buffer(int buffer_type) {
00155   return RenderBuffer(this, buffer_type & _buffer_mask);
00156 }
00157 
00158 ////////////////////////////////////////////////////////////////////
00159 //     Function: GraphicsStateGuardian::release_all_textures
00160 //       Access: Public
00161 //  Description: Frees the resources for all textures associated with
00162 //               this GSG.
00163 ////////////////////////////////////////////////////////////////////
00164 void GraphicsStateGuardian::
00165 release_all_textures() {
00166   // We must get a copy of the _prepared_textures list first, because
00167   // each call to release_texture() will remove that texture from the
00168   // list, and we don't want to traverse a list while we're modifying
00169   // it!
00170 
00171   Textures temp = _prepared_textures;
00172   for (Textures::const_iterator ti = temp.begin();
00173        ti != temp.end();
00174        ++ti) {
00175     release_texture(*ti);
00176   }
00177 
00178   // Now that we've released all of the textures, the
00179   // _prepared_textures list should have completely emptied itself.
00180   nassertv(_prepared_textures.empty());
00181 }
00182 
00183 ////////////////////////////////////////////////////////////////////
00184 //     Function: GraphicsStateGuardian::release_all_geoms
00185 //       Access: Public
00186 //  Description: Frees the resources for all Geoms and GeomNodes
00187 //               associated with this GSG.  Warning!  This may make
00188 //               the Geoms unrenderable, if the Panda-level
00189 //               information has been deleted.
00190 ////////////////////////////////////////////////////////////////////
00191 void GraphicsStateGuardian::
00192 release_all_geoms() {
00193   // As above, for both Geoms and GeomNodes.
00194 
00195   Geoms temp_geoms = _prepared_geoms;
00196   for (Geoms::const_iterator gi = temp_geoms.begin();
00197        gi != temp_geoms.end();
00198        ++gi) {
00199     release_geom(*gi);
00200   }
00201 
00202   GeomNodes temp_geom_nodes = _prepared_geom_nodes;
00203   for (GeomNodes::const_iterator gni = temp_geom_nodes.begin();
00204        gni != temp_geom_nodes.end();
00205        ++gni) {
00206     release_geom_node(*gni);
00207   }
00208 
00209   nassertv(_prepared_geoms.empty());
00210   nassertv(_prepared_geom_nodes.empty());
00211 }
00212 
00213 ////////////////////////////////////////////////////////////////////
00214 //     Function: GraphicsStateGuardian::prepare_texture
00215 //       Access: Public, Virtual
00216 //  Description: Prepares the indicated texture for retained-mode
00217 //               rendering.  In the future, this texture may be
00218 //               applied simply by calling apply_texture() with the
00219 //               value returned by this function.
00220 ////////////////////////////////////////////////////////////////////
00221 TextureContext *GraphicsStateGuardian::
00222 prepare_texture(Texture *) {
00223   return (TextureContext *)NULL;
00224 }
00225 
00226 ////////////////////////////////////////////////////////////////////
00227 //     Function: GraphicsStateGuardian::apply_texture
00228 //       Access: Public, Virtual
00229 //  Description: Applies the texture previously indicated via a call
00230 //               to prepare_texture() to the graphics state, so that
00231 //               geometry rendered in the future will be rendered with
00232 //               the given texture.
00233 ////////////////////////////////////////////////////////////////////
00234 void GraphicsStateGuardian::
00235 apply_texture(TextureContext *) {
00236 }
00237 
00238 ////////////////////////////////////////////////////////////////////
00239 //     Function: GraphicsStateGuardian::release_texture
00240 //       Access: Public, Virtual
00241 //  Description: Frees the resources previously allocated via a call
00242 //               to prepare_texture(), including deleting the
00243 //               TextureContext itself, if necessary.
00244 ////////////////////////////////////////////////////////////////////
00245 void GraphicsStateGuardian::
00246 release_texture(TextureContext *) {
00247 }
00248 
00249 ////////////////////////////////////////////////////////////////////
00250 //     Function: GraphicsStateGuardian::prepare_geom_node
00251 //       Access: Public, Virtual
00252 //  Description: Prepares the indicated GeomNode for retained-mode
00253 //               rendering.  If this function returns non-NULL, the
00254 //               value returned will be passed back to a future call
00255 //               to draw_geom_node(), which is expected to draw the
00256 //               contents of the node.
00257 ////////////////////////////////////////////////////////////////////
00258 GeomNodeContext *GraphicsStateGuardian::
00259 prepare_geom_node(GeomNode *) {
00260   return (GeomNodeContext *)NULL;
00261 }
00262 
00263 ////////////////////////////////////////////////////////////////////
00264 //     Function: GraphicsStateGuardian::draw_geom_node
00265 //       Access: Public, Virtual
00266 //  Description: Draws a GeomNode previously indicated by a call to
00267 //               prepare_geom_node().
00268 ////////////////////////////////////////////////////////////////////
00269 void GraphicsStateGuardian::
00270 draw_geom_node(GeomNode *node, const RenderState *state,
00271                GeomNodeContext *) {
00272 #if 0   // temporarily disabled until ported to new scene graph
00273   int num_geoms = node->get_num_geoms();
00274   for (int i = 0; i < num_geoms; i++) {
00275     node->get_geom(i)->draw(this);
00276   }
00277 #endif   // temporarily disabled until ported to new scene graph
00278 }
00279 
00280 ////////////////////////////////////////////////////////////////////
00281 //     Function: GraphicsStateGuardian::release_geom_node
00282 //       Access: Public, Virtual
00283 //  Description: Frees the resources previously allocated via a call
00284 //               to prepare_geom_node(), including deleting the
00285 //               GeomNodeContext itself, if necessary.
00286 ////////////////////////////////////////////////////////////////////
00287 void GraphicsStateGuardian::
00288 release_geom_node(GeomNodeContext *) {
00289 }
00290 
00291 ////////////////////////////////////////////////////////////////////
00292 //     Function: GraphicsStateGuardian::prepare_geom
00293 //       Access: Public, Virtual
00294 //  Description: Prepares the indicated Geom for retained-mode
00295 //               rendering.  The value returned by this function will
00296 //               be passed back into future calls to draw_tristrip(),
00297 //               etc., along with the Geom pointer.
00298 ////////////////////////////////////////////////////////////////////
00299 GeomContext *GraphicsStateGuardian::
00300 prepare_geom(Geom *) {
00301   return (GeomContext *)NULL;
00302 }
00303 
00304 ////////////////////////////////////////////////////////////////////
00305 //     Function: GraphicsStateGuardian::release_geom
00306 //       Access: Public, Virtual
00307 //  Description: Frees the resources previously allocated via a call
00308 //               to prepare_geom(), including deleting the GeomContext
00309 //               itself, if necessary.
00310 ////////////////////////////////////////////////////////////////////
00311 void GraphicsStateGuardian::
00312 release_geom(GeomContext *) {
00313 }
00314 
00315 ////////////////////////////////////////////////////////////////////
00316 //     Function: GraphicsStateGuardian::set_state_and_transform
00317 //       Access: Public, Virtual
00318 //  Description: Simultaneously resets the render state and the
00319 //               transform state.
00320 ////////////////////////////////////////////////////////////////////
00321 void GraphicsStateGuardian::
00322 set_state_and_transform(const RenderState *state,
00323                         const TransformState *transform) {
00324   set_state(state);
00325   set_transform(transform);
00326 }
00327 
00328 ////////////////////////////////////////////////////////////////////
00329 //     Function: GraphicsStateGuardian::set_color_clear_value
00330 //       Access: Public
00331 //  Description: Sets the color that the next do_clear() command will set
00332 //               the color buffer to
00333 ////////////////////////////////////////////////////////////////////
00334 void GraphicsStateGuardian::
00335 set_color_clear_value(const Colorf& value) {
00336   _color_clear_value = value;
00337 }
00338 
00339 ////////////////////////////////////////////////////////////////////
00340 //     Function: GraphicsStateGuardian::set_depth_clear_value
00341 //       Access: Public
00342 //  Description: Sets the depth that the next do_clear() command will set
00343 //               the depth buffer to
00344 ////////////////////////////////////////////////////////////////////
00345 void GraphicsStateGuardian::
00346 set_depth_clear_value(const float value) {
00347   _depth_clear_value = value;
00348 }
00349 
00350 ////////////////////////////////////////////////////////////////////
00351 //     Function: GraphicsStateGuardian::clear
00352 //       Access: Public
00353 //  Description: Clears the framebuffer within the current
00354 //               DisplayRegion, according to the flags indicated by
00355 //               the given ClearableRegion object.
00356 ////////////////////////////////////////////////////////////////////
00357 void GraphicsStateGuardian::
00358 clear(ClearableRegion *clearable) {
00359   int clear_buffer_type = 0;
00360   if (clearable->get_clear_color_active()) {
00361     clear_buffer_type |= RenderBuffer::T_back;
00362     set_color_clear_value(clearable->get_clear_color());
00363   }
00364   if (clearable->get_clear_depth_active()) {
00365     clear_buffer_type |= RenderBuffer::T_depth;
00366     set_depth_clear_value(clearable->get_clear_depth());
00367   }
00368 
00369   if (clear_buffer_type != 0) {
00370     prepare_display_region();
00371     do_clear(get_render_buffer(clear_buffer_type));
00372   }
00373 }
00374 
00375 ////////////////////////////////////////////////////////////////////
00376 //     Function: GraphicsStateGuardian::prepare_lens
00377 //       Access: Public, Virtual
00378 //  Description: Makes the current lens (whichever lens was most
00379 //               recently specified with push_lens()) active, so that
00380 //               it will transform future rendered geometry.  Normally
00381 //               this is only called from the draw process, and
00382 //               usually it is called immediately after a call to
00383 //               push_lens().
00384 //
00385 //               The return value is true if the lens is acceptable,
00386 //               false if it is not.
00387 ////////////////////////////////////////////////////////////////////
00388 bool GraphicsStateGuardian::
00389 prepare_lens() {
00390   return false;
00391 }
00392 
00393 ////////////////////////////////////////////////////////////////////
00394 //     Function: GraphicsStateGuardian::begin_frame
00395 //       Access: Public, Virtual
00396 //  Description: Called before each frame is rendered, to allow the
00397 //               GSG a chance to do any internal cleanup before
00398 //               beginning the frame.
00399 //
00400 //               The return value is true if successful (in which case
00401 //               the frame will be drawn and end_frame() will be
00402 //               called later), or false if unsuccessful (in which
00403 //               case nothing will be drawn and end_frame() will not
00404 //               be called).
00405 ////////////////////////////////////////////////////////////////////
00406 bool GraphicsStateGuardian::
00407 begin_frame() {
00408   // Undo any lighting we had enabled last frame, to force the lights
00409   // to be reissued, in case their parameters or positions have
00410   // changed between frames.
00411   if (_lighting_enabled_this_frame) {
00412     for (int i = 0; i < (int)_light_info.size(); i++) {
00413       if (_light_info[i]._enabled) {
00414         enable_light(i, false);
00415         _light_info[i]._enabled = false;
00416       }
00417       _light_info[i]._light = (Light *)NULL;
00418     }
00419 
00420     // Also force the lighting state to unlit, so that issue_light()
00421     // will be guaranteed to be called next frame even if we have the
00422     // same set of light pointers we had this frame.
00423     modify_state(get_unlit_state());
00424 
00425     _lighting_enabled_this_frame = false;
00426   }
00427 
00428   // Ditto for the clipping planes.
00429   if (_clip_planes_enabled_this_frame) {
00430     for (int i = 0; i < (int)_clip_plane_info.size(); i++) {
00431       if (_clip_plane_info[i]._enabled) {
00432         enable_clip_plane(i, false);
00433         _clip_plane_info[i]._enabled = false;
00434       }
00435       _clip_plane_info[i]._plane = (PlaneNode *)NULL;
00436     }
00437 
00438     modify_state(get_unclipped_state());
00439 
00440     _clip_planes_enabled_this_frame = false;
00441   }
00442 
00443 #ifdef DO_PSTATS
00444   // For Pstats to track our current texture memory usage, we have to
00445   // reset the set of current textures each frame.
00446   init_frame_pstats();
00447 
00448   // But since we don't get sent a new issue_texture() unless our
00449   // texture state has changed, we have to be sure to clear the
00450   // current texture state now.  A bit unfortunate, but probably not
00451   // measurably expensive.
00452   modify_state(get_untextured_state());
00453 #endif
00454   return true;
00455 }
00456 
00457 ////////////////////////////////////////////////////////////////////
00458 //     Function: GraphicsStateGuardian::begin_scene
00459 //       Access: Public, Virtual
00460 //  Description: Called between begin_frame() and end_frame() to mark
00461 //               the beginning of drawing commands for a "scene"
00462 //               (usually a particular DisplayRegion) within a frame.
00463 //               All 3-D drawing commands, except the clear operation,
00464 //               must be enclosed within begin_scene() .. end_scene().
00465 //
00466 //               The return value is true if successful (in which case
00467 //               the scene will be drawn and end_scene() will be
00468 //               called later), or false if unsuccessful (in which
00469 //               case nothing will be drawn and end_scene() will not
00470 //               be called).
00471 ////////////////////////////////////////////////////////////////////
00472 bool GraphicsStateGuardian::
00473 begin_scene() {
00474   return true;
00475 }
00476 
00477 ////////////////////////////////////////////////////////////////////
00478 //     Function: GraphicsStateGuardian::end_scene
00479 //       Access: Public, Virtual
00480 //  Description: Called between begin_frame() and end_frame() to mark
00481 //               the end of drawing commands for a "scene" (usually a
00482 //               particular DisplayRegion) within a frame.  All 3-D
00483 //               drawing commands, except the clear operation, must be
00484 //               enclosed within begin_scene() .. end_scene().
00485 ////////////////////////////////////////////////////////////////////
00486 void GraphicsStateGuardian::
00487 end_scene() {
00488 }
00489 
00490 ////////////////////////////////////////////////////////////////////
00491 //     Function: GraphicsStateGuardian::end_frame
00492 //       Access: Public, Virtual
00493 //  Description: Called after each frame is rendered, to allow the
00494 //               GSG a chance to do any internal cleanup after
00495 //               rendering the frame, and before the window flips.
00496 ////////////////////////////////////////////////////////////////////
00497 void GraphicsStateGuardian::
00498 end_frame() {
00499 }
00500 
00501 ////////////////////////////////////////////////////////////////////
00502 //     Function: GraphicsStateGuardian::wants_normals
00503 //       Access: Public, Virtual
00504 //  Description:
00505 ////////////////////////////////////////////////////////////////////
00506 bool GraphicsStateGuardian::
00507 wants_normals() const {
00508   return _normals_enabled;
00509 }
00510 
00511 ////////////////////////////////////////////////////////////////////
00512 //     Function: GraphicsStateGuardian::wants_texcoords
00513 //       Access: Public, Virtual
00514 //  Description:
00515 ////////////////////////////////////////////////////////////////////
00516 bool GraphicsStateGuardian::
00517 wants_texcoords() const {
00518   return false;
00519 }
00520 
00521 ////////////////////////////////////////////////////////////////////
00522 //     Function: GraphicsStateGuardian::wants_colors
00523 //       Access: Public, Virtual
00524 //  Description: Returns true if the GSG should issue geometry color
00525 //               commands, false otherwise.
00526 ////////////////////////////////////////////////////////////////////
00527 bool GraphicsStateGuardian::
00528 wants_colors() const {
00529   return _vertex_colors_enabled;
00530 }
00531 
00532 ////////////////////////////////////////////////////////////////////
00533 //     Function: GraphicsStateGuardian::depth_offset_decals
00534 //       Access: Public, Virtual
00535 //  Description: Returns true if this GSG can implement decals using a
00536 //               DepthOffsetAttrib, or false if that is unreliable
00537 //               and the three-step rendering process should be used
00538 //               instead.
00539 ////////////////////////////////////////////////////////////////////
00540 bool GraphicsStateGuardian::
00541 depth_offset_decals() {
00542   return false;
00543 }
00544 
00545 ////////////////////////////////////////////////////////////////////
00546 //     Function: GraphicsStateGuardian::begin_decal_base_first
00547 //       Access: Public, Virtual
00548 //  Description: Called during draw to begin a three-step rendering
00549 //               phase to draw decals.  The first step,
00550 //               begin_decal_base_first(), is called prior to drawing the
00551 //               base geometry.  It should set up whatever internal
00552 //               state is appropriate, as well as returning a
00553 //               RenderState object that should be applied to the base
00554 //               geometry for rendering.
00555 ////////////////////////////////////////////////////////////////////
00556 CPT(RenderState) GraphicsStateGuardian::
00557 begin_decal_base_first() {
00558   // Turn off writing the depth buffer to render the base geometry.
00559   static CPT(RenderState) decal_base_first;
00560   if (decal_base_first == (const RenderState *)NULL) {
00561     decal_base_first = RenderState::make
00562       (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
00563        RenderState::get_max_priority());
00564   }
00565   return decal_base_first;
00566 }
00567 
00568 ////////////////////////////////////////////////////////////////////
00569 //     Function: GraphicsStateGuardian::begin_decal_nested
00570 //       Access: Public, Virtual
00571 //  Description: Called during draw to begin a three-step rendering
00572 //               phase to draw decals.  The second step,
00573 //               begin_decal_nested(), is called after drawing the
00574 //               base geometry and prior to drawing any of the nested
00575 //               decal geometry that is to be applied to the base
00576 //               geometry.
00577 ////////////////////////////////////////////////////////////////////
00578 CPT(RenderState) GraphicsStateGuardian::
00579 begin_decal_nested() {
00580   // We should keep the depth buffer off during this operation, so
00581   // that decals on decals will render properly.
00582   static CPT(RenderState) decal_nested;
00583   if (decal_nested == (const RenderState *)NULL) {
00584     decal_nested = RenderState::make
00585       (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
00586        RenderState::get_max_priority());
00587   }
00588   return decal_nested;
00589 }
00590 
00591 ////////////////////////////////////////////////////////////////////
00592 //     Function: GraphicsStateGuardian::begin_decal_base_second
00593 //       Access: Public, Virtual
00594 //  Description: Called during draw to begin a three-step rendering
00595 //               phase to draw decals.  The third step,
00596 //               begin_decal_base_second(), is called after drawing the
00597 //               base geometry and the nested decal geometry, and
00598 //               prior to drawing the base geometry one more time (if
00599 //               needed).
00600 //
00601 //               It should return a RenderState object appropriate for
00602 //               rendering the base geometry the second time, or NULL
00603 //               if it is not necessary to re-render the base
00604 //               geometry.
00605 ////////////////////////////////////////////////////////////////////
00606 CPT(RenderState) GraphicsStateGuardian::
00607 begin_decal_base_second() {
00608   // Now let the depth buffer go back on, but turn off writing the
00609   // color buffer to render the base geometry after the second pass.
00610   // Also, turn off texturing since there's no need for it now.
00611   static CPT(RenderState) decal_base_second;
00612   if (decal_base_second == (const RenderState *)NULL) {
00613     decal_base_second = RenderState::make
00614       (ColorWriteAttrib::make(ColorWriteAttrib::M_off),
00615        // On reflection, we need to leave texturing on so the alpha
00616        // test mechanism can work (if it is enabled, e.g. we are
00617        // rendering an object with M_dual transparency).
00618        //       TextureAttrib::make_off(),
00619        RenderState::get_max_priority());
00620   }
00621   return decal_base_second;
00622 }
00623 
00624 ////////////////////////////////////////////////////////////////////
00625 //     Function: GraphicsStateGuardian::finish_decal
00626 //       Access: Public, Virtual
00627 //  Description: Called during draw to clean up after decals are
00628 //               finished.
00629 ////////////////////////////////////////////////////////////////////
00630 void GraphicsStateGuardian::
00631 finish_decal() {
00632   // No need to do anything special here.
00633 }
00634 
00635 ////////////////////////////////////////////////////////////////////
00636 //     Function: GraphicsStateGuardian::get_internal_coordinate_system
00637 //       Access: Public, Virtual
00638 //  Description: Should be overridden by derived classes to return the
00639 //               coordinate system used internally by the GSG, if any
00640 //               one particular coordinate system is used.  The
00641 //               default, CS_default, indicates that the GSG can use
00642 //               any coordinate system.
00643 //
00644 //               If this returns other than CS_default, the
00645 //               GraphicsEngine will automatically convert all
00646 //               transforms into the indicated coordinate system.
00647 ////////////////////////////////////////////////////////////////////
00648 CoordinateSystem GraphicsStateGuardian::
00649 get_internal_coordinate_system() const {
00650   return CS_default;
00651 }
00652 
00653 ////////////////////////////////////////////////////////////////////
00654 //     Function: GraphicsStateGuardian::issue_transform
00655 //       Access: Public, Virtual
00656 //  Description: Sends the indicated transform matrix to the graphics
00657 //               API to be applied to future vertices.
00658 ////////////////////////////////////////////////////////////////////
00659 void GraphicsStateGuardian::
00660 issue_transform(const TransformState *) {
00661 }
00662 
00663 ////////////////////////////////////////////////////////////////////
00664 //     Function: GraphicsStateGuardian::issue_color_scale
00665 //       Access: Public, Virtual
00666 //  Description:
00667 ////////////////////////////////////////////////////////////////////
00668 void GraphicsStateGuardian::
00669 issue_color_scale(const ColorScaleAttrib *attrib) {
00670   _current_color_scale = attrib->get_scale();
00671 
00672   if (_current_color_scale == LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f)) {
00673     _color_transform_enabled &= ~CT_scale;
00674   } else {
00675     _color_transform_enabled |= CT_scale;
00676   }
00677 
00678   _scene_graph_color_stale = _has_scene_graph_color;
00679 }
00680 
00681 ////////////////////////////////////////////////////////////////////
00682 //     Function: GraphicsStateGuardian::issue_color
00683 //       Access: Public, Virtual
00684 //  Description: This method is defined in the base class because it
00685 //               is likely that this functionality will be used for
00686 //               all (or at least most) kinds of
00687 //               GraphicsStateGuardians--it's not specific to any one
00688 //               rendering backend.
00689 //
00690 //               The ColorAttribute just changes the interpretation of
00691 //               the color on the vertices, and fiddles with
00692 //               _vertex_colors_enabled, etc.
00693 ////////////////////////////////////////////////////////////////////
00694 void GraphicsStateGuardian::
00695 issue_color(const ColorAttrib *attrib) {
00696   switch (attrib->get_color_type()) {
00697   case ColorAttrib::T_flat:
00698     // Color attribute flat: it specifies a scene graph color that
00699     // overrides the vertex color.
00700     _scene_graph_color = attrib->get_color();
00701     _has_scene_graph_color = true;
00702     _vertex_colors_enabled = false;
00703     _scene_graph_color_stale = true;
00704     break;
00705 
00706   case ColorAttrib::T_off:
00707     // Color attribute off: it specifies that no scene graph color is
00708     // in effect, and vertex color is not important either.
00709     _has_scene_graph_color = false;
00710     _scene_graph_color_stale = false;
00711     _vertex_colors_enabled = false;
00712     break;
00713 
00714   case ColorAttrib::T_vertex:
00715     // Color attribute vertex: it specifies that vertex color should
00716     // be revealed.
00717     _has_scene_graph_color = false;
00718     _scene_graph_color_stale = false;
00719     _vertex_colors_enabled = true;
00720     break;
00721   }
00722 }
00723 
00724 ////////////////////////////////////////////////////////////////////
00725 //     Function: GraphicsStateGuardian::issue_light
00726 //       Access: Public, Virtual
00727 //  Description: The default implementation of issue_light() assumes
00728 //               we have a limited number of hardware lights
00729 //               available.  This function assigns each light to a
00730 //               different hardware light id, trying to keep each
00731 //               light associated with the same id where possible, but
00732 //               reusing id's when necessary.  When it is no longer
00733 //               possible to reuse existing id's (e.g. all id's are in
00734 //               use), slot_new_light() is called to prepare the next
00735 //               sequential light id.
00736 //
00737 //               It will call apply_light() each time a light is
00738 //               assigned to a particular id for the first time in a
00739 //               given frame, and it will subsequently call
00740 //               enable_light() to enable or disable each light as the
00741 //               frame is rendered, as well as enable_lighting() to
00742 //               enable or disable overall lighting.
00743 //
00744 //               If this model of hardware lights with id's does not
00745 //               apply to a particular graphics engine, it should
00746 //               override this function to do something more
00747 //               appropriate instead.
00748 ////////////////////////////////////////////////////////////////////
00749 void GraphicsStateGuardian::
00750 issue_light(const LightAttrib *attrib) {
00751   // Initialize the current ambient light total and newly enabled
00752   // light list
00753   Colorf cur_ambient_light(0.0f, 0.0f, 0.0f, 1.0f);
00754   int i;
00755   int max_lights = (int)_light_info.size();
00756   for (i = 0; i < max_lights; i++) {
00757     _light_info[i]._next_enabled = false;
00758   }
00759 
00760   bool any_bound = false;
00761 
00762   int num_enabled = 0;
00763   int num_lights = attrib->get_num_lights();
00764   if (attrib->get_operation() == LightAttrib::O_remove) {
00765     num_lights = 0;
00766   }
00767   for (int li = 0; li < num_lights; li++) {
00768     Light *light = attrib->get_light(li);
00769     nassertv(light != (Light *)NULL);
00770 
00771     num_enabled++;
00772 
00773     // Lighting should be enabled before we apply any lights.
00774     enable_lighting(true);
00775     _lighting_enabled = true;
00776     _lighting_enabled_this_frame = true;
00777 
00778     if (light->get_type() == AmbientLight::get_class_type()) {
00779       // Ambient lights don't require specific light ids; simply add
00780       // in the ambient contribution to the current total
00781       cur_ambient_light += light->get_color();
00782         
00783     } else {
00784       // Check to see if this light has already been bound to an id
00785       int cur_light_id = -1;
00786       for (i = 0; i < max_lights; i++) {
00787         if (_light_info[i]._light == light) {
00788           // Light has already been bound to an id, we only need to
00789           // enable the light, not reapply it.
00790           cur_light_id = -2;
00791           enable_light(i, true);
00792           _light_info[i]._enabled = true;
00793           _light_info[i]._next_enabled = true;
00794           break;
00795         }
00796       }
00797         
00798       // See if there are any unbound light ids
00799       if (cur_light_id == -1) {
00800         for (i = 0; i < max_lights; i++) {
00801           if (_light_info[i]._light == (Light *)NULL) {
00802             _light_info[i]._light = light;
00803             cur_light_id = i;
00804             break;
00805           }
00806         }
00807       }
00808         
00809       // If there were no unbound light ids, see if we can replace
00810       // a currently unused but previously bound id
00811       if (cur_light_id == -1) {
00812         for (i = 0; i < max_lights; i++) {
00813           if (!attrib->has_light(_light_info[i]._light)) {
00814             _light_info[i]._light = light;
00815             cur_light_id = i;
00816             break;
00817           }
00818         }
00819       }
00820 
00821       // If we *still* don't have a light id, slot a new one.
00822       if (cur_light_id == -1) {
00823         if (slot_new_light(max_lights)) {
00824           cur_light_id = max_lights;
00825           _light_info.push_back(LightInfo());
00826           max_lights++;
00827           nassertv(max_lights == (int)_light_info.size());
00828         }
00829       }
00830         
00831       if (cur_light_id >= 0) {
00832         enable_light(cur_light_id, true);
00833         _light_info[cur_light_id]._enabled = true;
00834         _light_info[cur_light_id]._next_enabled = true;
00835         
00836         if (!any_bound) {
00837           begin_bind_lights();
00838           any_bound = true;
00839         }
00840 
00841         // This is the first time this frame that this light has been
00842         // bound to this particular id.
00843         light->bind(this, cur_light_id);
00844 
00845       } else if (cur_light_id == -1) {
00846         gsg_cat.warning()
00847           << "Failed to bind " << *light << " to id.\n";
00848       }
00849     }
00850   }
00851 
00852   // Disable all unused lights
00853   for (i = 0; i < max_lights; i++) {
00854     if (!_light_info[i]._next_enabled) {
00855       enable_light(i, false);
00856       _light_info[i]._enabled = false;
00857     }
00858   }
00859 
00860   // If no lights were enabled, disable lighting
00861   if (num_enabled == 0) {
00862     enable_lighting(false);
00863     _lighting_enabled = false;
00864   } else {
00865     set_ambient_light(cur_ambient_light);
00866   }
00867 
00868   if (any_bound) {
00869     end_bind_lights();
00870   }
00871 }
00872 
00873 ////////////////////////////////////////////////////////////////////
00874 //     Function: GraphicsStateGuardian::issue_color_write
00875 //       Access: Public, Virtual
00876 //  Description:
00877 ////////////////////////////////////////////////////////////////////
00878 void GraphicsStateGuardian::
00879 issue_color_write(const ColorWriteAttrib *attrib) {
00880   _color_write_mode = attrib->get_mode();
00881   set_blend_mode(_color_write_mode, _color_blend_mode, _transparency_mode);
00882 }
00883 
00884 ////////////////////////////////////////////////////////////////////
00885 //     Function: GraphicsStateGuardian::issue_transparency
00886 //       Access: Public, Virtual
00887 //  Description:
00888 ////////////////////////////////////////////////////////////////////
00889 void GraphicsStateGuardian::
00890 issue_transparency(const TransparencyAttrib *attrib) {
00891   _transparency_mode = attrib->get_mode();
00892   set_blend_mode(_color_write_mode, _color_blend_mode, _transparency_mode);
00893 }
00894 
00895 ////////////////////////////////////////////////////////////////////
00896 //     Function: GraphicsStateGuardian::issue_color_blend
00897 //       Access: Public, Virtual
00898 //  Description:
00899 ////////////////////////////////////////////////////////////////////
00900 void GraphicsStateGuardian::
00901 issue_color_blend(const ColorBlendAttrib *attrib) {
00902   _color_blend_mode = attrib->get_mode();
00903   set_blend_mode(_color_write_mode, _color_blend_mode, _transparency_mode);
00904 }
00905 
00906 ////////////////////////////////////////////////////////////////////
00907 //     Function: GraphicsStateGuardian::issue_clip_plane
00908 //       Access: Public, Virtual
00909 //  Description: This is fundametically similar to issue_light(), with
00910 //               calls to slot_new_clip_plane(), apply_clip_plane(),
00911 //               and enable_clip_planes(), as appropriate.
00912 ////////////////////////////////////////////////////////////////////
00913 void GraphicsStateGuardian::
00914 issue_clip_plane(const ClipPlaneAttrib *attrib) {
00915   int i;
00916   int max_planes = (int)_clip_plane_info.size();
00917   for (i = 0; i < max_planes; i++) {
00918     _clip_plane_info[i]._next_enabled = false;
00919   }
00920 
00921   bool any_bound = false;
00922 
00923   int num_enabled = 0;
00924   int num_planes = attrib->get_num_planes();
00925   if (attrib->get_operation() == ClipPlaneAttrib::O_remove) {
00926     num_planes = 0;
00927   }
00928   for (int li = 0; li < num_planes; li++) {
00929     PlaneNode *plane = attrib->get_plane(li);
00930     nassertv(plane != (PlaneNode *)NULL);
00931 
00932     num_enabled++;
00933 
00934     // Planeing should be enabled before we apply any planes.
00935     enable_clip_planes(true);
00936     _clip_planes_enabled = true;
00937     _clip_planes_enabled_this_frame = true;
00938 
00939     // Check to see if this plane has already been bound to an id
00940     int cur_plane_id = -1;
00941     for (i = 0; i < max_planes; i++) {
00942       if (_clip_plane_info[i]._plane == plane) {
00943         // Plane has already been bound to an id, we only need to
00944         // enable the plane, not reapply it.
00945         cur_plane_id = -2;
00946         enable_clip_plane(i, true);
00947         _clip_plane_info[i]._enabled = true;
00948         _clip_plane_info[i]._next_enabled = true;
00949         break;
00950       }
00951     }
00952         
00953     // See if there are any unbound plane ids
00954     if (cur_plane_id == -1) {
00955       for (i = 0; i < max_planes; i++) {
00956         if (_clip_plane_info[i]._plane == (PlaneNode *)NULL) {
00957           _clip_plane_info[i]._plane = plane;
00958           cur_plane_id = i;
00959           break;
00960         }
00961       }
00962     }
00963         
00964     // If there were no unbound plane ids, see if we can replace
00965     // a currently unused but previously bound id
00966     if (cur_plane_id == -1) {
00967       for (i = 0; i < max_planes; i++) {
00968         if (!attrib->has_plane(_clip_plane_info[i]._plane)) {
00969           _clip_plane_info[i]._plane = plane;
00970           cur_plane_id = i;
00971           break;
00972         }
00973       }
00974     }
00975 
00976     // If we *still* don't have a plane id, slot a new one.
00977     if (cur_plane_id == -1) {
00978       if (slot_new_clip_plane(max_planes)) {
00979         cur_plane_id = max_planes;
00980         _clip_plane_info.push_back(ClipPlaneInfo());
00981         max_planes++;
00982         nassertv(max_planes == (int)_clip_plane_info.size());
00983       }
00984     }
00985         
00986     if (cur_plane_id >= 0) {
00987       enable_clip_plane(cur_plane_id, true);
00988       _clip_plane_info[cur_plane_id]._enabled = true;
00989       _clip_plane_info[cur_plane_id]._next_enabled = true;
00990       
00991       if (!any_bound) {
00992         begin_bind_clip_planes();
00993         any_bound = true;
00994       }
00995       
00996       // This is the first time this frame that this plane has been
00997       // bound to this particular id.
00998       bind_clip_plane(plane, cur_plane_id);
00999       
01000     } else if (cur_plane_id == -1) {
01001       gsg_cat.warning()
01002         << "Failed to bind " << *plane << " to id.\n";
01003     }
01004   }
01005 
01006   // Disable all unused planes
01007   for (i = 0; i < max_planes; i++) {
01008     if (!_clip_plane_info[i]._next_enabled) {
01009       enable_clip_plane(i, false);
01010       _clip_plane_info[i]._enabled = false;
01011     }
01012   }
01013 
01014   // If no planes were enabled, disable clip planes in general.
01015   if (num_enabled == 0) {
01016     enable_clip_planes(false);
01017     _clip_planes_enabled = false;
01018   }
01019 
01020   if (any_bound) {
01021     end_bind_clip_planes();
01022   }
01023 }
01024 
01025 ////////////////////////////////////////////////////////////////////
01026 //     Function: GraphicsStateGuardian::bind_light
01027 //       Access: Public, Virtual
01028 //  Description: Called the first time a particular light has been
01029 //               bound to a given id within a frame, this should set
01030 //               up the associated hardware light with the light's
01031 //               properties.
01032 ////////////////////////////////////////////////////////////////////
01033 void GraphicsStateGuardian::
01034 bind_light(PointLight *light, int light_id) {
01035 }
01036 
01037 ////////////////////////////////////////////////////////////////////
01038 //     Function: GraphicsStateGuardian::bind_light
01039 //       Access: Public, Virtual
01040 //  Description: Called the first time a particular light has been
01041 //               bound to a given id within a frame, this should set
01042 //               up the associated hardware light with the light's
01043 //               properties.
01044 ////////////////////////////////////////////////////////////////////
01045 void GraphicsStateGuardian::
01046 bind_light(DirectionalLight *light, int light_id) {
01047 }
01048 
01049 ////////////////////////////////////////////////////////////////////
01050 //     Function: GraphicsStateGuardian::bind_light
01051 //       Access: Public, Virtual
01052 //  Description: Called the first time a particular light has been
01053 //               bound to a given id within a frame, this should set
01054 //               up the associated hardware light with the light's
01055 //               properties.
01056 ////////////////////////////////////////////////////////////////////
01057 void GraphicsStateGuardian::
01058 bind_light(Spotlight *light, int light_id) {
01059 }
01060 
01061 ////////////////////////////////////////////////////////////////////
01062 //     Function: GraphicsStateGuardian::slot_new_light
01063 //       Access: Protected, Virtual
01064 //  Description: This will be called by the base class before a
01065 //               particular light id will be used for the first time.
01066 //               It is intended to allow the derived class to reserve
01067 //               any additional resources, if required, for the new
01068 //               light; and also to indicate whether the hardware
01069 //               supports this many simultaneous lights.
01070 //
01071 //               The return value should be true if the additional
01072 //               light is supported, or false if it is not.
01073 ////////////////////////////////////////////////////////////////////
01074 bool GraphicsStateGuardian::
01075 slot_new_light(int light_id) {
01076   return true;
01077 }
01078 
01079 ////////////////////////////////////////////////////////////////////
01080 //     Function: GraphicsStateGuardian::enable_lighting
01081 //       Access: Protected, Virtual
01082 //  Description: Intended to be overridden by a derived class to
01083 //               enable or disable the use of lighting overall.  This
01084 //               is called by issue_light() according to whether any
01085 //               lights are in use or not.
01086 ////////////////////////////////////////////////////////////////////
01087 void GraphicsStateGuardian::
01088 enable_lighting(bool enable) {
01089 }
01090 
01091 ////////////////////////////////////////////////////////////////////
01092 //     Function: GraphicsStateGuardian::set_ambient_light
01093 //       Access: Protected, Virtual
01094 //  Description: Intended to be overridden by a derived class to
01095 //               indicate the color of the ambient light that should
01096 //               be in effect.  This is called by issue_light() after
01097 //               all other lights have been enabled or disabled.
01098 ////////////////////////////////////////////////////////////////////
01099 void GraphicsStateGuardian::
01100 set_ambient_light(const Colorf &color) {
01101 }
01102 
01103 ////////////////////////////////////////////////////////////////////
01104 //     Function: GraphicsStateGuardian::enable_light
01105 //       Access: Protected, Virtual
01106 //  Description: Intended to be overridden by a derived class to
01107 //               enable the indicated light id.  A specific Light will
01108 //               already have been bound to this id via bind_light().
01109 ////////////////////////////////////////////////////////////////////
01110 void GraphicsStateGuardian::
01111 enable_light(int light_id, bool enable) {
01112 }
01113 
01114 ////////////////////////////////////////////////////////////////////
01115 //     Function: GraphicsStateGuardian::begin_bind_lights
01116 //       Access: Protected, Virtual
01117 //  Description: Called immediately before bind_light() is called,
01118 //               this is intended to provide the derived class a hook
01119 //               in which to set up some state (like transform) that
01120 //               might apply to several lights.
01121 //
01122 //               The sequence is: begin_bind_lights() will be called,
01123 //               then one or more bind_light() calls, then
01124 //               end_bind_lights().
01125 ////////////////////////////////////////////////////////////////////
01126 void GraphicsStateGuardian::
01127 begin_bind_lights() {
01128 }
01129 
01130 ////////////////////////////////////////////////////////////////////
01131 //     Function: GraphicsStateGuardian::end_bind_lights
01132 //       Access: Protected, Virtual
01133 //  Description: Called after before bind_light() has been called one
01134 //               or more times (but before any geometry is issued or
01135 //               additional state is changed), this is intended to
01136 //               clean up any temporary changes to the state that may
01137 //               have been made by begin_bind_lights().
01138 ////////////////////////////////////////////////////////////////////
01139 void GraphicsStateGuardian::
01140 end_bind_lights() {
01141 }
01142 
01143 ////////////////////////////////////////////////////////////////////
01144 //     Function: GraphicsStateGuardian::slot_new_clip_plane
01145 //       Access: Protected, Virtual
01146 //  Description: This will be called by the base class before a
01147 //               particular clip plane id will be used for the first
01148 //               time.  It is intended to allow the derived class to
01149 //               reserve any additional resources, if required, for
01150 //               the new clip plane; and also to indicate whether the
01151 //               hardware supports this many simultaneous clipping
01152 //               planes.
01153 //
01154 //               The return value should be true if the additional
01155 //               plane is supported, or false if it is not.
01156 ////////////////////////////////////////////////////////////////////
01157 bool GraphicsStateGuardian::
01158 slot_new_clip_plane(int plane_id) {
01159   return true;
01160 }
01161 
01162 ////////////////////////////////////////////////////////////////////
01163 //     Function: GraphicsStateGuardian::enable_clip_planes
01164 //       Access: Protected, Virtual
01165 //  Description: Intended to be overridden by a derived class to
01166 //               enable or disable the use of clipping planes overall.
01167 //               This is called by issue_clip_plane() according to
01168 //               whether any planes are in use or not.
01169 ////////////////////////////////////////////////////////////////////
01170 void GraphicsStateGuardian::
01171 enable_clip_planes(bool enable) {
01172 }
01173 
01174 ////////////////////////////////////////////////////////////////////
01175 //     Function: GraphicsStateGuardian::enable_clip_plane
01176 //       Access: Protected, Virtual
01177 //  Description: Intended to be overridden by a derived class to
01178 //               enable the indicated plane id.  A specific PlaneNode
01179 //               will already have been bound to this id via
01180 //               bind_clip_plane().
01181 ////////////////////////////////////////////////////////////////////
01182 void GraphicsStateGuardian::
01183 enable_clip_plane(int plane_id, bool enable) {
01184 }
01185 
01186 ////////////////////////////////////////////////////////////////////
01187 //     Function: GraphicsStateGuardian::begin_bind_clip_planes
01188 //       Access: Protected, Virtual
01189 //  Description: Called immediately before bind_clip_plane() is called,
01190 //               this is intended to provide the derived class a hook
01191 //               in which to set up some state (like transform) that
01192 //               might apply to several planes.
01193 //
01194 //               The sequence is: begin_bind_clip_planes() will be
01195 //               called, then one or more bind_clip_plane() calls,
01196 //               then end_bind_clip_planes().
01197 ////////////////////////////////////////////////////////////////////
01198 void GraphicsStateGuardian::
01199 begin_bind_clip_planes() {
01200 }
01201 
01202 ////////////////////////////////////////////////////////////////////
01203 //     Function: GraphicsStateGuardian::bind_clip_plane
01204 //       Access: Public, Virtual
01205 //  Description: Called the first time a particular clipping plane has been
01206 //               bound to a given id within a frame, this should set
01207 //               up the associated hardware (or API) clipping plane
01208 //               with the plane's properties.
01209 ////////////////////////////////////////////////////////////////////
01210 void GraphicsStateGuardian::
01211 bind_clip_plane(PlaneNode *plane, int plane_id) {
01212 }
01213 
01214 ////////////////////////////////////////////////////////////////////
01215 //     Function: GraphicsStateGuardian::end_bind_clip_planes
01216 //       Access: Protected, Virtual
01217 //  Description: Called after before bind_clip_plane() has been called one
01218 //               or more times (but before any geometry is issued or
01219 //               additional state is changed), this is intended to
01220 //               clean up any temporary changes to the state that may
01221 //               have been made by begin_bind_clip_planes().
01222 ////////////////////////////////////////////////////////////////////
01223 void GraphicsStateGuardian::
01224 end_bind_clip_planes() {
01225 }
01226 
01227 ////////////////////////////////////////////////////////////////////
01228 //     Function: GraphicsStateGuardian::set_blend_mode
01229 //       Access: Protected, Virtual
01230 //  Description: Called after any of these three blending states have
01231 //               changed; this function is responsible for setting the
01232 //               appropriate color blending mode based on the given
01233 //               properties.
01234 ////////////////////////////////////////////////////////////////////
01235 void GraphicsStateGuardian::
01236 set_blend_mode(ColorWriteAttrib::Mode, ColorBlendAttrib::Mode,
01237                TransparencyAttrib::Mode) {
01238 }
01239 
01240 ////////////////////////////////////////////////////////////////////
01241 //     Function: GraphicsStateGuardian::mark_prepared_texture
01242 //       Access: Protected
01243 //  Description: This is intended to be called from within
01244 //               prepare_texture().  It adds the indicated
01245 //               TextureContext pointer to the _prepared_textures set,
01246 //               and returns true if it was successfully added
01247 //               (i.e. it was not already in the set).
01248 ////////////////////////////////////////////////////////////////////
01249 bool GraphicsStateGuardian::
01250 mark_prepared_texture(TextureContext *tc) {
01251   bool prepared = _prepared_textures.insert(tc).second;
01252 #ifdef DO_PSTATS
01253   if (prepared) {
01254     _total_texusage_pcollector.add_level(tc->estimate_texture_memory());
01255   }
01256 #endif
01257   return prepared;
01258 }
01259 
01260 ////////////////////////////////////////////////////////////////////
01261 //     Function: GraphicsStateGuardian::unmark_prepared_texture
01262 //       Access: Protected
01263 //  Description: This is intended to be called from within
01264 //               release_texture().  It removes the indicated
01265 //               TextureContext pointer from the _prepared_textures
01266 //               set, and returns true if it was successfully removed
01267 //               (i.e. it had been in the set).
01268 ////////////////////////////////////////////////////////////////////
01269 bool GraphicsStateGuardian::
01270 unmark_prepared_texture(TextureContext *tc) {
01271   bool removed = (_prepared_textures.erase(tc) != 0);
01272 #ifdef DO_PSTATS
01273   if (removed) {
01274     _total_texusage_pcollector.sub_level(tc->estimate_texture_memory());
01275   }
01276 #endif
01277   return removed;
01278 }
01279 
01280 ////////////////////////////////////////////////////////////////////
01281 //     Function: GraphicsStateGuardian::mark_prepared_geom
01282 //       Access: Protected
01283 //  Description: This is intended to be called from within
01284 //               prepare_geom().  It adds the indicated GeomContext
01285 //               pointer to the _prepared_geoms set, and returns true
01286 //               if it was successfully added (i.e. it was not already
01287 //               in the set).
01288 ////////////////////////////////////////////////////////////////////
01289 bool GraphicsStateGuardian::
01290 mark_prepared_geom(GeomContext *gc) {
01291   bool prepared = _prepared_geoms.insert(gc).second;
01292 #ifdef DO_PSTATS
01293   if (prepared) {
01294     _total_geom_pcollector.add_level(1);
01295   }
01296 #endif
01297   return prepared;
01298 }
01299 
01300 ////////////////////////////////////////////////////////////////////
01301 //     Function: GraphicsStateGuardian::unmark_prepared_geom
01302 //       Access: Protected
01303 //  Description: This is intended to be called from within
01304 //               release_geom().  It removes the indicated GeomContext
01305 //               pointer from the _prepared_geoms set, and returns
01306 //               true if it was successfully removed (i.e. it had been
01307 //               in the set).
01308 ////////////////////////////////////////////////////////////////////
01309 bool GraphicsStateGuardian::
01310 unmark_prepared_geom(GeomContext *gc) {
01311   bool removed = (_prepared_geoms.erase(gc) != 0);
01312 #ifdef DO_PSTATS
01313   if (removed) {
01314     _total_geom_pcollector.sub_level(1);
01315   }
01316 #endif
01317   return removed;
01318 }
01319 
01320 ////////////////////////////////////////////////////////////////////
01321 //     Function: GraphicsStateGuardian::mark_prepared_geom_node
01322 //       Access: Protected
01323 //  Description: This is intended to be called from within
01324 //               prepare_geom_node().  It adds the indicated
01325 //               GeomNodeContext pointer to the _prepared_geom_nodes
01326 //               set, and returns true if it was successfully added
01327 //               (i.e. it was not already in the set).
01328 ////////////////////////////////////////////////////////////////////
01329 bool GraphicsStateGuardian::
01330 mark_prepared_geom_node(GeomNodeContext *gnc) {
01331   bool prepared = _prepared_geom_nodes.insert(gnc).second;
01332 #ifdef DO_PSTATS
01333   if (prepared) {
01334     _total_geom_node_pcollector.add_level(1);
01335   }
01336 #endif
01337   return prepared;
01338 }
01339 
01340 ////////////////////////////////////////////////////////////////////
01341 //     Function: GraphicsStateGuardian::unmark_prepared_geom_node
01342 //       Access: Protected
01343 //  Description: This is intended to be called from within
01344 //               release_geom_node().  It removes the indicated
01345 //               GeomNodeContext pointer from the _prepared_geom_nodes
01346 //               set, and returns true if it was successfully removed
01347 //               (i.e. it had been in the set).
01348 ////////////////////////////////////////////////////////////////////
01349 bool GraphicsStateGuardian::
01350 unmark_prepared_geom_node(GeomNodeContext *gnc) {
01351   bool removed = (_prepared_geom_nodes.erase(gnc) != 0);
01352 #ifdef DO_PSTATS
01353   if (removed) {
01354     _total_geom_node_pcollector.sub_level(1);
01355   }
01356 #endif
01357   return removed;
01358 }
01359 
01360 ////////////////////////////////////////////////////////////////////
01361 //     Function: GraphicsStateGuardian::free_pointers
01362 //       Access: Protected, Virtual
01363 //  Description: Frees some memory that was explicitly allocated
01364 //               within the glgsg.
01365 ////////////////////////////////////////////////////////////////////
01366 void GraphicsStateGuardian::
01367 free_pointers() {
01368 }
01369 
01370 ////////////////////////////////////////////////////////////////////
01371 //     Function: GraphicsStateGuardian::close_gsg
01372 //       Access: Protected, Virtual
01373 //  Description: This is called by the associated GraphicsWindow when
01374 //               close_window() is called.  It should null out the
01375 //               _win pointer and possibly free any open resources
01376 //               associated with the GSG.
01377 ////////////////////////////////////////////////////////////////////
01378 void GraphicsStateGuardian::
01379 close_gsg() {
01380   _closing_gsg = true;
01381   free_pointers();
01382   release_all_textures();
01383   release_all_geoms();
01384 }
01385 
01386 #ifdef DO_PSTATS
01387 
01388 ////////////////////////////////////////////////////////////////////
01389 //     Function: GraphicsStateGuardian::init_frame_pstats
01390 //       Access: Protected
01391 //  Description: Initializes the relevant PStats data at the beginning
01392 //               of the frame.
01393 ////////////////////////////////////////////////////////////////////
01394 void GraphicsStateGuardian::
01395 init_frame_pstats() {
01396   if (PStatClient::is_connected()) {
01397     _current_textures.clear();
01398     _current_geoms.clear();
01399     _current_geom_nodes.clear();
01400     _active_texusage_pcollector.clear_level();
01401     _active_geom_pcollector.clear_level();
01402     _active_geom_node_pcollector.clear_level();
01403     
01404     // Also clear out our other counters while we're here.
01405     _vertices_tristrip_pcollector.clear_level();
01406     _vertices_trifan_pcollector.clear_level();
01407     _vertices_tri_pcollector.clear_level();
01408     _vertices_other_pcollector.clear_level();
01409     
01410     _state_changes_pcollector.clear_level();
01411     _transform_state_pcollector.clear_level();
01412     _texture_state_pcollector.clear_level();
01413     
01414     _nodes_pcollector.clear_level();
01415     _geom_nodes_pcollector.clear_level();
01416     
01417     // Not to mention the view-frustum-cull counters.
01418     _frustum_cull_volumes_pcollector.clear_level();
01419     _frustum_cull_transforms_pcollector.clear_level();
01420     
01421     _transform_states_pcollector.set_level(TransformState::get_num_states());
01422     _render_states_pcollector.set_level(RenderState::get_num_states());
01423     if (pstats_unused_states) {
01424       _transform_states_unused_pcollector.set_level(TransformState::get_num_unused_states());
01425       _render_states_unused_pcollector.set_level(RenderState::get_num_unused_states());
01426     }
01427   }
01428 }
01429 
01430 ////////////////////////////////////////////////////////////////////
01431 //     Function: GraphicsStateGuardian::add_to_texture_record
01432 //       Access: Protected
01433 //  Description: Records that the indicated texture has been applied
01434 //               this frame, and thus must be present in current
01435 //               texture memory.  This function is only used to update
01436 //               the PStats current_texmem collector; it gets compiled
01437 //               out if we aren't using PStats.
01438 ////////////////////////////////////////////////////////////////////
01439 void GraphicsStateGuardian::
01440 add_to_texture_record(TextureContext *tc) {
01441   if (PStatClient::is_connected()) {
01442     if (_current_textures.insert(tc).second) {
01443       _active_texusage_pcollector.add_level(tc->estimate_texture_memory());
01444     }
01445   }
01446 }
01447 
01448 ////////////////////////////////////////////////////////////////////
01449 //     Function: GraphicsStateGuardian::add_to_geom_record
01450 //       Access: Protected
01451 //  Description: Records that the indicated Geom has been drawn this
01452 //               frame.  This function is only used to update the
01453 //               PStats current_texmem collector; it gets compiled out
01454 //               if we aren't using PStats.
01455 ////////////////////////////////////////////////////////////////////
01456 void GraphicsStateGuardian::
01457 add_to_geom_record(GeomContext *gc) {
01458   if (PStatClient::is_connected()) {
01459     if (gc != (GeomContext *)NULL && _current_geoms.insert(gc).second) {
01460       _active_geom_pcollector.add_level(1);
01461     }
01462   }
01463 }
01464 
01465 ////////////////////////////////////////////////////////////////////
01466 //     Function: GraphicsStateGuardian::add_to_geom_node_record
01467 //       Access: Protected
01468 //  Description: Records that the indicated GeomNode has been drawn
01469 //               this frame.  This function is only used to update the
01470 //               PStats current_texmem collector; it gets compiled out
01471 //               if we aren't using PStats.
01472 ////////////////////////////////////////////////////////////////////
01473 void GraphicsStateGuardian::
01474 add_to_geom_node_record(GeomNodeContext *gnc) {
01475   if (PStatClient::is_connected()) {
01476     if (gnc != (GeomNodeContext *)NULL && 
01477         _current_geom_nodes.insert(gnc).second) {
01478       _active_geom_node_pcollector.add_level(1);
01479     }
01480   }
01481 }
01482 
01483 ////////////////////////////////////////////////////////////////////
01484 //     Function: GraphicsStateGuardian::record_state_change
01485 //       Access: Protected
01486 //  Description: Indicates a state change request for a property of
01487 //               the given type.
01488 ////////////////////////////////////////////////////////////////////
01489 void GraphicsStateGuardian::
01490 record_state_change(TypeHandle type) {
01491   _state_changes_pcollector.add_level(1);
01492 
01493   // We can't use the get_class_type() methods since we don't have
01494   // those header files available yet.
01495   string name = type.get_name();
01496   if (name == "TransformTransition") {
01497     _transform_state_pcollector.add_level(1);
01498   } else if (name == "TextureTransition") {
01499     _texture_state_pcollector.add_level(1);
01500   }
01501 }
01502 #endif  // DO_PSTATS
01503 
01504 ////////////////////////////////////////////////////////////////////
01505 //     Function: GraphicsStateGuardian::get_unlit_state
01506 //       Access: Protected, Static
01507 //  Description: 
01508 ////////////////////////////////////////////////////////////////////
01509 CPT(RenderState) GraphicsStateGuardian::
01510 get_unlit_state() {
01511   static CPT(RenderState) state = NULL;
01512   if (state == (const RenderState *)NULL) {
01513     state = RenderState::make(LightAttrib::make_all_off());
01514   }
01515   return state;
01516 }
01517 
01518 ////////////////////////////////////////////////////////////////////
01519 //     Function: GraphicsStateGuardian::get_unclipped_state
01520 //       Access: Protected, Static
01521 //  Description: 
01522 ////////////////////////////////////////////////////////////////////
01523 CPT(RenderState) GraphicsStateGuardian::
01524 get_unclipped_state() {
01525   static CPT(RenderState) state = NULL;
01526   if (state == (const RenderState *)NULL) {
01527     state = RenderState::make(ClipPlaneAttrib::make_all_off());
01528   }
01529   return state;
01530 }
01531 
01532 ////////////////////////////////////////////////////////////////////
01533 //     Function: GraphicsStateGuardian::get_untextured_state
01534 //       Access: Protected, Static
01535 //  Description: 
01536 ////////////////////////////////////////////////////////////////////
01537 CPT(RenderState) GraphicsStateGuardian::
01538 get_untextured_state() {
01539   static CPT(RenderState) state = NULL;
01540   if (state == (const RenderState *)NULL) {
01541     state = RenderState::make(TextureAttrib::make_off());
01542   }
01543   return state;
01544 }
01545 
01546 void GraphicsStateGuardian::
01547 traverse_prepared_textures(bool (*pertex_callbackfn)(TextureContext *,void *),void *callback_arg) {
01548   for (Textures::const_iterator ti = _prepared_textures.begin(); ti != _prepared_textures.end();
01549        ++ti) {
01550     bool bResult=(*pertex_callbackfn)(*ti,callback_arg);
01551     if(!bResult)
01552       return;
01553   }
01554 }

Generated on Fri May 2 00:36:30 2003 for Panda by doxygen1.3