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