00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00130
00131
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
00171
00172
00173 _max_texture_stages = 1;
00174
00175
00176
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
00183
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
00197 _max_lights = -1;
00198 _max_clip_planes = -1;
00199
00200
00201 _max_vertex_transforms = 0;
00202 _max_vertex_transform_indices = 0;
00203
00204 _supports_occlusion_query = false;
00205
00206
00207
00208 _copy_texture_inverted = false;
00209
00210
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
00229
00230
00231 _color_scale_via_lighting = color_scale_via_lighting;
00232
00233
00234
00235 _alpha_scale_via_texture = alpha_scale_via_texture;
00236
00237
00238
00239 _runtime_color_scale = false;
00240
00241 _stencil_render_states = 0;
00242
00243
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
00255
00256
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
00277
00278
00279
00280
00281
00282
00283 GraphicsEngine *GraphicsStateGuardian::
00284 get_engine() const {
00285 nassertr(_engine != (GraphicsEngine *)NULL, GraphicsEngine::get_global_ptr());
00286 return _engine;
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 bool GraphicsStateGuardian::
00303 get_supports_multisample() const {
00304 return _supports_multisample;
00305 }
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 int GraphicsStateGuardian::
00320 get_supported_geom_rendering() const {
00321 return _supported_geom_rendering;
00322 }
00323
00324
00325
00326
00327
00328
00329
00330 bool GraphicsStateGuardian::
00331 get_supports_cg_profile(const string &name) const {
00332 return false;
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 void GraphicsStateGuardian::
00347 set_coordinate_system(CoordinateSystem cs) {
00348 _coordinate_system = cs;
00349
00350
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
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 CoordinateSystem GraphicsStateGuardian::
00382 get_internal_coordinate_system() const {
00383 return _internal_coordinate_system;
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393 PreparedGraphicsObjects *GraphicsStateGuardian::
00394 get_prepared_objects() {
00395 return _prepared_objects;
00396 }
00397
00398
00399
00400
00401
00402
00403 bool GraphicsStateGuardian::
00404 set_gamma(PN_stdfloat gamma) {
00405 _gamma = gamma;
00406
00407 return false;
00408 }
00409
00410
00411
00412
00413
00414
00415 PN_stdfloat GraphicsStateGuardian::
00416 get_gamma(PN_stdfloat gamma) {
00417 return _gamma;
00418 }
00419
00420
00421
00422
00423
00424
00425 void GraphicsStateGuardian::
00426 restore_gamma() {
00427 }
00428
00429 #ifdef HAVE_PYTHON
00430
00431
00432
00433
00434
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
00466
00467
00468
00469
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
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510 void GraphicsStateGuardian::
00511 set_flash_texture(Texture *tex) {
00512 _flash_texture = tex;
00513 }
00514 #endif // NDEBUG
00515
00516 #ifndef NDEBUG
00517
00518
00519
00520
00521
00522
00523 void GraphicsStateGuardian::
00524 clear_flash_texture() {
00525 _flash_texture = NULL;
00526 }
00527 #endif // NDEBUG
00528
00529 #ifndef NDEBUG
00530
00531
00532
00533
00534
00535
00536 Texture *GraphicsStateGuardian::
00537 get_flash_texture() const {
00538 return _flash_texture;
00539 }
00540 #endif // NDEBUG
00541
00542
00543
00544
00545
00546
00547
00548
00549
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
00569
00570
00571
00572 SceneSetup *GraphicsStateGuardian::
00573 get_scene() const {
00574 return _scene_setup;
00575 }
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 TextureContext *GraphicsStateGuardian::
00591 prepare_texture(Texture *) {
00592 return (TextureContext *)NULL;
00593 }
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 bool GraphicsStateGuardian::
00612 update_texture(TextureContext *, bool) {
00613 return true;
00614 }
00615
00616
00617
00618
00619
00620
00621
00622
00623 void GraphicsStateGuardian::
00624 release_texture(TextureContext *) {
00625 }
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 bool GraphicsStateGuardian::
00640 extract_texture_data(Texture *) {
00641 return false;
00642 }
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 GeomContext *GraphicsStateGuardian::
00654 prepare_geom(Geom *) {
00655 return (GeomContext *)NULL;
00656 }
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 void GraphicsStateGuardian::
00669 release_geom(GeomContext *) {
00670 }
00671
00672
00673
00674
00675
00676
00677 ShaderContext *GraphicsStateGuardian::
00678 prepare_shader(Shader *shader) {
00679 return (ShaderContext *)NULL;
00680 }
00681
00682
00683
00684
00685
00686
00687 void GraphicsStateGuardian::
00688 release_shader(ShaderContext *sc) {
00689 }
00690
00691
00692
00693
00694
00695
00696
00697 VertexBufferContext *GraphicsStateGuardian::
00698 prepare_vertex_buffer(GeomVertexArrayData *) {
00699 return (VertexBufferContext *)NULL;
00700 }
00701
00702
00703
00704
00705
00706
00707
00708
00709 void GraphicsStateGuardian::
00710 release_vertex_buffer(VertexBufferContext *) {
00711 }
00712
00713
00714
00715
00716
00717
00718
00719 IndexBufferContext *GraphicsStateGuardian::
00720 prepare_index_buffer(GeomPrimitive *) {
00721 return (IndexBufferContext *)NULL;
00722 }
00723
00724
00725
00726
00727
00728
00729
00730
00731 void GraphicsStateGuardian::
00732 release_index_buffer(IndexBufferContext *) {
00733 }
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744 bool GraphicsStateGuardian::
00745 get_supports_occlusion_query() const {
00746 return _supports_occlusion_query;
00747 }
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765 void GraphicsStateGuardian::
00766 begin_occlusion_query() {
00767 nassertv(_current_occlusion_query == (OcclusionQueryContext *)NULL);
00768 }
00769
00770
00771
00772
00773
00774
00775
00776
00777
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
00789
00790
00791
00792
00793
00794 PT(GeomMunger) GraphicsStateGuardian::
00795 get_geom_munger(const RenderState *state, Thread *current_thread) {
00796
00797
00798
00799 RenderState *nc_state = ((RenderState *)state);
00800
00801
00802
00803
00804
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
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
00822
00823 nc_state->_mungers.erase(mi);
00824 }
00825
00826
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
00838
00839
00840
00841
00842 PT(GeomMunger) GraphicsStateGuardian::
00843 make_geom_munger(const RenderState *state, Thread *current_thread) {
00844
00845
00846
00847
00848 return NULL;
00849 }
00850
00851
00852
00853
00854
00855
00856
00857
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
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
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
00960 spec._value = LMatrix4::ident_mat();
00961 return &spec._value;
00962 }
00963 }
00964
00965
00966
00967
00968
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
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
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
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
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());
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
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
01282 return &LMatrix4::ident_mat();
01283 }
01284 case Shader::SMO_view_to_apiclip_x: {
01285
01286 return &LMatrix4::ident_mat();
01287 }
01288 default:
01289
01290 return &LMatrix4::ident_mat();
01291 }
01292 }
01293
01294
01295
01296
01297
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
01306
01307
01308
01309
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
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
01360
01361
01362
01363
01364
01365
01366
01367 void GraphicsStateGuardian::
01368 clear_before_callback() {
01369 }
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381 void GraphicsStateGuardian::
01382 clear_state_and_transform() {
01383
01384 reissue_transforms();
01385
01386
01387 _state_rs = RenderState::make_empty();
01388 _state_mask.clear();
01389 }
01390
01391
01392
01393
01394
01395
01396
01397
01398
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
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420 bool GraphicsStateGuardian::
01421 prepare_lens() {
01422 return false;
01423 }
01424
01425
01426
01427
01428
01429
01430
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
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458 bool GraphicsStateGuardian::
01459 begin_frame(Thread *current_thread) {
01460 _prepared_objects->begin_frame(this, current_thread);
01461
01462
01463
01464
01465
01466
01467
01468 _state_rs = RenderState::make_empty();
01469 _state_mask.clear();
01470
01471 return !_needs_reset;
01472 }
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490 bool GraphicsStateGuardian::
01491 begin_scene() {
01492 return true;
01493 }
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504 void GraphicsStateGuardian::
01505 end_scene() {
01506
01507
01508
01509
01510 _scene_setup = _scene_null;
01511
01512
01513
01514
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
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
01528 _state_rs = RenderState::make_empty();
01529 _state_mask.clear();
01530 }
01531
01532
01533
01534
01535
01536
01537
01538
01539 void GraphicsStateGuardian::
01540 end_frame(Thread *current_thread) {
01541 _prepared_objects->end_frame(current_thread);
01542
01543
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
01562 _prepared_objects->_graphics_memory_lru.begin_epoch();
01563 }
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573 bool GraphicsStateGuardian::
01574 depth_offset_decals() {
01575 return true;
01576 }
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589 CPT(RenderState) GraphicsStateGuardian::
01590 begin_decal_base_first() {
01591
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
01603
01604
01605
01606
01607
01608
01609
01610
01611 CPT(RenderState) GraphicsStateGuardian::
01612 begin_decal_nested() {
01613
01614
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
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639 CPT(RenderState) GraphicsStateGuardian::
01640 begin_decal_base_second() {
01641
01642
01643
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
01649
01650
01651
01652 RenderState::get_max_priority());
01653 }
01654 return decal_base_second;
01655 }
01656
01657
01658
01659
01660
01661
01662
01663 void GraphicsStateGuardian::
01664 finish_decal() {
01665
01666 }
01667
01668
01669
01670
01671
01672
01673
01674
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
01688
01689
01690
01691 bool GraphicsStateGuardian::
01692 draw_triangles(const GeomPrimitivePipelineReader *, bool) {
01693 return false;
01694 }
01695
01696
01697
01698
01699
01700
01701 bool GraphicsStateGuardian::
01702 draw_tristrips(const GeomPrimitivePipelineReader *, bool) {
01703 return false;
01704 }
01705
01706
01707
01708
01709
01710
01711 bool GraphicsStateGuardian::
01712 draw_trifans(const GeomPrimitivePipelineReader *, bool) {
01713 return false;
01714 }
01715
01716
01717
01718
01719
01720
01721 bool GraphicsStateGuardian::
01722 draw_lines(const GeomPrimitivePipelineReader *, bool) {
01723 return false;
01724 }
01725
01726
01727
01728
01729
01730
01731 bool GraphicsStateGuardian::
01732 draw_linestrips(const GeomPrimitivePipelineReader *, bool) {
01733 return false;
01734 }
01735
01736
01737
01738
01739
01740
01741 bool GraphicsStateGuardian::
01742 draw_points(const GeomPrimitivePipelineReader *, bool) {
01743 return false;
01744 }
01745
01746
01747
01748
01749
01750
01751
01752
01753 void GraphicsStateGuardian::
01754 end_draw_primitives() {
01755 _munger = NULL;
01756 _data_reader = NULL;
01757 }
01758
01759
01760
01761
01762
01763
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
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827 void GraphicsStateGuardian::
01828 set_state_and_transform(const RenderState *state,
01829 const TransformState *trans) {
01830 }
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843 void GraphicsStateGuardian::
01844 clear(DrawableRegion *clearable) {
01845 }
01846
01847
01848
01849
01850
01851
01852
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
01861
01862
01863
01864
01865
01866
01867
01868
01869 const TransformState *GraphicsStateGuardian::
01870 get_cs_transform() const {
01871 return _cs_transform;
01872 }
01873
01874
01875
01876
01877
01878
01879
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
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
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
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
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
01950
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
01958
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
01966
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
01983
01984
01985
01986 void GraphicsStateGuardian::
01987 do_issue_color_scale() {
01988
01989
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
02015
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
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043 void GraphicsStateGuardian::
02044 do_issue_light() {
02045
02046
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
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
02079
02080 cur_ambient_light += light_obj->get_color();
02081
02082 } else {
02083 const LColor &color = light_obj->get_color();
02084
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
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
02107
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
02132
02133
02134
02135
02136
02137
02138
02139 bool GraphicsStateGuardian::
02140 framebuffer_copy_to_texture(Texture *, int, const DisplayRegion *,
02141 const RenderBuffer &) {
02142 return false;
02143 }
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156 bool GraphicsStateGuardian::
02157 framebuffer_copy_to_ram(Texture *, int, const DisplayRegion *,
02158 const RenderBuffer &) {
02159 return false;
02160 }
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170 void GraphicsStateGuardian::
02171 bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
02172 }
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182 void GraphicsStateGuardian::
02183 bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
02184 }
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194 void GraphicsStateGuardian::
02195 bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
02196 }
02197
02198 #ifdef DO_PSTATS
02199
02200
02201
02202
02203
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
02232
02233
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
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
02265
02266
02267
02268
02269
02270
02271 void GraphicsStateGuardian::
02272 reissue_transforms() {
02273 }
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283 void GraphicsStateGuardian::
02284 enable_lighting(bool enable) {
02285 }
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295 void GraphicsStateGuardian::
02296 set_ambient_light(const LColor &color) {
02297 }
02298
02299
02300
02301
02302
02303
02304
02305
02306 void GraphicsStateGuardian::
02307 enable_light(int light_id, bool enable) {
02308 }
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322 void GraphicsStateGuardian::
02323 begin_bind_lights() {
02324 }
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335 void GraphicsStateGuardian::
02336 end_bind_lights() {
02337 }
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347 void GraphicsStateGuardian::
02348 enable_clip_planes(bool enable) {
02349 }
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359 void GraphicsStateGuardian::
02360 enable_clip_plane(int plane_id, bool enable) {
02361 }
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375 void GraphicsStateGuardian::
02376 begin_bind_clip_planes() {
02377 }
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387 void GraphicsStateGuardian::
02388 bind_clip_plane(const NodePath &plane, int plane_id) {
02389 }
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400 void GraphicsStateGuardian::
02401 end_bind_clip_planes() {
02402 }
02403
02404
02405
02406
02407
02408
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
02436
02437
02438
02439
02440 void GraphicsStateGuardian::
02441 free_pointers() {
02442 }
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452 void GraphicsStateGuardian::
02453 close_gsg() {
02454
02455
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
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
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
02487
02488
02489
02490
02491
02492
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
02506
02507
02508
02509
02510
02511
02512 void GraphicsStateGuardian::
02513 determine_light_color_scale() {
02514 if (_has_scene_graph_color) {
02515
02516
02517
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
02530
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
02541
02542
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
02555
02556
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
02569
02570
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
02583
02584
02585
02586
02587
02588
02589
02590
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
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
02612
02613 task->set_priority(max(task->get_priority(), priority));
02614 return;
02615 }
02616 }
02617
02618
02619
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
02630
02631
02632
02633
02634
02635
02636
02637 PT(Texture) GraphicsStateGuardian::
02638 make_shadow_buffer(const NodePath &light_np, GraphicsOutputBase *host) {
02639
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
02658 FrameBufferProperties fbp;
02659 fbp.set_depth_bits(1);
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
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
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
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
02697 tex->set_minfilter(Texture::FT_shadow);
02698 tex->set_magfilter(Texture::FT_shadow);
02699 } else {
02700
02701 tex->set_minfilter(Texture::FT_linear);
02702 tex->set_magfilter(Texture::FT_linear);
02703 }
02704
02705
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
02726
02727
02728
02729 string GraphicsStateGuardian::
02730 get_driver_vendor() {
02731 return string("0");
02732 }
02733
02734
02735
02736
02737
02738
02739 string GraphicsStateGuardian::get_driver_renderer() {
02740 return string("0");
02741 }
02742
02743
02744
02745
02746
02747
02748 string GraphicsStateGuardian::
02749 get_driver_version() {
02750 return string("0");
02751 }
02752
02753
02754
02755
02756
02757
02758 int GraphicsStateGuardian::
02759 get_driver_version_major() {
02760 return -1;
02761 }
02762
02763
02764
02765
02766
02767
02768 int GraphicsStateGuardian::
02769 get_driver_version_minor() {
02770 return -1;
02771 }
02772
02773
02774
02775
02776
02777
02778 int GraphicsStateGuardian::
02779 get_driver_shader_version_major() {
02780 return -1;
02781 }
02782
02783
02784
02785
02786
02787
02788 int GraphicsStateGuardian::
02789 get_driver_shader_version_minor() {
02790 return -1;
02791 }