graphicsStateGuardian.cxx
00001 // Filename: graphicsStateGuardian.cxx
00002 // Created by:  drose (02eb99)
00003 // Updated by: fperazzi, PandaSE (05May10) (added fetch_ptr_parameter,
00004 //  _max_2d_texture_array_layers, _supports_2d_texture_array,
00005 //  get_supports_cg_profile)
00006 //
00007 ////////////////////////////////////////////////////////////////////
00008 //
00009 // PANDA 3D SOFTWARE
00010 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00011 //
00012 // All use of this software is subject to the terms of the revised BSD
00013 // license.  You should have received a copy of this license along
00014 // with this source code in a file named "LICENSE."
00015 //
00016 ////////////////////////////////////////////////////////////////////
00017 
00018 #include "graphicsStateGuardian.h"
00019 #include "graphicsEngine.h"
00020 #include "config_display.h"
00021 #include "textureContext.h"
00022 #include "vertexBufferContext.h"
00023 #include "indexBufferContext.h"
00024 #include "renderBuffer.h"
00025 #include "light.h"
00026 #include "planeNode.h"
00027 #include "ambientLight.h"
00028 #include "throw_event.h"
00029 #include "clockObject.h"
00030 #include "pStatTimer.h"
00031 #include "geomTristrips.h"
00032 #include "geomTrifans.h"
00033 #include "geomLinestrips.h"
00034 #include "colorWriteAttrib.h"
00035 #include "shader.h"
00036 #include "pnotify.h"
00037 #include "drawableRegion.h"
00038 #include "displayRegion.h"
00039 #include "graphicsOutput.h"
00040 #include "texturePool.h"
00041 #include "geomMunger.h"
00042 #include "ambientLight.h"
00043 #include "directionalLight.h"
00044 #include "pointLight.h"
00045 #include "spotlight.h"
00046 #include "textureReloadRequest.h"
00047 #include "shaderAttrib.h"
00048 #include "materialAttrib.h"
00049 #include "depthWriteAttrib.h"
00050 #include "lightAttrib.h"
00051 #include "texGenAttrib.h"
00052 #include "shaderGenerator.h"
00053 #include "lightLensNode.h"
00054 #include "colorAttrib.h"
00055 #include "colorScaleAttrib.h"
00056 #include "clipPlaneAttrib.h"
00057 #include "fogAttrib.h"
00058 
00059 #include <algorithm>
00060 #include <limits.h>
00061 
00062 PStatCollector GraphicsStateGuardian::_vertex_buffer_switch_pcollector("Vertex buffer switch:Vertex");
00063 PStatCollector GraphicsStateGuardian::_index_buffer_switch_pcollector("Vertex buffer switch:Index");
00064 PStatCollector GraphicsStateGuardian::_load_vertex_buffer_pcollector("Draw:Transfer data:Vertex buffer");
00065 PStatCollector GraphicsStateGuardian::_load_index_buffer_pcollector("Draw:Transfer data:Index buffer");
00066 PStatCollector GraphicsStateGuardian::_create_vertex_buffer_pcollector("Draw:Transfer data:Create Vertex buffer");
00067 PStatCollector GraphicsStateGuardian::_create_index_buffer_pcollector("Draw:Transfer data:Create Index buffer");
00068 PStatCollector GraphicsStateGuardian::_load_texture_pcollector("Draw:Transfer data:Texture");
00069 PStatCollector GraphicsStateGuardian::_data_transferred_pcollector("Data transferred");
00070 PStatCollector GraphicsStateGuardian::_texmgrmem_total_pcollector("Texture manager");
00071 PStatCollector GraphicsStateGuardian::_texmgrmem_resident_pcollector("Texture manager:Resident");
00072 PStatCollector GraphicsStateGuardian::_primitive_batches_pcollector("Primitive batches");
00073 PStatCollector GraphicsStateGuardian::_primitive_batches_tristrip_pcollector("Primitive batches:Triangle strips");
00074 PStatCollector GraphicsStateGuardian::_primitive_batches_trifan_pcollector("Primitive batches:Triangle fans");
00075 PStatCollector GraphicsStateGuardian::_primitive_batches_tri_pcollector("Primitive batches:Triangles");
00076 PStatCollector GraphicsStateGuardian::_primitive_batches_patch_pcollector("Primitive batches:Patches");
00077 PStatCollector GraphicsStateGuardian::_primitive_batches_other_pcollector("Primitive batches:Other");
00078 PStatCollector GraphicsStateGuardian::_vertices_tristrip_pcollector("Vertices:Triangle strips");
00079 PStatCollector GraphicsStateGuardian::_vertices_trifan_pcollector("Vertices:Triangle fans");
00080 PStatCollector GraphicsStateGuardian::_vertices_tri_pcollector("Vertices:Triangles");
00081 PStatCollector GraphicsStateGuardian::_vertices_patch_pcollector("Vertices:Patches");
00082 PStatCollector GraphicsStateGuardian::_vertices_other_pcollector("Vertices:Other");
00083 PStatCollector GraphicsStateGuardian::_state_pcollector("State changes");
00084 PStatCollector GraphicsStateGuardian::_transform_state_pcollector("State changes:Transforms");
00085 PStatCollector GraphicsStateGuardian::_texture_state_pcollector("State changes:Textures");
00086 PStatCollector GraphicsStateGuardian::_draw_primitive_pcollector("Draw:Primitive:Draw");
00087 PStatCollector GraphicsStateGuardian::_draw_set_state_pcollector("Draw:Set State");
00088 PStatCollector GraphicsStateGuardian::_clear_pcollector("Draw:Clear");
00089 PStatCollector GraphicsStateGuardian::_flush_pcollector("Draw:Flush");
00090 
00091 PStatCollector GraphicsStateGuardian::_wait_occlusion_pcollector("Wait:Occlusion");
00092 
00093 
00094 PStatCollector GraphicsStateGuardian::_draw_set_state_transform_pcollector("Draw:Set State:Transform");
00095 PStatCollector GraphicsStateGuardian::_draw_set_state_alpha_test_pcollector("Draw:Set State:Alpha test");
00096 PStatCollector GraphicsStateGuardian::_draw_set_state_antialias_pcollector("Draw:Set State:Antialias");
00097 PStatCollector GraphicsStateGuardian::_draw_set_state_clip_plane_pcollector("Draw:Set State:Clip plane");
00098 PStatCollector GraphicsStateGuardian::_draw_set_state_color_pcollector("Draw:Set State:Color");
00099 PStatCollector GraphicsStateGuardian::_draw_set_state_cull_face_pcollector("Draw:Set State:Cull face");
00100 PStatCollector GraphicsStateGuardian::_draw_set_state_depth_offset_pcollector("Draw:Set State:Depth offset");
00101 PStatCollector GraphicsStateGuardian::_draw_set_state_depth_test_pcollector("Draw:Set State:Depth test");
00102 PStatCollector GraphicsStateGuardian::_draw_set_state_depth_write_pcollector("Draw:Set State:Depth write");
00103 PStatCollector GraphicsStateGuardian::_draw_set_state_render_mode_pcollector("Draw:Set State:Render mode");
00104 PStatCollector GraphicsStateGuardian::_draw_set_state_rescale_normal_pcollector("Draw:Set State:Rescale normal");
00105 PStatCollector GraphicsStateGuardian::_draw_set_state_shade_model_pcollector("Draw:Set State:Shade model");
00106 PStatCollector GraphicsStateGuardian::_draw_set_state_blending_pcollector("Draw:Set State:Blending");
00107 PStatCollector GraphicsStateGuardian::_draw_set_state_shader_pcollector("Draw:Set State:Shader");
00108 PStatCollector GraphicsStateGuardian::_draw_set_state_shader_parameters_pcollector("Draw:Set State:Shader Parameters");
00109 PStatCollector GraphicsStateGuardian::_draw_set_state_texture_pcollector("Draw:Set State:Texture");
00110 PStatCollector GraphicsStateGuardian::_draw_set_state_tex_matrix_pcollector("Draw:Set State:Tex matrix");
00111 PStatCollector GraphicsStateGuardian::_draw_set_state_tex_gen_pcollector("Draw:Set State:Tex gen");
00112 PStatCollector GraphicsStateGuardian::_draw_set_state_material_pcollector("Draw:Set State:Material");
00113 PStatCollector GraphicsStateGuardian::_draw_set_state_light_pcollector("Draw:Set State:Light");
00114 PStatCollector GraphicsStateGuardian::_draw_set_state_stencil_pcollector("Draw:Set State:Stencil");
00115 PStatCollector GraphicsStateGuardian::_draw_set_state_fog_pcollector("Draw:Set State:Fog");
00116 PStatCollector GraphicsStateGuardian::_draw_set_state_scissor_pcollector("Draw:Set State:Scissor");
00117 
00118 
00119 PT(TextureStage) GraphicsStateGuardian::_alpha_scale_texture_stage = NULL;
00120 
00121 TypeHandle GraphicsStateGuardian::_type_handle;
00122 
00123 ////////////////////////////////////////////////////////////////////
00124 //     Function: GraphicsStateGuardian::Constructor
00125 //       Access: Public
00126 //  Description:
00127 ////////////////////////////////////////////////////////////////////
00128 
00129 GraphicsStateGuardian::
00130 GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
00131                       GraphicsEngine *engine, GraphicsPipe *pipe) :
00132   _internal_coordinate_system(internal_coordinate_system),
00133   _pipe(pipe),
00134   _engine(engine)
00135 {
00136   _coordinate_system = CS_invalid;
00137   _internal_transform = TransformState::make_identity();
00138 
00139   set_coordinate_system(get_default_coordinate_system());
00140 
00141   _data_reader = (GeomVertexDataPipelineReader *)NULL;
00142   _current_display_region = (DisplayRegion*)NULL;
00143   _current_stereo_channel = Lens::SC_mono;
00144   _current_tex_view_offset = 0;
00145   _current_lens = (Lens *)NULL;
00146   _projection_mat = TransformState::make_identity();
00147   _projection_mat_inv = TransformState::make_identity();
00148 
00149   _needs_reset = true;
00150   _is_valid = false;
00151   _current_properties = NULL;
00152   _closing_gsg = false;
00153   _active = true;
00154   _prepared_objects = new PreparedGraphicsObjects;
00155   _stereo_buffer_mask = ~0;
00156   _incomplete_render = allow_incomplete_render;
00157   _effective_incomplete_render = false;
00158   _loader = Loader::get_global_ptr();
00159 
00160   _is_hardware = false;
00161   _prefers_triangle_strips = false;
00162   _max_vertices_per_array = INT_MAX;
00163   _max_vertices_per_primitive = INT_MAX;
00164 
00165   // Initially, we set this to 1 (the default--no multitexturing
00166   // supported).  A derived GSG may set this differently if it
00167   // supports multitexturing.
00168   _max_texture_stages = 1;
00169 
00170   // Also initially, we assume there are no limits on texture sizes,
00171   // and that 3-d and cube-map textures are not supported.
00172   _max_texture_dimension = -1;
00173   _max_3d_texture_dimension = 0;
00174   _max_2d_texture_array_layers = 0;
00175   _max_cube_map_dimension = 0;
00176 
00177   // Assume we don't support these fairly advanced texture combiner
00178   // modes.
00179   _supports_texture_combine = false;
00180   _supports_texture_saved_result = false;
00181   _supports_texture_dot3 = false;
00182 
00183   _supports_3d_texture = false;
00184   _supports_2d_texture_array = false;
00185   _supports_cube_map = false;
00186   _supports_tex_non_pow2 = false;
00187   _supports_compressed_texture = false;
00188   _compressed_texture_formats.clear();
00189   _compressed_texture_formats.set_bit(Texture::CM_off);
00190 
00191   // Assume no limits on number of lights or clip planes.
00192   _max_lights = -1;
00193   _max_clip_planes = -1;
00194 
00195   // Assume no vertex blending capability.
00196   _max_vertex_transforms = 0;
00197   _max_vertex_transform_indices = 0;
00198 
00199   _supports_occlusion_query = false;
00200 
00201   // Initially, we set this to false; a GSG that knows it has this
00202   // property should set it to true.
00203   _copy_texture_inverted = false;
00204 
00205   // Similarly with these capabilities flags.
00206   _supports_multisample = false;
00207   _supports_generate_mipmap = false;
00208   _supports_depth_texture = false;
00209   _supports_depth_stencil = false;
00210   _supports_shadow_filter = false;
00211   _supports_basic_shaders = false;
00212   _supports_geometry_shaders = false;
00213   _supports_tessellation_shaders = false;
00214   _supports_glsl = false;
00215 
00216   _supports_stencil = false;
00217   _supports_stencil_wrap = false;
00218   _supports_two_sided_stencil = false;
00219   _supports_geometry_instancing = false;
00220 
00221   // Assume a maximum of 1 render target in absence of MRT.
00222   _max_color_targets = 1;
00223 
00224   _supported_geom_rendering = 0;
00225 
00226   // If this is true, then we can apply a color and/or color scale by
00227   // twiddling the material and/or ambient light (which could mean
00228   // enabling lighting even without a LightAttrib).
00229   _color_scale_via_lighting = color_scale_via_lighting;
00230 
00231   // Similarly for applying a texture to achieve uniform alpha
00232   // scaling.
00233   _alpha_scale_via_texture = alpha_scale_via_texture;
00234 
00235   // Few GSG's can do this, since it requires touching each vertex as
00236   // it is rendered.
00237   _runtime_color_scale = false;
00238 
00239   _stencil_render_states = 0;
00240 
00241   // The default is no shader support.
00242   _auto_detect_shader_model = SM_00;
00243   _shader_model = SM_00;
00244 
00245   _gamma = 1.0f;
00246   _texture_quality_override = Texture::QL_default;
00247 
00248   _shader_generator = NULL;
00249 }
00250 
00251 ////////////////////////////////////////////////////////////////////
00252 //     Function: GraphicsStateGuardian::Destructor
00253 //       Access: Public, Virtual
00254 //  Description:
00255 ////////////////////////////////////////////////////////////////////
00256 GraphicsStateGuardian::
00257 ~GraphicsStateGuardian() {
00258   remove_gsg(this);
00259 
00260   if (_stencil_render_states) {
00261     delete _stencil_render_states;
00262     _stencil_render_states = 0;
00263   }
00264   
00265   if (_shader_generator) {
00266     delete _shader_generator;
00267     _shader_generator = 0;
00268   }
00269 
00270   GeomMunger::unregister_mungers_for_gsg(this);
00271 }
00272 
00273 ////////////////////////////////////////////////////////////////////
00274 //     Function: GraphicsStateGuardian::get_engine
00275 //       Access: Published
00276 //  Description: Returns the graphics engine that created this GSG.
00277 //               Since there is normally only one GraphicsEngine
00278 //               object in an application, this is usually the same as
00279 //               the global GraphicsEngine.
00280 ////////////////////////////////////////////////////////////////////
00281 GraphicsEngine *GraphicsStateGuardian::
00282 get_engine() const {
00283   nassertr(_engine != (GraphicsEngine *)NULL, GraphicsEngine::get_global_ptr());
00284   return _engine;
00285 }
00286 
00287 ////////////////////////////////////////////////////////////////////
00288 //     Function: GraphicsStateGuardian::get_supports_multisample
00289 //       Access: Published, Virtual
00290 //  Description: Returns true if this particular GSG supports using
00291 //               the multisample bits to provide antialiasing, and
00292 //               also supports M_multisample and M_multisample_mask
00293 //               transparency modes.  If this is not true for a
00294 //               particular GSG, Panda will map the M_multisample
00295 //               modes to M_binary.
00296 //
00297 //               This method is declared virtual solely so that it can
00298 //               be queried from cullResult.cxx.
00299 ////////////////////////////////////////////////////////////////////
00300 bool GraphicsStateGuardian::
00301 get_supports_multisample() const {
00302   return _supports_multisample;
00303 }
00304 
00305 ////////////////////////////////////////////////////////////////////
00306 //     Function: GraphicsStateGuardian::get_supported_geom_rendering
00307 //       Access: Published, Virtual
00308 //  Description: Returns the union of Geom::GeomRendering values that
00309 //               this particular GSG can support directly.  If a Geom
00310 //               needs to be rendered that requires some additional
00311 //               properties, the StandardMunger and/or the
00312 //               CullableObject will convert it as needed.
00313 //
00314 //               This method is declared virtual solely so that it can
00315 //               be queried from cullableObject.cxx.
00316 ////////////////////////////////////////////////////////////////////
00317 int GraphicsStateGuardian::
00318 get_supported_geom_rendering() const {
00319   return _supported_geom_rendering;
00320 }
00321 
00322 ////////////////////////////////////////////////////////////////////
00323 //     Function: GraphicsStateGuardian::get_supports_cg_profile
00324 //       Access: Published, Virtual
00325 //  Description: Returns true if this particular GSG supports the 
00326 //               specified Cg Shader Profile.
00327 ////////////////////////////////////////////////////////////////////
00328 bool GraphicsStateGuardian::
00329 get_supports_cg_profile(const string &name) const {
00330   return false;
00331 }
00332 
00333 ////////////////////////////////////////////////////////////////////
00334 //     Function: GraphicsStateGuardian::set_coordinate_system
00335 //       Access: Published
00336 //  Description: Changes the coordinate system in effect on this
00337 //               particular gsg.  This is also called the "external"
00338 //               coordinate system, since it is the coordinate system
00339 //               used by the scene graph, external to to GSG.
00340 //
00341 //               Normally, this will be the default coordinate system,
00342 //               but it might be set differently at runtime.  It will
00343 //               automatically be copied from the current lens's
00344 //               coordinate system as each DisplayRegion is rendered.
00345 ////////////////////////////////////////////////////////////////////
00346 void GraphicsStateGuardian::
00347 set_coordinate_system(CoordinateSystem cs) {
00348   if (cs == CS_default) {
00349     cs = get_default_coordinate_system();
00350   }
00351   _coordinate_system = cs;
00352 
00353   // Changing the external coordinate system changes the cs_transform.
00354   if (_internal_coordinate_system == CS_default ||
00355       _internal_coordinate_system == _coordinate_system) {
00356     _cs_transform = TransformState::make_identity();
00357     _inv_cs_transform = TransformState::make_identity();
00358 
00359   } else {
00360     _cs_transform =
00361       TransformState::make_mat
00362       (LMatrix4::convert_mat(_coordinate_system,
00363                               _internal_coordinate_system));
00364     _inv_cs_transform =
00365       TransformState::make_mat
00366       (LMatrix4::convert_mat(_internal_coordinate_system,
00367                               _coordinate_system));
00368   }
00369 }
00370 
00371 ////////////////////////////////////////////////////////////////////
00372 //     Function: GraphicsStateGuardian::get_internal_coordinate_system
00373 //       Access: Published, Virtual
00374 //  Description: Returns the coordinate system used internally by the
00375 //               GSG.  This may be the same as the external coordinate
00376 //               system reported by get_coordinate_system(), or it may
00377 //               be something different.
00378 //
00379 //               In any case, vertices that have been transformed
00380 //               before being handed to the GSG (that is, vertices
00381 //               with a contents value of C_clip_point) will be
00382 //               expected to be in this coordinate system.
00383 ////////////////////////////////////////////////////////////////////
00384 CoordinateSystem GraphicsStateGuardian::
00385 get_internal_coordinate_system() const {
00386   return _internal_coordinate_system;
00387 }
00388 
00389 ////////////////////////////////////////////////////////////////////
00390 //     Function: GraphicsStateGuardian::get_prepared_objects
00391 //       Access: Public, Virtual
00392 //  Description: Returns the set of texture and geom objects that have
00393 //               been prepared with this GSG (and possibly other GSG's
00394 //               that share objects).
00395 ////////////////////////////////////////////////////////////////////
00396 PreparedGraphicsObjects *GraphicsStateGuardian::
00397 get_prepared_objects() {
00398   return _prepared_objects;
00399 }
00400 
00401 ////////////////////////////////////////////////////////////////////
00402 //     Function: GraphicsStateGuardian::set_gamma
00403 //       Access: Published, Virtual
00404 //  Description: Set gamma.  Returns true on success.
00405 ////////////////////////////////////////////////////////////////////
00406 bool GraphicsStateGuardian::
00407 set_gamma(PN_stdfloat gamma) {
00408   _gamma = gamma;  
00409 
00410   return false;
00411 }
00412 
00413 ////////////////////////////////////////////////////////////////////
00414 //     Function: GraphicsStateGuardian::get_gamma
00415 //       Access: Published
00416 //  Description: Get the current gamma setting.
00417 ////////////////////////////////////////////////////////////////////
00418 PN_stdfloat GraphicsStateGuardian::
00419 get_gamma(PN_stdfloat gamma) {
00420   return _gamma;
00421 }
00422 
00423 ////////////////////////////////////////////////////////////////////
00424 //     Function: GraphicsStateGuardian::restore_gamma
00425 //       Access: Published, Virtual
00426 //  Description: Restore original gamma setting.
00427 ////////////////////////////////////////////////////////////////////
00428 void GraphicsStateGuardian::
00429 restore_gamma() {
00430 }
00431 
00432 ////////////////////////////////////////////////////////////////////
00433 //     Function: GraphicsStateGuardian::traverse_prepared_textures
00434 //       Access: Public
00435 //  Description: Calls the indicated function on all
00436 //               currently-prepared textures, or until the callback
00437 //               function returns false.
00438 ////////////////////////////////////////////////////////////////////
00439 void GraphicsStateGuardian::
00440 traverse_prepared_textures(GraphicsStateGuardian::TextureCallback *func, 
00441                            void *callback_arg) {
00442   ReMutexHolder holder(_prepared_objects->_lock);
00443   PreparedGraphicsObjects::Textures::const_iterator ti;
00444   for (ti = _prepared_objects->_prepared_textures.begin();
00445        ti != _prepared_objects->_prepared_textures.end();
00446        ++ti) {
00447     bool result = (*func)(*ti, callback_arg);
00448     if (!result) {
00449       return;
00450     }
00451   }
00452 }
00453 
00454 #ifndef NDEBUG
00455 ////////////////////////////////////////////////////////////////////
00456 //     Function: GraphicsStateGuardian::set_flash_texture
00457 //       Access: Published
00458 //  Description: Sets the "flash texture".  This is a debug feature;
00459 //               when enabled, the specified texture will begin
00460 //               flashing in the scene, helping you to find it
00461 //               visually.
00462 //
00463 //               The texture also flashes with a color code: blue for
00464 //               mipmap level 0, yellow for mipmap level 1, and red
00465 //               for mipmap level 2 or higher (even for textures that
00466 //               don't have mipmaps).  This gives you an idea of the
00467 //               choice of the texture size.  If it is blue, the
00468 //               texture is being drawn the proper size or magnified;
00469 //               if it is yellow, it is being minified a little bit;
00470 //               and if it red, it is being minified considerably.  If
00471 //               you see a red texture when you are right in front of
00472 //               it, you should consider reducing the size of the
00473 //               texture to avoid wasting texture memory.
00474 //
00475 //               Not all rendering backends support the flash_texture
00476 //               feature.  Presently, it is only supported by OpenGL.
00477 ////////////////////////////////////////////////////////////////////
00478 void GraphicsStateGuardian::
00479 set_flash_texture(Texture *tex) {
00480   _flash_texture = tex;
00481 }
00482 #endif  // NDEBUG
00483 
00484 #ifndef NDEBUG
00485 ////////////////////////////////////////////////////////////////////
00486 //     Function: GraphicsStateGuardian::clear_flash_texture
00487 //       Access: Published
00488 //  Description: Resets the "flash texture", so that no textures will
00489 //               flash.  See set_flash_texture().
00490 ////////////////////////////////////////////////////////////////////
00491 void GraphicsStateGuardian::
00492 clear_flash_texture() {
00493   _flash_texture = NULL;
00494 }
00495 #endif  // NDEBUG
00496 
00497 #ifndef NDEBUG
00498 ////////////////////////////////////////////////////////////////////
00499 //     Function: GraphicsStateGuardian::get_flash_texture
00500 //       Access: Published
00501 //  Description: Returns the current "flash texture", if any, or NULL
00502 //               if none.  See set_flash_texture().
00503 ////////////////////////////////////////////////////////////////////
00504 Texture *GraphicsStateGuardian::
00505 get_flash_texture() const {
00506   return _flash_texture;
00507 }
00508 #endif  // NDEBUG
00509 
00510 ////////////////////////////////////////////////////////////////////
00511 //     Function: GraphicsStateGuardian::set_scene
00512 //       Access: Published
00513 //  Description: Sets the SceneSetup object that indicates the initial
00514 //               camera position, etc.  This must be called before
00515 //               traversal begins.  Returns true if the scene is
00516 //               acceptable, false if something's wrong.  This should
00517 //               be called in the draw thread only.
00518 ////////////////////////////////////////////////////////////////////
00519 bool GraphicsStateGuardian::
00520 set_scene(SceneSetup *scene_setup) {
00521   _scene_setup = scene_setup;
00522   _current_lens = scene_setup->get_lens();
00523   if (_current_lens == (Lens *)NULL) {
00524     return false;
00525   }
00526 
00527   set_coordinate_system(_current_lens->get_coordinate_system());
00528 
00529   _projection_mat = calc_projection_mat(_current_lens);
00530   if (_projection_mat == 0) {
00531     return false;
00532   }
00533   _projection_mat_inv = _projection_mat->get_inverse();
00534   return prepare_lens();
00535 }
00536 
00537 ////////////////////////////////////////////////////////////////////
00538 //     Function: GraphicsStateGuardian::get_scene
00539 //       Access: Published, Virtual
00540 //  Description: Returns the current SceneSetup object.
00541 ////////////////////////////////////////////////////////////////////
00542 SceneSetup *GraphicsStateGuardian::
00543 get_scene() const {
00544   return _scene_setup;
00545 }
00546 
00547 ////////////////////////////////////////////////////////////////////
00548 //     Function: GraphicsStateGuardian::prepare_texture
00549 //       Access: Public, Virtual
00550 //  Description: Creates whatever structures the GSG requires to
00551 //               represent the texture internally, and returns a
00552 //               newly-allocated TextureContext object with this data.
00553 //               It is the responsibility of the calling function to
00554 //               later call release_texture() with this same pointer
00555 //               (which will also delete the pointer).
00556 //
00557 //               This function should not be called directly to
00558 //               prepare a texture.  Instead, call Texture::prepare().
00559 ////////////////////////////////////////////////////////////////////
00560 TextureContext *GraphicsStateGuardian::
00561 prepare_texture(Texture *) {
00562   return (TextureContext *)NULL;
00563 }
00564 
00565 ////////////////////////////////////////////////////////////////////
00566 //     Function: GraphicsStateGuardian::update_texture
00567 //       Access: Public, Virtual
00568 //  Description: Ensures that the current Texture data is refreshed
00569 //               onto the GSG.  This means updating the texture
00570 //               properties and/or re-uploading the texture image, if
00571 //               necessary.  This should only be called within the
00572 //               draw thread.
00573 //
00574 //               If force is true, this function will not return until
00575 //               the texture has been fully uploaded.  If force is
00576 //               false, the function may choose to upload a simple
00577 //               version of the texture instead, if the texture is not
00578 //               fully resident (and if get_incomplete_render() is
00579 //               true).
00580 ////////////////////////////////////////////////////////////////////
00581 bool GraphicsStateGuardian::
00582 update_texture(TextureContext *, bool) {
00583   return true;
00584 }
00585 
00586 ////////////////////////////////////////////////////////////////////
00587 //     Function: GraphicsStateGuardian::release_texture
00588 //       Access: Public, Virtual
00589 //  Description: Frees the resources previously allocated via a call
00590 //               to prepare_texture(), including deleting the
00591 //               TextureContext itself, if it is non-NULL.
00592 ////////////////////////////////////////////////////////////////////
00593 void GraphicsStateGuardian::
00594 release_texture(TextureContext *) {
00595 }
00596 
00597 ////////////////////////////////////////////////////////////////////
00598 //     Function: GraphicsStateGuardian::extract_texture_data
00599 //       Access: Public, Virtual
00600 //  Description: This method should only be called by the
00601 //               GraphicsEngine.  Do not call it directly; call
00602 //               GraphicsEngine::extract_texture_data() instead.
00603 //
00604 //               This method will be called in the draw thread to
00605 //               download the texture memory's image into its
00606 //               ram_image value.  It returns true on success, false
00607 //               otherwise.
00608 ////////////////////////////////////////////////////////////////////
00609 bool GraphicsStateGuardian::
00610 extract_texture_data(Texture *) {
00611   return false;
00612 }
00613 
00614 ////////////////////////////////////////////////////////////////////
00615 //     Function: GraphicsStateGuardian::prepare_geom
00616 //       Access: Public, Virtual
00617 //  Description: Prepares the indicated Geom for retained-mode
00618 //               rendering, by creating whatever structures are
00619 //               necessary in the GSG (for instance, vertex buffers).
00620 //               Returns the newly-allocated GeomContext that can be
00621 //               used to render the geom.
00622 ////////////////////////////////////////////////////////////////////
00623 GeomContext *GraphicsStateGuardian::
00624 prepare_geom(Geom *) {
00625   return (GeomContext *)NULL;
00626 }
00627 
00628 ////////////////////////////////////////////////////////////////////
00629 //     Function: GraphicsStateGuardian::release_geom
00630 //       Access: Public, Virtual
00631 //  Description: Frees the resources previously allocated via a call
00632 //               to prepare_geom(), including deleting the GeomContext
00633 //               itself, if it is non-NULL.
00634 //
00635 //               This function should not be called directly to
00636 //               prepare a Geom.  Instead, call Geom::prepare().
00637 ////////////////////////////////////////////////////////////////////
00638 void GraphicsStateGuardian::
00639 release_geom(GeomContext *) {
00640 }
00641 
00642 ////////////////////////////////////////////////////////////////////
00643 //     Function: GraphicsStateGuardian::prepare_shader
00644 //       Access: Public, Virtual
00645 //  Description: Compile a vertex/fragment shader body.
00646 ////////////////////////////////////////////////////////////////////
00647 ShaderContext *GraphicsStateGuardian::
00648 prepare_shader(Shader *shader) {
00649   return (ShaderContext *)NULL;
00650 }
00651 
00652 ////////////////////////////////////////////////////////////////////
00653 //     Function: GraphicsStateGuardian::release_shader
00654 //       Access: Public, Virtual
00655 //  Description: Releases the resources allocated by prepare_shader
00656 ////////////////////////////////////////////////////////////////////
00657 void GraphicsStateGuardian::
00658 release_shader(ShaderContext *sc) {
00659 }
00660 
00661 ////////////////////////////////////////////////////////////////////
00662 //     Function: GraphicsStateGuardian::prepare_vertex_buffer
00663 //       Access: Public, Virtual
00664 //  Description: Prepares the indicated buffer for retained-mode
00665 //               rendering.
00666 ////////////////////////////////////////////////////////////////////
00667 VertexBufferContext *GraphicsStateGuardian::
00668 prepare_vertex_buffer(GeomVertexArrayData *) {
00669   return (VertexBufferContext *)NULL;
00670 }
00671 
00672 ////////////////////////////////////////////////////////////////////
00673 //     Function: GraphicsStateGuardian::release_vertex_buffer
00674 //       Access: Public, Virtual
00675 //  Description: Frees the resources previously allocated via a call
00676 //               to prepare_data(), including deleting the
00677 //               VertexBufferContext itself, if necessary.
00678 ////////////////////////////////////////////////////////////////////
00679 void GraphicsStateGuardian::
00680 release_vertex_buffer(VertexBufferContext *) {
00681 }
00682 
00683 ////////////////////////////////////////////////////////////////////
00684 //     Function: GraphicsStateGuardian::prepare_index_buffer
00685 //       Access: Public, Virtual
00686 //  Description: Prepares the indicated buffer for retained-mode
00687 //               rendering.
00688 ////////////////////////////////////////////////////////////////////
00689 IndexBufferContext *GraphicsStateGuardian::
00690 prepare_index_buffer(GeomPrimitive *) {
00691   return (IndexBufferContext *)NULL;
00692 }
00693 
00694 ////////////////////////////////////////////////////////////////////
00695 //     Function: GraphicsStateGuardian::release_index_buffer
00696 //       Access: Public, Virtual
00697 //  Description: Frees the resources previously allocated via a call
00698 //               to prepare_data(), including deleting the
00699 //               IndexBufferContext itself, if necessary.
00700 ////////////////////////////////////////////////////////////////////
00701 void GraphicsStateGuardian::
00702 release_index_buffer(IndexBufferContext *) {
00703 }
00704 
00705 ////////////////////////////////////////////////////////////////////
00706 //     Function: GraphicsStateGuardian::get_supports_occlusion_query
00707 //       Access: Public, Virtual
00708 //  Description: Returns true if this GSG supports an occlusion query.
00709 //               If this is true, then begin_occlusion_query() and
00710 //               end_occlusion_query() may be called to bracket a
00711 //               sequence of draw_triangles() (or whatever) calls to
00712 //               measure pixels that pass the depth test.
00713 ////////////////////////////////////////////////////////////////////
00714 bool GraphicsStateGuardian::
00715 get_supports_occlusion_query() const {
00716   return _supports_occlusion_query;
00717 }
00718 
00719 ////////////////////////////////////////////////////////////////////
00720 //     Function: GraphicsStateGuardian::begin_occlusion_query
00721 //       Access: Public, Virtual
00722 //  Description: Begins a new occlusion query.  After this call, you
00723 //               may call begin_draw_primitives() and
00724 //               draw_triangles()/draw_whatever() repeatedly.
00725 //               Eventually, you should call end_occlusion_query()
00726 //               before the end of the frame; that will return a new
00727 //               OcclusionQueryContext object that will tell you how
00728 //               many pixels represented by the bracketed geometry
00729 //               passed the depth test.
00730 //
00731 //               It is not valid to call begin_occlusion_query()
00732 //               between another begin_occlusion_query()
00733 //               .. end_occlusion_query() sequence.
00734 ////////////////////////////////////////////////////////////////////
00735 void GraphicsStateGuardian::
00736 begin_occlusion_query() {
00737   nassertv(_current_occlusion_query == (OcclusionQueryContext *)NULL);
00738 }
00739 
00740 ////////////////////////////////////////////////////////////////////
00741 //     Function: GraphicsStateGuardian::end_occlusion_query
00742 //       Access: Public, Virtual
00743 //  Description: Ends a previous call to begin_occlusion_query().
00744 //               This call returns the OcclusionQueryContext object
00745 //               that will (eventually) report the number of pixels
00746 //               that passed the depth test between the call to
00747 //               begin_occlusion_query() and end_occlusion_query().
00748 ////////////////////////////////////////////////////////////////////
00749 PT(OcclusionQueryContext) GraphicsStateGuardian::
00750 end_occlusion_query() {
00751   nassertr(_current_occlusion_query != (OcclusionQueryContext *)NULL, NULL);
00752   PT(OcclusionQueryContext) result = _current_occlusion_query;
00753   _current_occlusion_query = NULL;
00754   return result;
00755 }
00756 
00757 ////////////////////////////////////////////////////////////////////
00758 //     Function: GraphicsStateGuardian::dispatch_compute
00759 //       Access: Public, Virtual
00760 //  Description: Dispatches a currently bound compute shader using
00761 //               the given work group counts.
00762 ////////////////////////////////////////////////////////////////////
00763 void GraphicsStateGuardian::
00764 dispatch_compute(int num_groups_x, int num_groups_y, int num_groups_z) {
00765   nassertv(false /* Compute shaders not supported by GSG */);
00766 }
00767 
00768 ////////////////////////////////////////////////////////////////////
00769 //     Function: GraphicsStateGuardian::get_geom_munger
00770 //       Access: Public, Virtual
00771 //  Description: Looks up or creates a GeomMunger object to munge
00772 //               vertices appropriate to this GSG for the indicated
00773 //               state.
00774 ////////////////////////////////////////////////////////////////////
00775 PT(GeomMunger) GraphicsStateGuardian::
00776 get_geom_munger(const RenderState *state, Thread *current_thread) {
00777   // We can cast the RenderState to a non-const object because we are
00778   // only updating a cache within the RenderState, not really changing
00779   // any of its properties.
00780   RenderState *nc_state = ((RenderState *)state);
00781 
00782   // Before we even look up the map, see if the _last_mi value points
00783   // to this GSG.  This is likely because we tend to visit the same
00784   // state multiple times during a frame.  Also, this might well be
00785   // the only GSG in the world anyway.
00786   if (!nc_state->_mungers.empty()) {
00787     RenderState::Mungers::const_iterator mi = nc_state->_last_mi;
00788     if (!(*mi).first.was_deleted() && (*mi).first == this) {
00789       if ((*mi).second->is_registered()) {
00790         return (*mi).second;
00791       }
00792     }
00793   }
00794 
00795   // Nope, we have to look it up in the map.
00796   RenderState::Mungers::iterator mi = nc_state->_mungers.find(this);
00797   if (mi != nc_state->_mungers.end() && !(*mi).first.was_deleted()) {
00798     if ((*mi).second->is_registered()) {
00799       nc_state->_last_mi = mi;
00800       return (*mi).second;
00801     }
00802     // This GeomMunger is no longer registered.  Remove it from the
00803     // map.
00804     nc_state->_mungers.erase(mi);
00805   }
00806 
00807   // Nothing in the map; create a new entry.
00808   PT(GeomMunger) munger = make_geom_munger(nc_state, current_thread);
00809   nassertr(munger != (GeomMunger *)NULL && munger->is_registered(), munger);
00810 
00811   mi = nc_state->_mungers.insert(RenderState::Mungers::value_type(this, munger)).first;
00812   nc_state->_last_mi = mi;
00813 
00814   return munger;
00815 }
00816 
00817 ////////////////////////////////////////////////////////////////////
00818 //     Function: GraphicsStateGuardian::make_geom_munger
00819 //       Access: Public, Virtual
00820 //  Description: Creates a new GeomMunger object to munge vertices
00821 //               appropriate to this GSG for the indicated state.
00822 ////////////////////////////////////////////////////////////////////
00823 PT(GeomMunger) GraphicsStateGuardian::
00824 make_geom_munger(const RenderState *state, Thread *current_thread) {
00825   // The default implementation returns no munger at all, but
00826   // presumably, every kind of GSG needs some special munging action,
00827   // so real GSG's will override this to return something more
00828   // useful.
00829   return NULL;
00830 }
00831 
00832 ////////////////////////////////////////////////////////////////////
00833 //     Function: GraphicsStateGuardian::compute_distance_to
00834 //       Access: Public, Virtual
00835 //  Description: This function may only be called during a render
00836 //               traversal; it will compute the distance to the
00837 //               indicated point, assumed to be in eye coordinates,
00838 //               from the camera plane.
00839 ////////////////////////////////////////////////////////////////////
00840 PN_stdfloat GraphicsStateGuardian::
00841 compute_distance_to(const LPoint3 &point) const {
00842   switch (_coordinate_system) {
00843   case CS_zup_right:
00844     return point[1];
00845 
00846   case CS_yup_right:
00847     return -point[2];
00848 
00849   case CS_zup_left:
00850     return -point[1];
00851 
00852   case CS_yup_left:
00853     return point[2];
00854 
00855   default:
00856     gsg_cat.error()
00857       << "Invalid coordinate system in compute_distance_to: "
00858       << (int)_coordinate_system << "\n";
00859     return 0.0f;
00860   }
00861 }
00862 
00863 ////////////////////////////////////////////////////////////////////
00864 //     Function: GraphicsStateGuardian::fetch_specified_value
00865 //       Access: Public
00866 //  Description: The gsg contains a large number of useful matrices:
00867 //
00868 //                  * the world transform,
00869 //                  * the modelview matrix,
00870 //                  * the cs_transform,
00871 //                  * etc, etc.
00872 //
00873 //               A shader can request any of these values, and
00874 //               furthermore, it can request that various compositions,
00875 //               inverses, and transposes be performed.  The
00876 //               ShaderMatSpec is a data structure indicating what
00877 //               datum is desired and what conversions to perform.
00878 //               This routine, fetch_specified_value, is responsible for
00879 //               doing the actual retrieval and conversions.
00880 //
00881 //               Some values, like the following, aren't matrices:
00882 //
00883 //                  * window size
00884 //                  * texture coordinates of card center
00885 //
00886 //               This routine can fetch these values as well, by
00887 //               shoehorning them into a matrix.  In this way, we avoid
00888 //               the need for a separate routine to fetch these values.
00889 //
00890 //               The "altered" bits indicate what parts of the
00891 //               state_and_transform have changed since the last 
00892 //               time this particular ShaderMatSpec was evaluated.
00893 //               This may allow data to be cached and not reevaluated.
00894 //
00895 ////////////////////////////////////////////////////////////////////
00896 const LMatrix4 *GraphicsStateGuardian::
00897 fetch_specified_value(Shader::ShaderMatSpec &spec, int altered) {
00898   LVecBase3 v;
00899   
00900   if (altered & spec._dep[0]) {
00901     const LMatrix4 *t = fetch_specified_part(spec._part[0], spec._arg[0], spec._cache[0]);
00902     if (t != &spec._cache[0]) {
00903       spec._cache[0] = *t;
00904     }
00905   }
00906   if (altered & spec._dep[1]) {
00907     const LMatrix4 *t = fetch_specified_part(spec._part[1], spec._arg[1], spec._cache[1]);
00908     if (t != &spec._cache[1]) {
00909       spec._cache[1] = *t;
00910     }
00911   }
00912   
00913   switch(spec._func) {
00914   case Shader::SMF_compose:
00915     spec._value.multiply(spec._cache[0], spec._cache[1]);
00916     return &spec._value;
00917   case Shader::SMF_transform_dlight:
00918     spec._value = spec._cache[0];
00919     v = spec._cache[1].xform_vec(spec._cache[0].get_row3(2));
00920     v.normalize();
00921     spec._value.set_row(2, v);
00922     v = spec._cache[1].xform_vec(spec._cache[0].get_row3(3));
00923     v.normalize();
00924     spec._value.set_row(3, v);
00925     return &spec._value;
00926   case Shader::SMF_transform_plight:
00927     spec._value = spec._cache[0];
00928     spec._value.set_row(2, spec._cache[1].xform_point(spec._cache[0].get_row3(2)));
00929     return &spec._value;
00930   case Shader::SMF_transform_slight:
00931     spec._value = spec._cache[0];
00932     spec._value.set_row(2, spec._cache[1].xform_point(spec._cache[0].get_row3(2)));
00933     v = spec._cache[1].xform_vec(spec._cache[0].get_row3(3));
00934     v.normalize();
00935     spec._value.set_row(3, v);
00936     return &spec._value;
00937   case Shader::SMF_first:
00938     return &spec._cache[0];
00939   default:
00940     // should never get here
00941     spec._value = LMatrix4::ident_mat();
00942     return &spec._value;
00943   }
00944 }
00945 
00946 ////////////////////////////////////////////////////////////////////
00947 //     Function: GraphicsStateGuardian::fetch_specified_part
00948 //       Access: Public
00949 //  Description: See fetch_specified_value
00950 ////////////////////////////////////////////////////////////////////
00951 const LMatrix4 *GraphicsStateGuardian::
00952 fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &t) {
00953   switch(part) {
00954   case Shader::SMO_identity: {
00955     return &LMatrix4::ident_mat();
00956   }
00957   case Shader::SMO_window_size: {
00958     t = LMatrix4::translate_mat(_current_display_region->get_pixel_width(),
00959                                  _current_display_region->get_pixel_height(),
00960                                  0.0);
00961     return &t;
00962   }
00963   case Shader::SMO_pixel_size: {
00964     t = LMatrix4::translate_mat(_current_display_region->get_pixel_width(),
00965                                  _current_display_region->get_pixel_height(),
00966                                  0.0);
00967     return &t;
00968   }
00969   case Shader::SMO_frame_time: {
00970     PN_stdfloat time = ClockObject::get_global_clock()->get_frame_time();
00971     t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time);
00972     return &t;
00973   }
00974   case Shader::SMO_frame_delta: {
00975     PN_stdfloat dt = ClockObject::get_global_clock()->get_dt();
00976     t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt);
00977     return &t;
00978   }
00979   case Shader::SMO_texpad_x: {
00980     Texture *tex = _target_shader->get_shader_input_texture(name);
00981     nassertr(tex != 0, &LMatrix4::zeros_mat());
00982     int sx = tex->get_x_size() - tex->get_pad_x_size();
00983     int sy = tex->get_y_size() - tex->get_pad_y_size();
00984     int sz = tex->get_z_size() - tex->get_pad_z_size();
00985     double cx = (sx * 0.5) / tex->get_x_size();
00986     double cy = (sy * 0.5) / tex->get_y_size();
00987     double cz = (sz * 0.5) / tex->get_z_size();
00988     t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,cx,cy,cz,0);
00989     return &t;
00990   }
00991   case Shader::SMO_texpix_x: {
00992     Texture *tex = _target_shader->get_shader_input_texture(name);
00993     nassertr(tex != 0, &LMatrix4::zeros_mat());
00994     double px = 1.0 / tex->get_x_size();
00995     double py = 1.0 / tex->get_y_size();
00996     double pz = 1.0 / tex->get_z_size();
00997     t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,px,py,pz,0);
00998     return &t;
00999   }
01000   case Shader::SMO_attr_material: {
01001     const MaterialAttrib *target_material = DCAST(MaterialAttrib, _target_rs->get_attrib_def(MaterialAttrib::get_class_slot()));
01002     // Material matrix contains AMBIENT, DIFFUSE, EMISSION, SPECULAR+SHININESS
01003     if (target_material->is_off()) {
01004       t = LMatrix4(1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0);
01005       return &t;
01006     }
01007     Material *m = target_material->get_material();
01008     LVecBase4 const &amb = m->get_ambient();
01009     LVecBase4 const &dif = m->get_diffuse();
01010     LVecBase4 const &emm = m->get_emission();
01011     LVecBase4 spc = m->get_specular();
01012     spc[3] = m->get_shininess();
01013     t = LMatrix4(amb[0],amb[1],amb[2],amb[3],
01014                   dif[0],dif[1],dif[2],dif[3],
01015                   emm[0],emm[1],emm[2],emm[3],
01016                   spc[0],spc[1],spc[2],spc[3]);
01017     return &t;
01018   }
01019   case Shader::SMO_attr_color: {
01020     const ColorAttrib *target_color = DCAST(ColorAttrib, _target_rs->get_attrib_def(ColorAttrib::get_class_slot()));
01021     if (target_color->get_color_type() != ColorAttrib::T_flat) {
01022       return &LMatrix4::ones_mat();
01023     }
01024     LVecBase4 c = target_color->get_color();
01025     t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]);
01026     return &t;
01027   }
01028   case Shader::SMO_attr_colorscale: {
01029     const ColorScaleAttrib *target_color = DCAST(ColorScaleAttrib, _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot()));
01030     if (target_color->is_identity()) {
01031       return &LMatrix4::ones_mat();
01032     }
01033     LVecBase4 cs = target_color->get_scale();
01034     t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,cs[0],cs[1],cs[2],cs[3]);
01035     return &t;
01036   }
01037   case Shader::SMO_attr_fog: {
01038     const FogAttrib *target_fog = DCAST(FogAttrib, _target_rs->get_attrib_def(FogAttrib::get_class_slot()));
01039     Fog *fog = target_fog->get_fog();
01040     if (fog == (Fog*) NULL) {
01041       return &LMatrix4::ones_mat();
01042     }
01043     PN_stdfloat start, end;
01044     fog->get_linear_range(start, end);
01045     t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,fog->get_exp_density(),start,end,1.0f/(end-start));
01046     return &t;
01047   }
01048   case Shader::SMO_attr_fogcolor: {
01049     const FogAttrib *target_fog = DCAST(FogAttrib, _target_rs->get_attrib_def(FogAttrib::get_class_slot()));
01050     Fog *fog = target_fog->get_fog();
01051     if (fog == (Fog*) NULL) {
01052       return &LMatrix4::ones_mat();
01053     }
01054     LVecBase4 c = fog->get_color();
01055     t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]);
01056     return &t;
01057   }
01058   case Shader::SMO_alight_x: {
01059     const NodePath &np = _target_shader->get_shader_input_nodepath(name);
01060     nassertr(!np.is_empty(), &LMatrix4::zeros_mat());
01061     AmbientLight *lt;
01062     DCAST_INTO_R(lt, np.node(), &LMatrix4::zeros_mat());
01063     LColor const &c = lt->get_color();
01064     t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]);
01065     return &t;
01066   }
01067   case Shader::SMO_satten_x: {
01068     const NodePath &np = _target_shader->get_shader_input_nodepath(name);
01069     nassertr(!np.is_empty(), &LMatrix4::ones_mat());
01070     Spotlight *lt;
01071     DCAST_INTO_R(lt, np.node(), &LMatrix4::ones_mat());
01072     LVecBase3 const &a = lt->get_attenuation();
01073     PN_stdfloat x = lt->get_exponent();
01074     t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,a[0],a[1],a[2],x);
01075     return &t;
01076   }
01077   case Shader::SMO_dlight_x: {
01078     // The dlight matrix contains COLOR, SPECULAR, DIRECTION, PSEUDOHALFANGLE
01079     const NodePath &np = _target_shader->get_shader_input_nodepath(name);
01080     nassertr(!np.is_empty(), &LMatrix4::zeros_mat());
01081     DirectionalLight *lt;
01082     DCAST_INTO_R(lt, np.node(), &LMatrix4::zeros_mat());
01083     LColor const &c = lt->get_color();
01084     LColor const &s = lt->get_specular_color();
01085     t = np.get_net_transform()->get_mat() *
01086       get_scene()->get_world_transform()->get_mat();
01087     LVecBase3 d = -(t.xform_vec(lt->get_direction()));
01088     d.normalize();
01089     LVecBase3 h = d + LVecBase3(0,-1,0);
01090     h.normalize();
01091     t = LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],c[3],d[0],d[1],d[2],0,h[0],h[1],h[2],0);
01092     return &t;
01093   }
01094   case Shader::SMO_plight_x: {
01095     // The plight matrix contains COLOR, SPECULAR, POINT, ATTENUATION
01096     const NodePath &np = _target_shader->get_shader_input_nodepath(name);
01097     nassertr(!np.is_empty(), &LMatrix4::ones_mat());
01098     PointLight *lt;
01099     DCAST_INTO_R(lt, np.node(), &LMatrix4::zeros_mat());
01100     LColor const &c = lt->get_color();
01101     LColor const &s = lt->get_specular_color();
01102     t = np.get_net_transform()->get_mat() *
01103       get_scene()->get_world_transform()->get_mat();
01104     LVecBase3 p = (t.xform_point(lt->get_point()));
01105     LVecBase3 a = lt->get_attenuation();
01106     t = LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],s[3],p[0],p[1],p[2],0,a[0],a[1],a[2],0);
01107     return &t;
01108   }
01109   case Shader::SMO_slight_x: {
01110     // The slight matrix contains COLOR, SPECULAR, POINT, DIRECTION
01111     const NodePath &np = _target_shader->get_shader_input_nodepath(name);
01112     nassertr(!np.is_empty(), &LMatrix4::zeros_mat());
01113     Spotlight *lt;
01114     DCAST_INTO_R(lt, np.node(), &LMatrix4::zeros_mat());
01115     Lens *lens = lt->get_lens();
01116     nassertr(lens != (Lens *)NULL, &LMatrix4::zeros_mat());
01117     LColor const &c = lt->get_color();
01118     LColor const &s = lt->get_specular_color();
01119     PN_stdfloat cutoff = ccos(deg_2_rad(lens->get_hfov() * 0.5f));
01120     t = np.get_net_transform()->get_mat() *
01121       get_scene()->get_world_transform()->get_mat();
01122     LVecBase3 p = t.xform_point(lens->get_nodal_point());
01123     LVecBase3 d = -(t.xform_vec(lens->get_view_vector()));
01124     t = LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],s[3],p[0],p[1],p[2],0,d[0],d[1],d[2],cutoff);
01125     return &t;
01126   }
01127   case Shader::SMO_texmat_x: {
01128     const TexMatrixAttrib *tma = DCAST(TexMatrixAttrib, _target_rs->get_attrib_def(TexMatrixAttrib::get_class_slot()));
01129     const TextureAttrib *ta = DCAST(TextureAttrib, _target_rs->get_attrib_def(TextureAttrib::get_class_slot()));
01130     int stagenr = atoi(name->get_name().c_str());
01131     if (stagenr >= ta->get_num_on_stages()) {
01132       return &LMatrix4::ident_mat();
01133     }
01134     return &tma->get_mat(ta->get_on_stage(stagenr));
01135   }
01136   case Shader::SMO_plane_x: {
01137     const NodePath &np = _target_shader->get_shader_input_nodepath(name);
01138     nassertr(!np.is_empty(), &LMatrix4::zeros_mat());
01139     nassertr(np.node()->is_of_type(PlaneNode::get_class_type()), &LMatrix4::zeros_mat());
01140     LPlane p = DCAST(PlaneNode, np.node())->get_plane();
01141     t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,p[0],p[1],p[2],p[3]);
01142     return &t;
01143   }
01144   case Shader::SMO_clipplane_x: {
01145     const ClipPlaneAttrib *cpa = DCAST(ClipPlaneAttrib, _target_rs->get_attrib_def(ClipPlaneAttrib::get_class_slot()));
01146     int planenr = atoi(name->get_name().c_str());
01147     if (planenr >= cpa->get_num_on_planes()) {
01148       return &LMatrix4::zeros_mat();
01149     }
01150     const NodePath &np = cpa->get_on_plane(planenr);
01151     nassertr(!np.is_empty(), &LMatrix4::zeros_mat());
01152     nassertr(np.node()->is_of_type(PlaneNode::get_class_type()), &LMatrix4::zeros_mat());
01153     LPlane p (DCAST(PlaneNode, np.node())->get_plane());
01154     p.xform(np.get_net_transform()->get_mat()); // World-space
01155     t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,p[0],p[1],p[2],p[3]);
01156     return &t;
01157   }
01158   case Shader::SMO_mat_constant_x: {
01159     return &_target_shader->get_shader_input_matrix(name, t);
01160   }
01161   case Shader::SMO_vec_constant_x: {
01162     const LVecBase4 &input = _target_shader->get_shader_input_vector(name);
01163     const PN_stdfloat *data = input.get_data();
01164     t = LMatrix4(data[0],data[1],data[2],data[3],
01165                  data[0],data[1],data[2],data[3],
01166                  data[0],data[1],data[2],data[3],
01167                  data[0],data[1],data[2],data[3]);
01168     return &t;
01169   }
01170   case Shader::SMO_world_to_view: {
01171     return &(get_scene()->get_world_transform()->get_mat());
01172     break;
01173   }
01174   case Shader::SMO_view_to_world: {
01175     return &(get_scene()->get_camera_transform()->get_mat());
01176   }
01177   case Shader::SMO_model_to_view: {
01178     return &(get_external_transform()->get_mat());
01179   }
01180   case Shader::SMO_view_to_model: {
01181     t = get_external_transform()->get_inverse()->get_mat();
01182     return &t;
01183   }
01184   case Shader::SMO_apiview_to_view: {
01185     return &(_inv_cs_transform->get_mat());
01186   }
01187   case Shader::SMO_view_to_apiview: {
01188     return &(_cs_transform->get_mat());
01189   }
01190   case Shader::SMO_clip_to_view: {
01191     if (_current_lens->get_coordinate_system() == _coordinate_system) {
01192       return &(_current_lens->get_projection_mat_inv(_current_stereo_channel));
01193     } else {
01194       t = _current_lens->get_projection_mat_inv(_current_stereo_channel) *
01195         LMatrix4::convert_mat(_current_lens->get_coordinate_system(), _coordinate_system);
01196       return &t;
01197     }
01198   }
01199   case Shader::SMO_view_to_clip: {
01200     if (_current_lens->get_coordinate_system() == _coordinate_system) {
01201       return &(_current_lens->get_projection_mat(_current_stereo_channel));
01202     } else {
01203       t = LMatrix4::convert_mat(_coordinate_system, _current_lens->get_coordinate_system()) *
01204         _current_lens->get_projection_mat(_current_stereo_channel);
01205       return &t;
01206     }
01207   }
01208   case Shader::SMO_apiclip_to_view: {
01209     t = _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat();
01210     return &t;
01211   }
01212   case Shader::SMO_view_to_apiclip: {
01213     t = _cs_transform->get_mat() * _projection_mat->get_mat();
01214     return &t;
01215   }
01216   case Shader::SMO_view_x_to_view: {
01217     const NodePath &np = _target_shader->get_shader_input_nodepath(name);
01218     nassertr(!np.is_empty(), &LMatrix4::ident_mat());
01219     t = np.get_net_transform()->get_mat() *
01220       get_scene()->get_world_transform()->get_mat();
01221     return &t;
01222   }
01223   case Shader::SMO_view_to_view_x: {
01224     const NodePath &np = _target_shader->get_shader_input_nodepath(name);
01225     nassertr(!np.is_empty(), &LMatrix4::ident_mat());
01226     t = get_scene()->get_camera_transform()->get_mat() *
01227       np.get_net_transform()->get_inverse()->get_mat();
01228     return &t;
01229   }
01230   case Shader::SMO_apiview_x_to_view: {
01231     const NodePath &np = _target_shader->get_shader_input_nodepath(name);
01232     nassertr(!np.is_empty(), &LMatrix4::ident_mat());
01233     t = LMatrix4::convert_mat(_internal_coordinate_system, _coordinate_system) *
01234       np.get_net_transform()->get_mat() *
01235       get_scene()->get_world_transform()->get_mat();
01236     return &t;
01237   }
01238   case Shader::SMO_view_to_apiview_x: {
01239     const NodePath &np = _target_shader->get_shader_input_nodepath(name);
01240     nassertr(!np.is_empty(), &LMatrix4::ident_mat());
01241     t = (get_scene()->get_camera_transform()->get_mat() *
01242          np.get_net_transform()->get_inverse()->get_mat() *
01243          LMatrix4::convert_mat(_coordinate_system, _internal_coordinate_system));
01244     return &t;
01245   }
01246   case Shader::SMO_clip_x_to_view: {
01247     const NodePath &np = _target_shader->get_shader_input_nodepath(name);
01248     nassertr(!np.is_empty(), &LMatrix4::ident_mat());
01249     nassertr(np.node()->is_of_type(LensNode::get_class_type()), &LMatrix4::ident_mat());
01250     Lens *lens = DCAST(LensNode, np.node())->get_lens();
01251     t = lens->get_projection_mat_inv(_current_stereo_channel) *
01252       LMatrix4::convert_mat(lens->get_coordinate_system(), _coordinate_system) *
01253       np.get_net_transform()->get_mat() *
01254       get_scene()->get_world_transform()->get_mat();
01255     return &t;
01256   }
01257   case Shader::SMO_view_to_clip_x: {
01258     const NodePath &np = _target_shader->get_shader_input_nodepath(name);
01259     nassertr(!np.is_empty(), &LMatrix4::ident_mat());
01260     nassertr(np.node()->is_of_type(LensNode::get_class_type()), &LMatrix4::ident_mat());
01261     Lens *lens = DCAST(LensNode, np.node())->get_lens();
01262     t = get_scene()->get_camera_transform()->get_mat() *
01263       np.get_net_transform()->get_inverse()->get_mat() *
01264       LMatrix4::convert_mat(_coordinate_system, lens->get_coordinate_system()) *
01265       lens->get_projection_mat(_current_stereo_channel);
01266     return &t;
01267   }
01268   case Shader::SMO_apiclip_x_to_view: {
01269     const NodePath &np = _target_shader->get_shader_input_nodepath(name);
01270     nassertr(!np.is_empty(), &LMatrix4::ident_mat());
01271     nassertr(np.node()->is_of_type(LensNode::get_class_type()), &LMatrix4::ident_mat());
01272     Lens *lens = DCAST(LensNode, np.node())->get_lens();
01273     t = calc_projection_mat(lens)->get_inverse()->get_mat() *
01274       get_cs_transform_for(lens->get_coordinate_system())->get_inverse()->get_mat() *
01275       np.get_net_transform()->get_mat() *
01276       get_scene()->get_world_transform()->get_mat();
01277     return &t;
01278   }
01279   case Shader::SMO_view_to_apiclip_x: {
01280     const NodePath &np = _target_shader->get_shader_input_nodepath(name);
01281     nassertr(!np.is_empty(), &LMatrix4::ident_mat());
01282     nassertr(np.node()->is_of_type(LensNode::get_class_type()), &LMatrix4::ident_mat());
01283     Lens *lens = DCAST(LensNode, np.node())->get_lens();
01284     t = get_scene()->get_camera_transform()->get_mat() *
01285       np.get_net_transform()->get_inverse()->get_mat() *
01286       get_cs_transform_for(lens->get_coordinate_system())->get_mat() *
01287       calc_projection_mat(lens)->get_mat();
01288     return &t;
01289   }
01290   default:
01291     nassertr(false /*should never get here*/, &LMatrix4::ident_mat());
01292     return &LMatrix4::ident_mat();
01293   }
01294 }
01295 
01296 ////////////////////////////////////////////////////////////////////
01297 //     Function: GraphicsStateGuardian::fetch_ptr_parameter
01298 //       Access: Public
01299 //  Description: Return a pointer to struct ShaderPtrData
01300 ////////////////////////////////////////////////////////////////////
01301 const Shader::ShaderPtrData *GraphicsStateGuardian::
01302 fetch_ptr_parameter(const Shader::ShaderPtrSpec& spec) {
01303   return (_target_shader->get_shader_input_ptr(spec._arg));
01304 }
01305 
01306 ////////////////////////////////////////////////////////////////////
01307 //     Function: GraphicsStateGuardian::prepare_display_region
01308 //       Access: Public, Virtual
01309 //  Description: Makes the specified DisplayRegion current.  All
01310 //               future drawing and clear operations will be
01311 //               constrained within the given DisplayRegion.
01312 ////////////////////////////////////////////////////////////////////
01313 void GraphicsStateGuardian::
01314 prepare_display_region(DisplayRegionPipelineReader *dr) {
01315   _current_display_region = dr->get_object();
01316   _current_stereo_channel = dr->get_stereo_channel();
01317   _current_tex_view_offset = dr->get_tex_view_offset();
01318   _effective_incomplete_render = _incomplete_render && _current_display_region->get_incomplete_render();
01319 
01320   _stereo_buffer_mask = ~0;
01321 
01322   Lens::StereoChannel output_channel = dr->get_stereo_channel();
01323   if (dr->get_window()->get_swap_eyes()) {
01324     // Reverse the output channel.
01325     switch (output_channel) {
01326     case Lens::SC_left:
01327       output_channel = Lens::SC_right;
01328       break;
01329 
01330     case Lens::SC_right:
01331       output_channel = Lens::SC_left;
01332       break;
01333 
01334     default:
01335       break;
01336     }
01337   }
01338 
01339   switch (output_channel) {
01340   case Lens::SC_left:
01341     _color_write_mask = dr->get_window()->get_left_eye_color_mask();
01342     if (_current_properties->is_stereo()) {
01343       _stereo_buffer_mask = ~RenderBuffer::T_right;
01344     }
01345     break;
01346 
01347   case Lens::SC_right:
01348     _color_write_mask = dr->get_window()->get_right_eye_color_mask();
01349     if (_current_properties->is_stereo()) {
01350       _stereo_buffer_mask = ~RenderBuffer::T_left;
01351     }
01352     break;
01353 
01354   case Lens::SC_mono:
01355   case Lens::SC_stereo:
01356     _color_write_mask = ColorWriteAttrib::C_all;
01357   }
01358 }
01359 
01360 ////////////////////////////////////////////////////////////////////
01361 //     Function: GraphicsStateGuardian::clear_before_callback
01362 //       Access: Public, Virtual
01363 //  Description: Resets any non-standard graphics state that might
01364 //               give a callback apoplexy.  Some drivers require that
01365 //               the graphics state be restored to neutral before
01366 //               performing certain operations.  In OpenGL, for
01367 //               instance, this closes any open vertex buffers.
01368 ////////////////////////////////////////////////////////////////////
01369 void GraphicsStateGuardian::
01370 clear_before_callback() {
01371 }
01372 
01373 ////////////////////////////////////////////////////////////////////
01374 //     Function: GraphicsStateGuardian::clear_state_and_transform
01375 //       Access: Public, Virtual
01376 //  Description: Forgets the current graphics state and current
01377 //               transform, so that the next call to
01378 //               set_state_and_transform() will have to reload
01379 //               everything.  This is a good thing to call when you
01380 //               are no longer sure what the graphics state is.  This
01381 //               should only be called from the draw thread.
01382 ////////////////////////////////////////////////////////////////////
01383 void GraphicsStateGuardian::
01384 clear_state_and_transform() {
01385   // Re-issue the modelview and projection transforms.
01386   reissue_transforms();
01387 
01388   // Now clear the state flags to unknown.
01389   _state_rs = RenderState::make_empty();
01390   _state_mask.clear();
01391 }
01392 
01393 ////////////////////////////////////////////////////////////////////
01394 //     Function: GraphicsStateGuardian::remove_window
01395 //       Access: Public, Virtual
01396 //  Description: This is simply a transparent call to
01397 //               GraphicsEngine::remove_window().  It exists primary
01398 //               to support removing a window from that compiles
01399 //               before the display module, and therefore has no
01400 //               knowledge of a GraphicsEngine object.
01401 ////////////////////////////////////////////////////////////////////
01402 void GraphicsStateGuardian::
01403 remove_window(GraphicsOutputBase *window) {
01404   nassertv(_engine != (GraphicsEngine *)NULL);
01405   GraphicsOutput *win;
01406   DCAST_INTO_V(win, window);
01407   _engine->remove_window(win);
01408 }
01409 
01410 ////////////////////////////////////////////////////////////////////
01411 //     Function: GraphicsStateGuardian::prepare_lens
01412 //       Access: Public, Virtual
01413 //  Description: Makes the current lens (whichever lens was most
01414 //               recently specified with set_scene()) active, so
01415 //               that it will transform future rendered geometry.
01416 //               Normally this is only called from the draw process,
01417 //               and usually it is called by set_scene().
01418 //
01419 //               The return value is true if the lens is acceptable,
01420 //               false if it is not.
01421 ////////////////////////////////////////////////////////////////////
01422 bool GraphicsStateGuardian::
01423 prepare_lens() {
01424   return false;
01425 }
01426 
01427 ////////////////////////////////////////////////////////////////////
01428 //     Function: GraphicsStateGuardian::calc_projection_mat
01429 //       Access: Public, Virtual
01430 //  Description: Given a lens, this function calculates the appropriate
01431 //               projection matrix for this gsg.  The result depends
01432 //               on the peculiarities of the rendering API.
01433 ////////////////////////////////////////////////////////////////////
01434 CPT(TransformState) GraphicsStateGuardian::
01435 calc_projection_mat(const Lens *lens) {
01436   if (lens == (Lens *)NULL) {
01437     return NULL;
01438   }
01439 
01440   if (!lens->is_linear()) {
01441     return NULL;
01442   }
01443 
01444   return TransformState::make_identity();
01445 }
01446 
01447 ////////////////////////////////////////////////////////////////////
01448 //     Function: GraphicsStateGuardian::begin_frame
01449 //       Access: Public, Virtual
01450 //  Description: Called before each frame is rendered, to allow the
01451 //               GSG a chance to do any internal cleanup before
01452 //               beginning the frame.
01453 //
01454 //               The return value is true if successful (in which case
01455 //               the frame will be drawn and end_frame() will be
01456 //               called later), or false if unsuccessful (in which
01457 //               case nothing will be drawn and end_frame() will not
01458 //               be called).
01459 ////////////////////////////////////////////////////////////////////
01460 bool GraphicsStateGuardian::
01461 begin_frame(Thread *current_thread) {
01462   _prepared_objects->begin_frame(this, current_thread);
01463 
01464   // We should reset the state to the default at the beginning of
01465   // every frame.  Although this will incur additional overhead,
01466   // particularly in a simple scene, it helps ensure that states that
01467   // have changed properties since last time without changing
01468   // attribute pointers--like textures, lighting, or fog--will still
01469   // be accurately updated.
01470   _state_rs = RenderState::make_empty();
01471   _state_mask.clear();
01472 
01473   return !_needs_reset;
01474 }
01475 
01476 ////////////////////////////////////////////////////////////////////
01477 //     Function: GraphicsStateGuardian::begin_scene
01478 //       Access: Published, Virtual
01479 //  Description: Called between begin_frame() and end_frame() to mark
01480 //               the beginning of drawing commands for a "scene"
01481 //               (usually a particular DisplayRegion) within a frame.
01482 //               All 3-D drawing commands, except the clear operation,
01483 //               must be enclosed within begin_scene() .. end_scene().
01484 //               This must be called in the draw thread.
01485 //
01486 //               The return value is true if successful (in which case
01487 //               the scene will be drawn and end_scene() will be
01488 //               called later), or false if unsuccessful (in which
01489 //               case nothing will be drawn and end_scene() will not
01490 //               be called).
01491 ////////////////////////////////////////////////////////////////////
01492 bool GraphicsStateGuardian::
01493 begin_scene() {
01494   return true;
01495 }
01496 
01497 ////////////////////////////////////////////////////////////////////
01498 //     Function: GraphicsStateGuardian::end_scene
01499 //       Access: Published, Virtual
01500 //  Description: Called between begin_frame() and end_frame() to mark
01501 //               the end of drawing commands for a "scene" (usually a
01502 //               particular DisplayRegion) within a frame.  All 3-D
01503 //               drawing commands, except the clear operation, must be
01504 //               enclosed within begin_scene() .. end_scene().
01505 ////////////////////////////////////////////////////////////////////
01506 void GraphicsStateGuardian::
01507 end_scene() {
01508   // We should clear this pointer now, so that we don't keep unneeded
01509   // reference counts dangling.  We keep around a "null" scene setup
01510   // object instead of using a null pointer to avoid special-case code
01511   // in set_state_and_transform.
01512   _scene_setup = _scene_null;
01513 
01514   // Undo any lighting we had enabled last scene, to force the lights
01515   // to be reissued, in case their parameters or positions have
01516   // changed between scenes.
01517   int i;
01518   for (i = 0; i < _num_lights_enabled; ++i) {
01519     enable_light(i, false);
01520   }
01521   _num_lights_enabled = 0;
01522 
01523   // Ditto for the clipping planes.
01524   for (i = 0; i < _num_clip_planes_enabled; ++i) {
01525     enable_clip_plane(i, false);
01526   }
01527   _num_clip_planes_enabled = 0;
01528 
01529   // Put the state into the 'unknown' state, forcing a reload.
01530   _state_rs = RenderState::make_empty();
01531   _state_mask.clear();
01532 }
01533 
01534 ////////////////////////////////////////////////////////////////////
01535 //     Function: GraphicsStateGuardian::end_frame
01536 //       Access: Public, Virtual
01537 //  Description: Called after each frame is rendered, to allow the
01538 //               GSG a chance to do any internal cleanup after
01539 //               rendering the frame, and before the window flips.
01540 ////////////////////////////////////////////////////////////////////
01541 void GraphicsStateGuardian::
01542 end_frame(Thread *current_thread) {
01543   _prepared_objects->end_frame(current_thread);
01544 
01545   // Flush any PStatCollectors.
01546   _data_transferred_pcollector.flush_level();
01547 
01548   _primitive_batches_pcollector.flush_level();
01549   _primitive_batches_tristrip_pcollector.flush_level();
01550   _primitive_batches_trifan_pcollector.flush_level();
01551   _primitive_batches_tri_pcollector.flush_level();
01552   _primitive_batches_patch_pcollector.flush_level();
01553   _primitive_batches_other_pcollector.flush_level();
01554   _vertices_tristrip_pcollector.flush_level();
01555   _vertices_trifan_pcollector.flush_level();
01556   _vertices_tri_pcollector.flush_level();
01557   _vertices_patch_pcollector.flush_level();
01558   _vertices_other_pcollector.flush_level();
01559 
01560   _state_pcollector.flush_level();
01561   _texture_state_pcollector.flush_level();
01562   _transform_state_pcollector.flush_level();
01563   _draw_primitive_pcollector.flush_level();
01564 
01565   // Evict any textures and/or vbuffers that exceed our texture memory.
01566   _prepared_objects->_graphics_memory_lru.begin_epoch();
01567 }
01568 
01569 ////////////////////////////////////////////////////////////////////
01570 //     Function: GraphicsStateGuardian::depth_offset_decals
01571 //       Access: Public, Virtual
01572 //  Description: Returns true if this GSG can implement decals using a
01573 //               DepthOffsetAttrib, or false if that is unreliable
01574 //               and the three-step rendering process should be used
01575 //               instead.
01576 ////////////////////////////////////////////////////////////////////
01577 bool GraphicsStateGuardian::
01578 depth_offset_decals() {
01579   return true;
01580 }
01581 
01582 ////////////////////////////////////////////////////////////////////
01583 //     Function: GraphicsStateGuardian::begin_decal_base_first
01584 //       Access: Public, Virtual
01585 //  Description: Called during draw to begin a three-step rendering
01586 //               phase to draw decals.  The first step,
01587 //               begin_decal_base_first(), is called prior to drawing the
01588 //               base geometry.  It should set up whatever internal
01589 //               state is appropriate, as well as returning a
01590 //               RenderState object that should be applied to the base
01591 //               geometry for rendering.
01592 ////////////////////////////////////////////////////////////////////
01593 CPT(RenderState) GraphicsStateGuardian::
01594 begin_decal_base_first() {
01595   // Turn off writing the depth buffer to render the base geometry.
01596   static CPT(RenderState) decal_base_first;
01597   if (decal_base_first == (const RenderState *)NULL) {
01598     decal_base_first = RenderState::make
01599       (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
01600        RenderState::get_max_priority());
01601   }
01602   return decal_base_first;
01603 }
01604 
01605 ////////////////////////////////////////////////////////////////////
01606 //     Function: GraphicsStateGuardian::begin_decal_nested
01607 //       Access: Public, Virtual
01608 //  Description: Called during draw to begin a three-step rendering
01609 //               phase to draw decals.  The second step,
01610 //               begin_decal_nested(), is called after drawing the
01611 //               base geometry and prior to drawing any of the nested
01612 //               decal geometry that is to be applied to the base
01613 //               geometry.
01614 ////////////////////////////////////////////////////////////////////
01615 CPT(RenderState) GraphicsStateGuardian::
01616 begin_decal_nested() {
01617   // We should keep the depth buffer off during this operation, so
01618   // that decals on decals will render properly.
01619   static CPT(RenderState) decal_nested;
01620   if (decal_nested == (const RenderState *)NULL) {
01621     decal_nested = RenderState::make
01622       (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
01623        RenderState::get_max_priority());
01624   }
01625   return decal_nested;
01626 }
01627 
01628 ////////////////////////////////////////////////////////////////////
01629 //     Function: GraphicsStateGuardian::begin_decal_base_second
01630 //       Access: Public, Virtual
01631 //  Description: Called during draw to begin a three-step rendering
01632 //               phase to draw decals.  The third step,
01633 //               begin_decal_base_second(), is called after drawing the
01634 //               base geometry and the nested decal geometry, and
01635 //               prior to drawing the base geometry one more time (if
01636 //               needed).
01637 //
01638 //               It should return a RenderState object appropriate for
01639 //               rendering the base geometry the second time, or NULL
01640 //               if it is not necessary to re-render the base
01641 //               geometry.
01642 ////////////////////////////////////////////////////////////////////
01643 CPT(RenderState) GraphicsStateGuardian::
01644 begin_decal_base_second() {
01645   // Now let the depth buffer go back on, but turn off writing the
01646   // color buffer to render the base geometry after the second pass.
01647   // Also, turn off texturing since there's no need for it now.
01648   static CPT(RenderState) decal_base_second;
01649   if (decal_base_second == (const RenderState *)NULL) {
01650     decal_base_second = RenderState::make
01651       (ColorWriteAttrib::make(ColorWriteAttrib::C_off),
01652        // On reflection, we need to leave texturing on so the alpha
01653        // test mechanism can work (if it is enabled, e.g. we are
01654        // rendering an object with M_dual transparency).
01655        //       TextureAttrib::make_off(),
01656        RenderState::get_max_priority());
01657   }
01658   return decal_base_second;
01659 }
01660 
01661 ////////////////////////////////////////////////////////////////////
01662 //     Function: GraphicsStateGuardian::finish_decal
01663 //       Access: Public, Virtual
01664 //  Description: Called during draw to clean up after decals are
01665 //               finished.
01666 ////////////////////////////////////////////////////////////////////
01667 void GraphicsStateGuardian::
01668 finish_decal() {
01669   // No need to do anything special here.
01670 }
01671 
01672 ////////////////////////////////////////////////////////////////////
01673 //     Function: GraphicsStateGuardian::begin_draw_primitives()
01674 //       Access: Public, Virtual
01675 //  Description: Called before a sequence of draw_primitive()
01676 //               functions are called, this should prepare the vertex
01677 //               data for rendering.  It returns true if the vertices
01678 //               are ok, false to abort this group of primitives.
01679 ////////////////////////////////////////////////////////////////////
01680 bool GraphicsStateGuardian::
01681 begin_draw_primitives(const GeomPipelineReader *geom_reader,
01682                       const GeomMunger *munger,
01683                       const GeomVertexDataPipelineReader *data_reader,
01684                       bool force) {
01685   _munger = munger;
01686   _data_reader = data_reader;
01687   return _data_reader->has_vertex();
01688 }
01689 
01690 ////////////////////////////////////////////////////////////////////
01691 //     Function: GraphicsStateGuardian::draw_triangles
01692 //       Access: Public, Virtual
01693 //  Description: Draws a series of disconnected triangles.
01694 ////////////////////////////////////////////////////////////////////
01695 bool GraphicsStateGuardian::
01696 draw_triangles(const GeomPrimitivePipelineReader *, bool) {
01697   return false;
01698 }
01699 
01700 ////////////////////////////////////////////////////////////////////
01701 //     Function: GraphicsStateGuardian::draw_tristrips
01702 //       Access: Public, Virtual
01703 //  Description: Draws a series of triangle strips.
01704 ////////////////////////////////////////////////////////////////////
01705 bool GraphicsStateGuardian::
01706 draw_tristrips(const GeomPrimitivePipelineReader *, bool) {
01707   return false;
01708 }
01709 
01710 ////////////////////////////////////////////////////////////////////
01711 //     Function: GraphicsStateGuardian::draw_trifans
01712 //       Access: Public, Virtual
01713 //  Description: Draws a series of triangle fans.
01714 ////////////////////////////////////////////////////////////////////
01715 bool GraphicsStateGuardian::
01716 draw_trifans(const GeomPrimitivePipelineReader *, bool) {
01717   return false;
01718 }
01719 
01720 ////////////////////////////////////////////////////////////////////
01721 //     Function: GraphicsStateGuardian::draw_patches
01722 //       Access: Public, Virtual
01723 //  Description: Draws a series of "patches", which can only be
01724 //               processed by a tessellation shader.
01725 ////////////////////////////////////////////////////////////////////
01726 bool GraphicsStateGuardian::
01727 draw_patches(const GeomPrimitivePipelineReader *, bool) {
01728   return false;
01729 }
01730 
01731 ////////////////////////////////////////////////////////////////////
01732 //     Function: GraphicsStateGuardian::draw_lines
01733 //       Access: Public, Virtual
01734 //  Description: Draws a series of disconnected line segments.
01735 ////////////////////////////////////////////////////////////////////
01736 bool GraphicsStateGuardian::
01737 draw_lines(const GeomPrimitivePipelineReader *, bool) {
01738   return false;
01739 }
01740 
01741 ////////////////////////////////////////////////////////////////////
01742 //     Function: GraphicsStateGuardian::draw_linestrips
01743 //       Access: Public, Virtual
01744 //  Description: Draws a series of line strips.
01745 ////////////////////////////////////////////////////////////////////
01746 bool GraphicsStateGuardian::
01747 draw_linestrips(const GeomPrimitivePipelineReader *, bool) {
01748   return false;
01749 }
01750 
01751 ////////////////////////////////////////////////////////////////////
01752 //     Function: GraphicsStateGuardian::draw_points
01753 //       Access: Public, Virtual
01754 //  Description: Draws a series of disconnected points.
01755 ////////////////////////////////////////////////////////////////////
01756 bool GraphicsStateGuardian::
01757 draw_points(const GeomPrimitivePipelineReader *, bool) {
01758   return false;
01759 }
01760 
01761 ////////////////////////////////////////////////////////////////////
01762 //     Function: GraphicsStateGuardian::end_draw_primitives()
01763 //       Access: Public, Virtual
01764 //  Description: Called after a sequence of draw_primitive()
01765 //               functions are called, this should do whatever cleanup
01766 //               is appropriate.
01767 ////////////////////////////////////////////////////////////////////
01768 void GraphicsStateGuardian::
01769 end_draw_primitives() {
01770   _munger = NULL;
01771   _data_reader = NULL;
01772 }
01773 
01774 ////////////////////////////////////////////////////////////////////
01775 //     Function: GraphicsStateGuardian::reset
01776 //       Access: Public, Virtual
01777 //  Description: Resets all internal state as if the gsg were newly
01778 //               created.
01779 ////////////////////////////////////////////////////////////////////
01780 void GraphicsStateGuardian::
01781 reset() {
01782   _needs_reset = false;
01783   _is_valid = false;
01784 
01785   _state_rs = RenderState::make_empty();
01786   _target_rs = NULL;
01787   _state_mask.clear();
01788   _internal_transform = _cs_transform;
01789   _scene_null = new SceneSetup;
01790   _scene_setup = _scene_null;
01791 
01792   _color_write_mask = ColorWriteAttrib::C_all;
01793 
01794   _has_scene_graph_color = false;
01795   _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
01796   _transform_stale = true;
01797   _color_blend_involves_color_scale = false;
01798   _texture_involves_color_scale = false;
01799   _vertex_colors_enabled = true;
01800   _lighting_enabled = false;
01801   _num_lights_enabled = 0;
01802   _num_clip_planes_enabled = 0;
01803   _clip_planes_enabled = false;
01804 
01805   _color_scale_enabled = false;
01806   _current_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
01807   _has_texture_alpha_scale = false;
01808 
01809   _has_material_force_color = false;
01810   _material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
01811   _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
01812 
01813   _tex_gen_modifies_mat = false;
01814   _last_max_stage_index = 0;
01815 
01816   _is_valid = true;
01817 
01818   if (_stencil_render_states) {
01819     delete _stencil_render_states;
01820     _stencil_render_states = 0;
01821   }
01822   _stencil_render_states = new StencilRenderStates (this);
01823 }
01824 
01825 ////////////////////////////////////////////////////////////////////
01826 //     Function: GraphicsStateGuardian::set_state_and_transform
01827 //       Access: Public
01828 //  Description: Simultaneously resets the render state and the
01829 //               transform state.
01830 //
01831 //               This transform specified is the "internal" net
01832 //               transform, already converted into the GSG's internal
01833 //               coordinate space by composing it to
01834 //               get_cs_transform().  (Previously, this used to be the
01835 //               "external" net transform, with the assumption that
01836 //               that GSG would convert it internally, but that is no
01837 //               longer the case.)
01838 //
01839 //               Special case: if (state==NULL), then the target
01840 //               state is already stored in _target.
01841 ////////////////////////////////////////////////////////////////////
01842 void GraphicsStateGuardian::
01843 set_state_and_transform(const RenderState *state,
01844                         const TransformState *trans) {
01845 }
01846 
01847 ////////////////////////////////////////////////////////////////////
01848 //     Function: GraphicsStateGuardian::clear
01849 //       Access: Public
01850 //  Description: Clears the framebuffer within the current
01851 //               DisplayRegion, according to the flags indicated by
01852 //               the given DrawableRegion object.
01853 //
01854 //               This does not set the DisplayRegion first.  You
01855 //               should call prepare_display_region() to specify the
01856 //               region you wish the clear operation to apply to.
01857 ////////////////////////////////////////////////////////////////////
01858 void GraphicsStateGuardian::
01859 clear(DrawableRegion *clearable) {
01860 }
01861 
01862 ////////////////////////////////////////////////////////////////////
01863 //     Function: GraphicsStateGuardian::get_render_buffer
01864 //       Access: Public
01865 //  Description: Returns a RenderBuffer object suitable for operating
01866 //               on the requested set of buffers.  buffer_type is the
01867 //               union of all the desired RenderBuffer::Type values.
01868 ////////////////////////////////////////////////////////////////////
01869 RenderBuffer GraphicsStateGuardian::
01870 get_render_buffer(int buffer_type, const FrameBufferProperties &prop) {
01871   return RenderBuffer(this, buffer_type & prop.get_buffer_mask() & _stereo_buffer_mask);
01872 }
01873 
01874 ////////////////////////////////////////////////////////////////////
01875 //     Function: GraphicsStateGuardian::get_cs_transform_for
01876 //       Access: Public, Virtual
01877 //  Description: Returns what the cs_transform would be set to after a
01878 //               call to set_coordinate_system(cs).  This is another
01879 //               way of saying the cs_transform when rendering the
01880 //               scene for a camera with the indicated coordinate
01881 //               system.
01882 ////////////////////////////////////////////////////////////////////
01883 CPT(TransformState) GraphicsStateGuardian::
01884 get_cs_transform_for(CoordinateSystem cs) const {
01885   if (_internal_coordinate_system == CS_default ||
01886       _internal_coordinate_system == cs) {
01887     return TransformState::make_identity();
01888 
01889   } else {
01890     return TransformState::make_mat
01891       (LMatrix4::convert_mat(cs, _internal_coordinate_system));
01892   }
01893 }
01894 
01895 ////////////////////////////////////////////////////////////////////
01896 //     Function: GraphicsStateGuardian::get_cs_transform
01897 //       Access: Public, Virtual
01898 //  Description: Returns a transform that converts from the GSG's
01899 //               external coordinate system (as returned by
01900 //               get_coordinate_system()) to its internal coordinate
01901 //               system (as returned by
01902 //               get_internal_coordinate_system()).  This is used for
01903 //               rendering.
01904 ////////////////////////////////////////////////////////////////////
01905 CPT(TransformState) GraphicsStateGuardian::
01906 get_cs_transform() const {
01907   return _cs_transform;
01908 }
01909 
01910 ////////////////////////////////////////////////////////////////////
01911 //     Function: GraphicsStateGuardian::do_issue_clip_plane
01912 //       Access: Public
01913 //  Description: This is fundametically similar to do_issue_light(), with
01914 //               calls to apply_clip_plane() and enable_clip_planes(),
01915 //               as appropriate.
01916 ////////////////////////////////////////////////////////////////////
01917 void GraphicsStateGuardian::
01918 do_issue_clip_plane() {
01919   int num_enabled = 0;
01920   int num_on_planes = 0;
01921 
01922   const ClipPlaneAttrib *target_clip_plane = DCAST(ClipPlaneAttrib, _target_rs->get_attrib_def(ClipPlaneAttrib::get_class_slot()));
01923   if (target_clip_plane != (ClipPlaneAttrib *)NULL) {
01924     CPT(ClipPlaneAttrib) new_plane = target_clip_plane->filter_to_max(_max_clip_planes);
01925 
01926     num_on_planes = new_plane->get_num_on_planes();
01927     for (int li = 0; li < num_on_planes; li++) {
01928       NodePath plane = new_plane->get_on_plane(li);
01929       nassertv(!plane.is_empty());
01930       PlaneNode *plane_node;
01931       DCAST_INTO_V(plane_node, plane.node());
01932       if ((plane_node->get_clip_effect() & PlaneNode::CE_visible) != 0) {
01933         // Clipping should be enabled before we apply any planes.
01934         if (!_clip_planes_enabled) {
01935           enable_clip_planes(true);
01936           _clip_planes_enabled = true;
01937         }
01938         
01939         enable_clip_plane(num_enabled, true);
01940         if (num_enabled == 0) {
01941           begin_bind_clip_planes();
01942         }
01943         
01944         bind_clip_plane(plane, num_enabled);
01945         num_enabled++;
01946       }
01947     }
01948   }
01949 
01950   int i;
01951   for (i = num_enabled; i < _num_clip_planes_enabled; ++i) {
01952     enable_clip_plane(i, false);
01953   }
01954   _num_clip_planes_enabled = num_enabled;
01955 
01956   // If no planes were set, disable clipping
01957   if (num_enabled == 0) {
01958     if (_clip_planes_enabled) {
01959       enable_clip_planes(false);
01960       _clip_planes_enabled = false;
01961     }
01962   } else {
01963     end_bind_clip_planes();
01964   }
01965 }
01966 
01967 ////////////////////////////////////////////////////////////////////
01968 //     Function: GraphicsStateGuardian::do_issue_color
01969 //       Access: Public
01970 //  Description: This method is defined in the base class because it
01971 //               is likely that this functionality will be used for
01972 //               all (or at least most) kinds of
01973 //               GraphicsStateGuardians--it's not specific to any one
01974 //               rendering backend.
01975 //
01976 //               The ColorAttribute just changes the interpretation of
01977 //               the color on the vertices, and fiddles with
01978 //               _vertex_colors_enabled, etc.
01979 ////////////////////////////////////////////////////////////////////
01980 void GraphicsStateGuardian::
01981 do_issue_color() {
01982   const ColorAttrib *target_color = DCAST(ColorAttrib, _target_rs->get_attrib_def(ColorAttrib::get_class_slot()));
01983   switch (target_color->get_color_type()) {
01984   case ColorAttrib::T_flat:
01985     // Color attribute flat: it specifies a scene graph color that
01986     // overrides the vertex color.
01987     _scene_graph_color = target_color->get_color();
01988     _has_scene_graph_color = true;
01989     _vertex_colors_enabled = false;
01990     break;
01991 
01992   case ColorAttrib::T_off:
01993     // Color attribute off: it specifies that no scene graph color is
01994     // in effect, and vertex color is not important either.
01995     _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
01996     _has_scene_graph_color = false;
01997     _vertex_colors_enabled = false;
01998     break;
01999 
02000   case ColorAttrib::T_vertex:
02001     // Color attribute vertex: it specifies that vertex color should
02002     // be revealed.
02003     _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
02004     _has_scene_graph_color = false;
02005     _vertex_colors_enabled = true;
02006     break;
02007   }
02008 
02009   if (_color_scale_via_lighting) {
02010     _state_mask.clear_bit(LightAttrib::get_class_slot());
02011     _state_mask.clear_bit(MaterialAttrib::get_class_slot());
02012 
02013     determine_light_color_scale();
02014   }
02015 }
02016 
02017 ////////////////////////////////////////////////////////////////////
02018 //     Function: GraphicsStateGuardian::do_issue_color_scale
02019 //       Access: Public, Virtual
02020 //  Description:
02021 ////////////////////////////////////////////////////////////////////
02022 void GraphicsStateGuardian::
02023 do_issue_color_scale() {
02024   // If the previous color scale had set a special texture, clear the
02025   // texture now.
02026   if (_has_texture_alpha_scale) {
02027     _state_mask.clear_bit(TextureAttrib::get_class_slot());
02028   }
02029 
02030   const ColorScaleAttrib *target_color_scale = DCAST(ColorScaleAttrib, _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot()));
02031   _color_scale_enabled = target_color_scale->has_scale();
02032   _current_color_scale = target_color_scale->get_scale();
02033   _has_texture_alpha_scale = false;
02034 
02035   if (_color_blend_involves_color_scale) {
02036     _state_mask.clear_bit(TransparencyAttrib::get_class_slot());
02037   }
02038   if (_texture_involves_color_scale) {
02039     _state_mask.clear_bit(TextureAttrib::get_class_slot());
02040   }
02041   if (_color_scale_via_lighting) {
02042     _state_mask.clear_bit(LightAttrib::get_class_slot());
02043     _state_mask.clear_bit(MaterialAttrib::get_class_slot());
02044 
02045     determine_light_color_scale();
02046   }
02047 
02048   if (_alpha_scale_via_texture && !_has_scene_graph_color &&
02049       target_color_scale->has_alpha_scale()) {
02050     // This color scale will set a special texture--so again, clear
02051     // the texture.
02052     _state_mask.clear_bit(TextureAttrib::get_class_slot());
02053     _state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
02054 
02055     _has_texture_alpha_scale = true;
02056   }
02057 }
02058 
02059 ////////////////////////////////////////////////////////////////////
02060 //     Function: GraphicsStateGuardian::do_issue_light
02061 //       Access: Protected, Virtual
02062 //  Description: This implementation of do_issue_light() assumes
02063 //               we have a limited number of hardware lights
02064 //               available.  This function assigns each light to a
02065 //               different hardware light id, trying to keep each
02066 //               light associated with the same id where possible, but
02067 //               reusing id's when necessary.  When it is no longer
02068 //               possible to reuse existing id's (e.g. all id's are in
02069 //               use), the next sequential id is assigned (if
02070 //               available).
02071 //
02072 //               It will call apply_light() each time a light is
02073 //               assigned to a particular id for the first time in a
02074 //               given frame, and it will subsequently call
02075 //               enable_light() to enable or disable each light as the
02076 //               frame is rendered, as well as enable_lighting() to
02077 //               enable or disable overall lighting.
02078 ////////////////////////////////////////////////////////////////////
02079 void GraphicsStateGuardian::
02080 do_issue_light() {
02081   // Initialize the current ambient light total and newly enabled
02082   // light list
02083   LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
02084   int i;
02085 
02086   int num_enabled = 0;
02087   int num_on_lights = 0;
02088 
02089   const LightAttrib *target_light = DCAST(LightAttrib, _target_rs->get_attrib_def(LightAttrib::get_class_slot()));
02090   if (display_cat.is_spam()) {
02091     display_cat.spam()
02092       << "do_issue_light: " << target_light << "\n";
02093   }
02094   if (target_light != (LightAttrib *)NULL) {
02095     CPT(LightAttrib) new_light = target_light->filter_to_max(_max_lights);
02096     if (display_cat.is_spam()) {
02097       new_light->write(display_cat.spam(false), 2);
02098     }
02099 
02100     num_on_lights = new_light->get_num_on_lights();
02101     for (int li = 0; li < num_on_lights; li++) {
02102       NodePath light = new_light->get_on_light(li);
02103       nassertv(!light.is_empty());
02104       Light *light_obj = light.node()->as_light();
02105       nassertv(light_obj != (Light *)NULL);
02106 
02107       // Lighting should be enabled before we apply any lights.
02108       if (!_lighting_enabled) {
02109         enable_lighting(true);
02110         _lighting_enabled = true;
02111       }
02112 
02113       if (light_obj->get_type() == AmbientLight::get_class_type()) {
02114         // Ambient lights don't require specific light ids; simply add
02115         // in the ambient contribution to the current total
02116         cur_ambient_light += light_obj->get_color();
02117 
02118       } else {
02119         const LColor &color = light_obj->get_color();
02120         // Don't bother binding the light if it has no color to contribute.
02121         if (color[0] != 0.0 || color[1] != 0.0 || color[2] != 0.0) {
02122           enable_light(num_enabled, true);
02123           if (num_enabled == 0) {
02124             begin_bind_lights();
02125           }
02126           
02127           light_obj->bind(this, light, num_enabled);
02128           num_enabled++;
02129         }
02130       }
02131     }
02132   }
02133 
02134   for (i = num_enabled; i < _num_lights_enabled; ++i) {
02135     enable_light(i, false);
02136   }
02137   _num_lights_enabled = num_enabled;
02138 
02139   // If no lights were set, disable lighting
02140   if (num_on_lights == 0) {
02141     if (_color_scale_via_lighting && (_has_material_force_color || _light_color_scale != LVecBase4(1.0f, 1.0f, 1.0f, 1.0f))) {
02142       // Unless we need lighting anyway to apply a color or color
02143       // scale.
02144       if (!_lighting_enabled) {
02145         enable_lighting(true);
02146         _lighting_enabled = true;
02147       }
02148       set_ambient_light(LColor(1.0f, 1.0f, 1.0f, 1.0f));
02149 
02150     } else {
02151       if (_lighting_enabled) {
02152         enable_lighting(false);
02153         _lighting_enabled = false;
02154       }
02155     }
02156 
02157   } else {
02158     set_ambient_light(cur_ambient_light);
02159   }
02160 
02161   if (num_enabled != 0) {
02162     end_bind_lights();
02163   }
02164 }
02165 
02166 ////////////////////////////////////////////////////////////////////
02167 //     Function: GraphicsStateGuardian::framebuffer_copy_to_texture
02168 //       Access: Public, Virtual
02169 //  Description: Copy the pixels within the indicated display
02170 //               region from the framebuffer into texture memory.
02171 //
02172 //               If z > -1, it is the cube map index into which to
02173 //               copy.
02174 ////////////////////////////////////////////////////////////////////
02175 bool GraphicsStateGuardian::
02176 framebuffer_copy_to_texture(Texture *, int, int, const DisplayRegion *,
02177                             const RenderBuffer &) {
02178   return false;
02179 }
02180 
02181 
02182 ////////////////////////////////////////////////////////////////////
02183 //     Function: GraphicsStateGuardian::framebuffer_copy_to_ram
02184 //       Access: Public, Virtual
02185 //  Description: Copy the pixels within the indicated display region
02186 //               from the framebuffer into system memory, not texture
02187 //               memory.  Returns true on success, false on failure.
02188 //
02189 //               This completely redefines the ram image of the
02190 //               indicated texture.
02191 ////////////////////////////////////////////////////////////////////
02192 bool GraphicsStateGuardian::
02193 framebuffer_copy_to_ram(Texture *, int, int, const DisplayRegion *,
02194                         const RenderBuffer &) {
02195   return false;
02196 }
02197 
02198 ////////////////////////////////////////////////////////////////////
02199 //     Function: GraphicsStateGuardian::bind_light
02200 //       Access: Public, Virtual
02201 //  Description: Called the first time a particular light has been
02202 //               bound to a given id within a frame, this should set
02203 //               up the associated hardware light with the light's
02204 //               properties.
02205 ////////////////////////////////////////////////////////////////////
02206 void GraphicsStateGuardian::
02207 bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
02208 }
02209 
02210 ////////////////////////////////////////////////////////////////////
02211 //     Function: GraphicsStateGuardian::bind_light
02212 //       Access: Public, Virtual
02213 //  Description: Called the first time a particular light has been
02214 //               bound to a given id within a frame, this should set
02215 //               up the associated hardware light with the light's
02216 //               properties.
02217 ////////////////////////////////////////////////////////////////////
02218 void GraphicsStateGuardian::
02219 bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
02220 }
02221 
02222 ////////////////////////////////////////////////////////////////////
02223 //     Function: GraphicsStateGuardian::bind_light
02224 //       Access: Public, Virtual
02225 //  Description: Called the first time a particular light has been
02226 //               bound to a given id within a frame, this should set
02227 //               up the associated hardware light with the light's
02228 //               properties.
02229 ////////////////////////////////////////////////////////////////////
02230 void GraphicsStateGuardian::
02231 bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
02232 }
02233 
02234 #ifdef DO_PSTATS
02235 ////////////////////////////////////////////////////////////////////
02236 //     Function: GraphicsStateGuardian::init_frame_pstats
02237 //       Access: Public, Static
02238 //  Description: Initializes the relevant PStats data at the beginning
02239 //               of the frame.
02240 ////////////////////////////////////////////////////////////////////
02241 void GraphicsStateGuardian::
02242 init_frame_pstats() {
02243   if (PStatClient::is_connected()) {
02244     _data_transferred_pcollector.clear_level();
02245     _vertex_buffer_switch_pcollector.clear_level();
02246     _index_buffer_switch_pcollector.clear_level();
02247 
02248     _primitive_batches_pcollector.clear_level();
02249     _primitive_batches_tristrip_pcollector.clear_level();
02250     _primitive_batches_trifan_pcollector.clear_level();
02251     _primitive_batches_tri_pcollector.clear_level();
02252     _primitive_batches_patch_pcollector.clear_level();
02253     _primitive_batches_other_pcollector.clear_level();
02254     _vertices_tristrip_pcollector.clear_level();
02255     _vertices_trifan_pcollector.clear_level();
02256     _vertices_tri_pcollector.clear_level();
02257     _vertices_patch_pcollector.clear_level();
02258     _vertices_other_pcollector.clear_level();
02259 
02260     _state_pcollector.clear_level();
02261     _transform_state_pcollector.clear_level();
02262     _texture_state_pcollector.clear_level();
02263   }
02264 }
02265 #endif  // DO_PSTATS
02266 
02267 
02268 ////////////////////////////////////////////////////////////////////
02269 //     Function: GraphicsStateGuardian::create_gamma_table
02270 //       Access: Public, Static
02271 //  Description: Create a gamma table.
02272 ////////////////////////////////////////////////////////////////////
02273 void GraphicsStateGuardian::
02274 create_gamma_table (PN_stdfloat gamma, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table) {
02275   int i;
02276 
02277   if (gamma <= 0.0) {
02278     // avoid divide by zero and negative exponents
02279     gamma = 1.0;
02280   }
02281   
02282   for (i = 0; i < 256; i++) {
02283     double g;
02284     double x;
02285     PN_stdfloat gamma_correction;
02286     
02287     x = ((double) i / 255.0);
02288     gamma_correction = 1.0 / gamma;    
02289     x = pow (x, (double) gamma_correction);
02290     if (x > 1.00) {
02291       x = 1.0;
02292     }
02293 
02294     g = x * 65535.0;    
02295     red_table [i] = (int)g;
02296     green_table [i] = (int)g;
02297     blue_table [i] = (int)g;
02298   }    
02299 }
02300 
02301 ////////////////////////////////////////////////////////////////////
02302 //     Function: GraphicsStateGuardian::reissue_transforms
02303 //       Access: Protected, Virtual
02304 //  Description: Called by clear_state_and_transform() to ensure that
02305 //               the current modelview and projection matrices are
02306 //               properly loaded in the graphics state, after a
02307 //               callback might have mucked them up.
02308 ////////////////////////////////////////////////////////////////////
02309 void GraphicsStateGuardian::
02310 reissue_transforms() {
02311 }
02312 
02313 ////////////////////////////////////////////////////////////////////
02314 //     Function: GraphicsStateGuardian::enable_lighting
02315 //       Access: Protected, Virtual
02316 //  Description: Intended to be overridden by a derived class to
02317 //               enable or disable the use of lighting overall.  This
02318 //               is called by do_issue_light() according to whether any
02319 //               lights are in use or not.
02320 ////////////////////////////////////////////////////////////////////
02321 void GraphicsStateGuardian::
02322 enable_lighting(bool enable) {
02323 }
02324 
02325 ////////////////////////////////////////////////////////////////////
02326 //     Function: GraphicsStateGuardian::set_ambient_light
02327 //       Access: Protected, Virtual
02328 //  Description: Intended to be overridden by a derived class to
02329 //               indicate the color of the ambient light that should
02330 //               be in effect.  This is called by do_issue_light() after
02331 //               all other lights have been enabled or disabled.
02332 ////////////////////////////////////////////////////////////////////
02333 void GraphicsStateGuardian::
02334 set_ambient_light(const LColor &color) {
02335 }
02336 
02337 ////////////////////////////////////////////////////////////////////
02338 //     Function: GraphicsStateGuardian::enable_light
02339 //       Access: Protected, Virtual
02340 //  Description: Intended to be overridden by a derived class to
02341 //               enable the indicated light id.  A specific Light will
02342 //               already have been bound to this id via bind_light().
02343 ////////////////////////////////////////////////////////////////////
02344 void GraphicsStateGuardian::
02345 enable_light(int light_id, bool enable) {
02346 }
02347 
02348 ////////////////////////////////////////////////////////////////////
02349 //     Function: GraphicsStateGuardian::begin_bind_lights
02350 //       Access: Protected, Virtual
02351 //  Description: Called immediately before bind_light() is called,
02352 //               this is intended to provide the derived class a hook
02353 //               in which to set up some state (like transform) that
02354 //               might apply to several lights.
02355 //
02356 //               The sequence is: begin_bind_lights() will be called,
02357 //               then one or more bind_light() calls, then
02358 //               end_bind_lights().
02359 ////////////////////////////////////////////////////////////////////
02360 void GraphicsStateGuardian::
02361 begin_bind_lights() {
02362 }
02363 
02364 ////////////////////////////////////////////////////////////////////
02365 //     Function: GraphicsStateGuardian::end_bind_lights
02366 //       Access: Protected, Virtual
02367 //  Description: Called after before bind_light() has been called one
02368 //               or more times (but before any geometry is issued or
02369 //               additional state is changed), this is intended to
02370 //               clean up any temporary changes to the state that may
02371 //               have been made by begin_bind_lights().
02372 ////////////////////////////////////////////////////////////////////
02373 void GraphicsStateGuardian::
02374 end_bind_lights() {
02375 }
02376 
02377 ////////////////////////////////////////////////////////////////////
02378 //     Function: GraphicsStateGuardian::enable_clip_planes
02379 //       Access: Protected, Virtual
02380 //  Description: Intended to be overridden by a derived class to
02381 //               enable or disable the use of clipping planes overall.
02382 //               This is called by do_issue_clip_plane() according to
02383 //               whether any planes are in use or not.
02384 ////////////////////////////////////////////////////////////////////
02385 void GraphicsStateGuardian::
02386 enable_clip_planes(bool enable) {
02387 }
02388 
02389 ////////////////////////////////////////////////////////////////////
02390 //     Function: GraphicsStateGuardian::enable_clip_plane
02391 //       Access: Protected, Virtual
02392 //  Description: Intended to be overridden by a derived class to
02393 //               enable the indicated plane id.  A specific PlaneNode
02394 //               will already have been bound to this id via
02395 //               bind_clip_plane().
02396 ////////////////////////////////////////////////////////////////////
02397 void GraphicsStateGuardian::
02398 enable_clip_plane(int plane_id, bool enable) {
02399 }
02400 
02401 ////////////////////////////////////////////////////////////////////
02402 //     Function: GraphicsStateGuardian::begin_bind_clip_planes
02403 //       Access: Protected, Virtual
02404 //  Description: Called immediately before bind_clip_plane() is called,
02405 //               this is intended to provide the derived class a hook
02406 //               in which to set up some state (like transform) that
02407 //               might apply to several planes.
02408 //
02409 //               The sequence is: begin_bind_clip_planes() will be
02410 //               called, then one or more bind_clip_plane() calls,
02411 //               then end_bind_clip_planes().
02412 ////////////////////////////////////////////////////////////////////
02413 void GraphicsStateGuardian::
02414 begin_bind_clip_planes() {
02415 }
02416 
02417 ////////////////////////////////////////////////////////////////////
02418 //     Function: GraphicsStateGuardian::bind_clip_plane
02419 //       Access: Public, Virtual
02420 //  Description: Called the first time a particular clipping plane has been
02421 //               bound to a given id within a frame, this should set
02422 //               up the associated hardware (or API) clipping plane
02423 //               with the plane's properties.
02424 ////////////////////////////////////////////////////////////////////
02425 void GraphicsStateGuardian::
02426 bind_clip_plane(const NodePath &plane, int plane_id) {
02427 }
02428 
02429 ////////////////////////////////////////////////////////////////////
02430 //     Function: GraphicsStateGuardian::end_bind_clip_planes
02431 //       Access: Protected, Virtual
02432 //  Description: Called after before bind_clip_plane() has been called one
02433 //               or more times (but before any geometry is issued or
02434 //               additional state is changed), this is intended to
02435 //               clean up any temporary changes to the state that may
02436 //               have been made by begin_bind_clip_planes().
02437 ////////////////////////////////////////////////////////////////////
02438 void GraphicsStateGuardian::
02439 end_bind_clip_planes() {
02440 }
02441 
02442 ////////////////////////////////////////////////////////////////////
02443 //     Function: GraphicsStateGuardian::determine_target_texture
02444 //       Access: Protected
02445 //  Description: Assigns _target_texture and _target_tex_gen
02446 //               based on the _target_rs.
02447 ////////////////////////////////////////////////////////////////////
02448 void GraphicsStateGuardian::
02449 determine_target_texture() {
02450   const TextureAttrib *target_texture = DCAST(TextureAttrib, _target_rs->get_attrib_def(TextureAttrib::get_class_slot()));
02451   const TexGenAttrib *target_tex_gen = DCAST(TexGenAttrib, _target_rs->get_attrib_def(TexGenAttrib::get_class_slot()));
02452 
02453   nassertv(target_texture != (TextureAttrib *)NULL &&
02454            target_tex_gen != (TexGenAttrib *)NULL);
02455   _target_texture = target_texture;
02456   _target_tex_gen = target_tex_gen;
02457 
02458   if (_has_texture_alpha_scale) {
02459     PT(TextureStage) stage = get_alpha_scale_texture_stage();
02460     PT(Texture) texture = TexturePool::get_alpha_scale_map();
02461 
02462     _target_texture = DCAST(TextureAttrib, _target_texture->add_on_stage(stage, texture));
02463     _target_tex_gen = DCAST(TexGenAttrib, _target_tex_gen->add_stage
02464                                (stage, TexGenAttrib::M_constant, LTexCoord3(_current_color_scale[3], 0.0f, 0.0f)));
02465   }
02466 
02467   int max_texture_stages = get_max_texture_stages();
02468   _target_texture = _target_texture->filter_to_max(max_texture_stages);
02469   nassertv(_target_texture->get_num_on_stages() <= max_texture_stages);
02470 }
02471 
02472 ////////////////////////////////////////////////////////////////////
02473 //     Function: GraphicsStateGuardian::free_pointers
02474 //       Access: Protected, Virtual
02475 //  Description: Frees some memory that was explicitly allocated
02476 //               within the glgsg.
02477 ////////////////////////////////////////////////////////////////////
02478 void GraphicsStateGuardian::
02479 free_pointers() {
02480 }
02481 
02482 ////////////////////////////////////////////////////////////////////
02483 //     Function: GraphicsStateGuardian::close_gsg
02484 //       Access: Protected, Virtual
02485 //  Description: This is called by the associated GraphicsWindow when
02486 //               close_window() is called.  It should null out the
02487 //               _win pointer and possibly free any open resources
02488 //               associated with the GSG.
02489 ////////////////////////////////////////////////////////////////////
02490 void GraphicsStateGuardian::
02491 close_gsg() {
02492   // Protect from multiple calls, and also inform any other functions
02493   // not to try to create new stuff while we're going down.
02494   if (_closing_gsg) {
02495     return;
02496   }
02497   _closing_gsg = true;
02498 
02499   if (display_cat.is_debug()) {
02500     display_cat.debug()
02501       << this << " close_gsg " << get_type() << "\n";
02502   }
02503   free_pointers();
02504 
02505   // As tempting as it may be to try to release all the textures and
02506   // geoms now, we can't, because we might not be the currently-active
02507   // GSG (this is particularly important in OpenGL, which maintains
02508   // one currently-active GL state in each thread).  If we start
02509   // deleting textures, we'll be inadvertently deleting textures from
02510   // some other OpenGL state.
02511 
02512   // Fortunately, it doesn't really matter, since the graphics API
02513   // will be responsible for cleaning up anything we don't clean up
02514   // explicitly.  We'll just let them drop.
02515 
02516   // However, if any objects have recently been released, we have to
02517   // ensure they are actually deleted properly.
02518   Thread *current_thread = Thread::get_current_thread();
02519   _prepared_objects->begin_frame(this, current_thread);
02520   _prepared_objects->end_frame(current_thread);
02521 }
02522 
02523 ////////////////////////////////////////////////////////////////////
02524 //     Function: GraphicsStateGuardian::panic_deactivate
02525 //       Access: Protected
02526 //  Description: This is called internally when it is determined that
02527 //               things are just fubar.  It temporarily deactivates
02528 //               the GSG just so things don't get out of hand, and
02529 //               throws an event so the application can deal with this
02530 //               if it needs to.
02531 ////////////////////////////////////////////////////////////////////
02532 void GraphicsStateGuardian::
02533 panic_deactivate() {
02534   if (_active) {
02535     display_cat.error()
02536       << "Deactivating " << get_type() << ".\n";
02537     set_active(false);
02538     throw_event("panic-deactivate-gsg", this);
02539   }
02540 }
02541 
02542 ////////////////////////////////////////////////////////////////////
02543 //     Function: GraphicsStateGuardian::determine_light_color_scale
02544 //       Access: Protected
02545 //  Description: Called whenever the color or color scale is changed,
02546 //               if _color_scale_via_lighting is true.  This will
02547 //               rederive _material_force_color and _light_color_scale
02548 //               appropriately.
02549 ////////////////////////////////////////////////////////////////////
02550 void GraphicsStateGuardian::
02551 determine_light_color_scale() {
02552   if (_has_scene_graph_color) {
02553     // If we have a scene graph color, it, plus the color scale, goes
02554     // directly into the material; we don't color scale the
02555     // lights--this allows an alpha color scale to work properly.
02556     _has_material_force_color = true;
02557     _material_force_color = _scene_graph_color;
02558     _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
02559     if (!_color_blend_involves_color_scale && _color_scale_enabled) {
02560       _material_force_color.set(_scene_graph_color[0] * _current_color_scale[0],
02561                                 _scene_graph_color[1] * _current_color_scale[1],
02562                                 _scene_graph_color[2] * _current_color_scale[2],
02563                                 _scene_graph_color[3] * _current_color_scale[3]);
02564     }
02565 
02566   } else {
02567     // Otherise, leave the materials alone, but we might still scale
02568     // the lights.
02569     _has_material_force_color = false;
02570     _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
02571     if (!_color_blend_involves_color_scale && _color_scale_enabled) {
02572       _light_color_scale = _current_color_scale;
02573     }
02574   }
02575 }
02576 
02577 ////////////////////////////////////////////////////////////////////
02578 //     Function: GraphicsStateGuardian::get_unlit_state
02579 //       Access: Protected, Static
02580 //  Description:
02581 ////////////////////////////////////////////////////////////////////
02582 CPT(RenderState) GraphicsStateGuardian::
02583 get_unlit_state() {
02584   static CPT(RenderState) state = NULL;
02585   if (state == (const RenderState *)NULL) {
02586     state = RenderState::make(LightAttrib::make_all_off());
02587   }
02588   return state;
02589 }
02590 
02591 ////////////////////////////////////////////////////////////////////
02592 //     Function: GraphicsStateGuardian::get_unclipped_state
02593 //       Access: Protected, Static
02594 //  Description:
02595 ////////////////////////////////////////////////////////////////////
02596 CPT(RenderState) GraphicsStateGuardian::
02597 get_unclipped_state() {
02598   static CPT(RenderState) state = NULL;
02599   if (state == (const RenderState *)NULL) {
02600     state = RenderState::make(ClipPlaneAttrib::make_all_off());
02601   }
02602   return state;
02603 }
02604 
02605 ////////////////////////////////////////////////////////////////////
02606 //     Function: GraphicsStateGuardian::get_untextured_state
02607 //       Access: Protected, Static
02608 //  Description:
02609 ////////////////////////////////////////////////////////////////////
02610 CPT(RenderState) GraphicsStateGuardian::
02611 get_untextured_state() {
02612   static CPT(RenderState) state = NULL;
02613   if (state == (const RenderState *)NULL) {
02614     state = RenderState::make(TextureAttrib::make_off());
02615   }
02616   return state;
02617 }
02618 
02619 ////////////////////////////////////////////////////////////////////
02620 //     Function: GraphicsStateGuardian::async_reload_texture
02621 //       Access: Protected
02622 //  Description: Should be called when a texture is encountered that
02623 //               needs to have its RAM image reloaded, and
02624 //               get_incomplete_render() is true.  This will fire off
02625 //               a thread on the current Loader object that will
02626 //               request the texture to load its image.  The image
02627 //               will be available at some point in the future (no
02628 //               event will be generated).
02629 ////////////////////////////////////////////////////////////////////
02630 void GraphicsStateGuardian::
02631 async_reload_texture(TextureContext *tc) {
02632   nassertv(_loader != (Loader *)NULL);
02633 
02634   int priority = 0;
02635   if (_current_display_region != (DisplayRegion *)NULL) {
02636     priority = _current_display_region->get_texture_reload_priority();
02637   }
02638 
02639   string task_name = string("reload:") + tc->get_texture()->get_name();
02640   PT(AsyncTaskManager) task_mgr = _loader->get_task_manager();
02641   
02642   // See if we are already loading this task.
02643   AsyncTaskCollection orig_tasks = task_mgr->find_tasks(task_name);
02644   int num_tasks = orig_tasks.get_num_tasks();
02645   for (int ti = 0; ti < num_tasks; ++ti) {
02646     AsyncTask *task = orig_tasks.get_task(ti);
02647     if (task->is_exact_type(TextureReloadRequest::get_class_type()) &&
02648         DCAST(TextureReloadRequest, task)->get_texture() == tc->get_texture()) {
02649       // This texture is already queued to be reloaded.  Don't queue
02650       // it again, just make sure the priority is updated, and return.
02651       task->set_priority(max(task->get_priority(), priority));
02652       return;
02653     }
02654   }
02655 
02656   // This texture has not yet been queued to be reloaded.  Queue it up
02657   // now.
02658   PT(AsyncTask) request = 
02659     new TextureReloadRequest(task_name,
02660                              _prepared_objects, tc->get_texture(),
02661                              _supports_compressed_texture);
02662   request->set_priority(priority);
02663   _loader->load_async(request);
02664 }
02665 
02666 ////////////////////////////////////////////////////////////////////
02667 //     Function: GraphicsStateGuardian::make_shadow_buffer
02668 //       Access: Protected
02669 //  Description: Creates a depth buffer for shadow mapping. This
02670 //               is a convenience function for the ShaderGenerator;
02671 //               putting this directly in the ShaderGenerator would
02672 //               cause circular dependency issues.
02673 //               Returns the depth texture.
02674 ////////////////////////////////////////////////////////////////////
02675 PT(Texture) GraphicsStateGuardian::
02676 make_shadow_buffer(const NodePath &light_np, GraphicsOutputBase *host) {
02677   // Make sure everything is valid.
02678   nassertr(light_np.node()->is_of_type(DirectionalLight::get_class_type()) ||
02679            light_np.node()->is_of_type(PointLight::get_class_type()) ||
02680            light_np.node()->is_of_type(Spotlight::get_class_type()), NULL);
02681 
02682   PT(LightLensNode) light = DCAST(LightLensNode, light_np.node());
02683   if (light == NULL || !light->_shadow_caster) {
02684     return NULL;
02685   }
02686 
02687   bool is_point = light->is_of_type(PointLight::get_class_type());
02688 
02689   nassertr(light->_sbuffers.count(this) == 0, NULL);
02690 
02691   display_cat.debug() << "Constructing shadow buffer for light '" << light->get_name()
02692     << "', size=" << light->_sb_xsize << "x" << light->_sb_ysize
02693     << ", sort=" << light->_sb_sort << "\n";
02694 
02695   // Setup some flags and properties
02696   FrameBufferProperties fbp;
02697   fbp.set_depth_bits(1); // We only need depth
02698   WindowProperties props = WindowProperties::size(light->_sb_xsize, light->_sb_ysize);
02699   int flags = GraphicsPipe::BF_refuse_window;
02700   if (is_point) {
02701     flags |= GraphicsPipe::BF_size_square;
02702   }
02703 
02704   // Create the buffer
02705   PT(GraphicsOutput) sbuffer = get_engine()->make_output(get_pipe(), light->get_name(),
02706       light->_sb_sort, fbp, props, flags, this, DCAST(GraphicsOutput, host));
02707   nassertr(sbuffer != NULL, NULL);
02708 
02709   // Create a texture and fill it in with some data to workaround an OpenGL error
02710   PT(Texture) tex = new Texture(light->get_name());
02711   if (is_point) {
02712     if (light->_sb_xsize != light->_sb_ysize) {
02713       display_cat.error()
02714         << "PointLight shadow buffers must have an equal width and height!\n";
02715     }
02716     tex->setup_cube_map(light->_sb_xsize, Texture::T_unsigned_byte, Texture::F_depth_component);
02717   } else {
02718     tex->setup_2d_texture(light->_sb_xsize, light->_sb_ysize, Texture::T_unsigned_byte, Texture::F_depth_component);
02719   }
02720   tex->make_ram_image();
02721   sbuffer->add_render_texture(tex, GraphicsOutput::RTM_bind_or_copy, GraphicsOutput::RTP_depth);
02722 
02723   // Set the wrap mode
02724   if (is_point) {
02725     tex->set_wrap_u(Texture::WM_clamp);
02726     tex->set_wrap_v(Texture::WM_clamp);
02727   } else {
02728     tex->set_wrap_u(Texture::WM_border_color);
02729     tex->set_wrap_v(Texture::WM_border_color);
02730     tex->set_border_color(LVecBase4(1, 1, 1, 1));
02731   }
02732 
02733   if (get_supports_shadow_filter()) {
02734     // If we have the ARB_shadow extension, enable shadow filtering.
02735     tex->set_minfilter(Texture::FT_shadow);
02736     tex->set_magfilter(Texture::FT_shadow);
02737   } else {
02738     // We only accept linear - this tells the GPU to use hardware PCF.
02739     tex->set_minfilter(Texture::FT_linear);
02740     tex->set_magfilter(Texture::FT_linear);
02741   }
02742 
02743   // Assign display region(s) to the buffer and camera
02744   if (is_point) {
02745     for (int i = 0; i < 6; ++i) {
02746       PT(DisplayRegion) dr = sbuffer->make_mono_display_region(0, 1, 0, 1);
02747       dr->set_lens_index(i);
02748       dr->set_target_tex_page(i);
02749       dr->set_camera(light_np);
02750       dr->set_clear_depth_active(true);
02751     }
02752   } else {
02753     PT(DisplayRegion) dr = sbuffer->make_mono_display_region(0, 1, 0, 1);
02754     dr->set_camera(light_np);
02755     dr->set_clear_depth_active(true);
02756   }
02757   light->_sbuffers[this] = sbuffer;
02758 
02759   return tex;
02760 }
02761 
02762 ////////////////////////////////////////////////////////////////////
02763 //     Function: GraphicsStateGuardian::get_driver_vendor
02764 //       Access: Public, Virtual
02765 //  Description: Returns the vendor of the video card driver 
02766 ////////////////////////////////////////////////////////////////////
02767 string GraphicsStateGuardian::
02768 get_driver_vendor() {
02769   return string("0");
02770 }
02771 
02772 ////////////////////////////////////////////////////////////////////
02773 //     Function: GraphicsStateGuardian::get_driver_vendor
02774 //       Access: Public, Virtual
02775 //  Description: Returns GL_Renderer
02776 ////////////////////////////////////////////////////////////////////
02777 string GraphicsStateGuardian::get_driver_renderer() {
02778   return string("0");
02779 }
02780 
02781 ////////////////////////////////////////////////////////////////////
02782 //     Function: GraphicsStateGuardian::get_driver_version
02783 //       Access: Public, Virtual
02784 //  Description: Returns driver version
02785 //               This has an implementation-defined meaning, and may
02786 //               be "0" if the particular graphics implementation
02787 //               does not provide a way to query this information.
02788 ////////////////////////////////////////////////////////////////////
02789 string GraphicsStateGuardian::
02790 get_driver_version() {
02791   return string("0");
02792 }
02793 
02794 ////////////////////////////////////////////////////////////////////
02795 //     Function: GraphicsStateGuardian::get_driver_version_major
02796 //       Access: Public, Virtual
02797 //  Description: Returns major version of the video driver.
02798 //               This has an implementation-defined meaning, and may
02799 //               be -1 if the particular graphics implementation
02800 //               does not provide a way to query this information.
02801 ////////////////////////////////////////////////////////////////////
02802 int GraphicsStateGuardian::
02803 get_driver_version_major() {
02804   return -1;
02805 }
02806 
02807 ////////////////////////////////////////////////////////////////////
02808 //     Function: GraphicsStateGuardian::get_driver_version_minor
02809 //       Access: Public, Virtual
02810 //  Description: Returns the minor version of the video driver.
02811 //               This has an implementation-defined meaning, and may
02812 //               be -1 if the particular graphics implementation
02813 //               does not provide a way to query this information.
02814 ////////////////////////////////////////////////////////////////////
02815 int GraphicsStateGuardian::
02816 get_driver_version_minor() {
02817   return -1;
02818 }
02819 
02820 ////////////////////////////////////////////////////////////////////
02821 //     Function: GraphicsStateGuardian::get_driver_shader_version_major
02822 //       Access: Public, Virtual
02823 //  Description: Returns the major version of the shader model.
02824 ////////////////////////////////////////////////////////////////////
02825 int GraphicsStateGuardian::
02826 get_driver_shader_version_major() {
02827   return -1;
02828 }
02829 
02830 ////////////////////////////////////////////////////////////////////
02831 //     Function: GraphicsStateGuardian::get_driver_shader_version_minor
02832 //       Access: Public, Virtual
02833 //  Description: Returns the minor version of the shader model.
02834 ////////////////////////////////////////////////////////////////////
02835 int GraphicsStateGuardian::
02836 get_driver_shader_version_minor() {
02837   return -1;
02838 }