67PStatCollector GraphicsStateGuardian::_vertex_buffer_switch_pcollector(
"Buffer switch:Vertex");
68PStatCollector GraphicsStateGuardian::_index_buffer_switch_pcollector(
"Buffer switch:Index");
69PStatCollector GraphicsStateGuardian::_shader_buffer_switch_pcollector(
"Buffer switch:Shader");
70PStatCollector GraphicsStateGuardian::_load_vertex_buffer_pcollector(
"Draw:Transfer data:Vertex buffer");
71PStatCollector GraphicsStateGuardian::_load_index_buffer_pcollector(
"Draw:Transfer data:Index buffer");
72PStatCollector GraphicsStateGuardian::_load_shader_buffer_pcollector(
"Draw:Transfer data:Shader buffer");
73PStatCollector GraphicsStateGuardian::_create_vertex_buffer_pcollector(
"Draw:Transfer data:Create Vertex buffer");
74PStatCollector GraphicsStateGuardian::_create_index_buffer_pcollector(
"Draw:Transfer data:Create Index buffer");
75PStatCollector GraphicsStateGuardian::_create_shader_buffer_pcollector(
"Draw:Transfer data:Create Shader buffer");
76PStatCollector GraphicsStateGuardian::_load_texture_pcollector(
"Draw:Transfer data:Texture");
77PStatCollector GraphicsStateGuardian::_data_transferred_pcollector(
"Data transferred");
78PStatCollector GraphicsStateGuardian::_texmgrmem_total_pcollector(
"Texture manager");
79PStatCollector GraphicsStateGuardian::_texmgrmem_resident_pcollector(
"Texture manager:Resident");
80PStatCollector GraphicsStateGuardian::_primitive_batches_pcollector(
"Primitive batches");
81PStatCollector GraphicsStateGuardian::_primitive_batches_tristrip_pcollector(
"Primitive batches:Triangle strips");
82PStatCollector GraphicsStateGuardian::_primitive_batches_trifan_pcollector(
"Primitive batches:Triangle fans");
83PStatCollector GraphicsStateGuardian::_primitive_batches_tri_pcollector(
"Primitive batches:Triangles");
84PStatCollector GraphicsStateGuardian::_primitive_batches_patch_pcollector(
"Primitive batches:Patches");
85PStatCollector GraphicsStateGuardian::_primitive_batches_other_pcollector(
"Primitive batches:Other");
86PStatCollector GraphicsStateGuardian::_vertices_tristrip_pcollector(
"Vertices:Triangle strips");
87PStatCollector GraphicsStateGuardian::_vertices_trifan_pcollector(
"Vertices:Triangle fans");
88PStatCollector GraphicsStateGuardian::_vertices_tri_pcollector(
"Vertices:Triangles");
89PStatCollector GraphicsStateGuardian::_vertices_patch_pcollector(
"Vertices:Patches");
90PStatCollector GraphicsStateGuardian::_vertices_other_pcollector(
"Vertices:Other");
91PStatCollector GraphicsStateGuardian::_state_pcollector(
"State changes");
92PStatCollector GraphicsStateGuardian::_transform_state_pcollector(
"State changes:Transforms");
93PStatCollector GraphicsStateGuardian::_texture_state_pcollector(
"State changes:Textures");
94PStatCollector GraphicsStateGuardian::_draw_primitive_pcollector(
"Draw:Primitive:Draw");
95PStatCollector GraphicsStateGuardian::_draw_set_state_pcollector(
"Draw:Set State");
96PStatCollector GraphicsStateGuardian::_flush_pcollector(
"Draw:Flush");
97PStatCollector GraphicsStateGuardian::_compute_dispatch_pcollector(
"Draw:Compute dispatch");
99PStatCollector GraphicsStateGuardian::_wait_occlusion_pcollector(
"Wait:Occlusion");
100PStatCollector GraphicsStateGuardian::_wait_timer_pcollector(
"Wait:Timer Queries");
101PStatCollector GraphicsStateGuardian::_timer_queries_pcollector(
"Timer queries");
102PStatCollector GraphicsStateGuardian::_command_latency_pcollector(
"Command latency");
104PStatCollector GraphicsStateGuardian::_prepare_pcollector(
"Draw:Prepare");
105PStatCollector GraphicsStateGuardian::_prepare_texture_pcollector(
"Draw:Prepare:Texture");
106PStatCollector GraphicsStateGuardian::_prepare_sampler_pcollector(
"Draw:Prepare:Sampler");
107PStatCollector GraphicsStateGuardian::_prepare_geom_pcollector(
"Draw:Prepare:Geom");
108PStatCollector GraphicsStateGuardian::_prepare_shader_pcollector(
"Draw:Prepare:Shader");
109PStatCollector GraphicsStateGuardian::_prepare_vertex_buffer_pcollector(
"Draw:Prepare:Vertex buffer");
110PStatCollector GraphicsStateGuardian::_prepare_index_buffer_pcollector(
"Draw:Prepare:Index buffer");
111PStatCollector GraphicsStateGuardian::_prepare_shader_buffer_pcollector(
"Draw:Prepare:Shader buffer");
113PStatCollector GraphicsStateGuardian::_draw_set_state_transform_pcollector(
"Draw:Set State:Transform");
114PStatCollector GraphicsStateGuardian::_draw_set_state_alpha_test_pcollector(
"Draw:Set State:Alpha test");
115PStatCollector GraphicsStateGuardian::_draw_set_state_antialias_pcollector(
"Draw:Set State:Antialias");
116PStatCollector GraphicsStateGuardian::_draw_set_state_clip_plane_pcollector(
"Draw:Set State:Clip plane");
117PStatCollector GraphicsStateGuardian::_draw_set_state_color_pcollector(
"Draw:Set State:Color");
118PStatCollector GraphicsStateGuardian::_draw_set_state_cull_face_pcollector(
"Draw:Set State:Cull face");
119PStatCollector GraphicsStateGuardian::_draw_set_state_depth_offset_pcollector(
"Draw:Set State:Depth offset");
120PStatCollector GraphicsStateGuardian::_draw_set_state_depth_test_pcollector(
"Draw:Set State:Depth test");
121PStatCollector GraphicsStateGuardian::_draw_set_state_depth_write_pcollector(
"Draw:Set State:Depth write");
122PStatCollector GraphicsStateGuardian::_draw_set_state_render_mode_pcollector(
"Draw:Set State:Render mode");
123PStatCollector GraphicsStateGuardian::_draw_set_state_rescale_normal_pcollector(
"Draw:Set State:Rescale normal");
124PStatCollector GraphicsStateGuardian::_draw_set_state_shade_model_pcollector(
"Draw:Set State:Shade model");
125PStatCollector GraphicsStateGuardian::_draw_set_state_blending_pcollector(
"Draw:Set State:Blending");
126PStatCollector GraphicsStateGuardian::_draw_set_state_shader_pcollector(
"Draw:Set State:Shader");
127PStatCollector GraphicsStateGuardian::_draw_set_state_shader_parameters_pcollector(
"Draw:Set State:Shader Parameters");
128PStatCollector GraphicsStateGuardian::_draw_set_state_texture_pcollector(
"Draw:Set State:Texture");
129PStatCollector GraphicsStateGuardian::_draw_set_state_tex_matrix_pcollector(
"Draw:Set State:Tex matrix");
130PStatCollector GraphicsStateGuardian::_draw_set_state_tex_gen_pcollector(
"Draw:Set State:Tex gen");
131PStatCollector GraphicsStateGuardian::_draw_set_state_material_pcollector(
"Draw:Set State:Material");
132PStatCollector GraphicsStateGuardian::_draw_set_state_light_pcollector(
"Draw:Set State:Light");
133PStatCollector GraphicsStateGuardian::_draw_set_state_stencil_pcollector(
"Draw:Set State:Stencil");
134PStatCollector GraphicsStateGuardian::_draw_set_state_fog_pcollector(
"Draw:Set State:Fog");
135PStatCollector GraphicsStateGuardian::_draw_set_state_scissor_pcollector(
"Draw:Set State:Scissor");
137PT(
TextureStage) GraphicsStateGuardian::_alpha_scale_texture_stage =
nullptr;
139TypeHandle GraphicsStateGuardian::_type_handle;
145GraphicsStateGuardian::
146GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
148 _internal_coordinate_system(internal_coordinate_system),
152 _coordinate_system = CS_invalid;
153 _internal_transform = TransformState::make_identity();
155 if (_internal_coordinate_system == CS_default) {
156 _internal_coordinate_system = get_default_coordinate_system();
159 set_coordinate_system(get_default_coordinate_system());
161 _data_reader =
nullptr;
162 _current_display_region =
nullptr;
163 _current_stereo_channel = Lens::SC_mono;
164 _current_tex_view_offset = 0;
165 _current_lens =
nullptr;
166 _projection_mat = TransformState::make_identity();
167 _projection_mat_inv = TransformState::make_identity();
171 _current_properties =
nullptr;
172 _closing_gsg =
false;
175 _stereo_buffer_mask = ~0;
176 _incomplete_render = allow_incomplete_render;
177 _effective_incomplete_render =
false;
180 _is_hardware =
false;
181 _prefers_triangle_strips =
false;
182 _max_vertices_per_array = INT_MAX;
183 _max_vertices_per_primitive = INT_MAX;
187 _max_texture_stages = 1;
191 _max_texture_dimension = -1;
192 _max_3d_texture_dimension = 0;
193 _max_2d_texture_array_layers = 0;
194 _max_cube_map_dimension = 0;
195 _max_buffer_texture_size = 0;
198 _supports_texture_combine =
false;
199 _supports_texture_saved_result =
false;
200 _supports_texture_dot3 =
false;
202 _supports_3d_texture =
false;
203 _supports_2d_texture_array =
false;
204 _supports_cube_map =
false;
205 _supports_buffer_texture =
false;
206 _supports_cube_map_array =
false;
207 _supports_tex_non_pow2 =
false;
208 _supports_texture_srgb =
false;
209 _supports_compressed_texture =
false;
210 _compressed_texture_formats.clear();
211 _compressed_texture_formats.set_bit(Texture::CM_off);
215 _max_clip_planes = -1;
218 _max_vertex_transforms = 0;
219 _max_vertex_transform_indices = 0;
221 _supports_occlusion_query =
false;
222 _supports_timer_query =
false;
225 _timer_queries_active =
false;
226 _last_query_frame = 0;
227 _last_num_queried = 0;
230 _pstats_gpu_thread = -1;
235 _copy_texture_inverted =
false;
238 _supports_multisample =
false;
239 _supports_generate_mipmap =
false;
240 _supports_depth_texture =
false;
241 _supports_depth_stencil =
false;
242 _supports_shadow_filter =
false;
243 _supports_sampler_objects =
false;
244 _supports_basic_shaders =
false;
245 _supports_geometry_shaders =
false;
246 _supports_tessellation_shaders =
false;
247 _supports_compute_shaders =
false;
248 _supports_glsl =
false;
249 _supports_hlsl =
false;
251 _supports_stencil =
false;
252 _supports_stencil_wrap =
false;
253 _supports_two_sided_stencil =
false;
254 _supports_geometry_instancing =
false;
255 _supports_indirect_draw =
false;
258 _supports_luminance_texture =
true;
261 _max_color_targets = 1;
262 _supports_dual_source_blending =
false;
264 _supported_geom_rendering = 0;
269 _color_scale_via_lighting = color_scale_via_lighting;
272 _alpha_scale_via_texture = alpha_scale_via_texture;
276 _runtime_color_scale =
false;
279 _auto_detect_shader_model = SM_00;
280 _shader_model = SM_00;
283 _texture_quality_override = Texture::QL_default;
287 static size_t next_index = 0;
294GraphicsStateGuardian::
295~GraphicsStateGuardian() {
306 for (
size_t si = 0; si < size; ++si) {
308 state->_mungers.
remove(_id);
309 state->_munged_states.
remove(_id);
320 nassertr(_engine !=
nullptr, GraphicsEngine::get_global_ptr());
335 return _supports_multisample;
349 return _supported_geom_rendering;
372 if (cs == CS_default) {
373 cs = get_default_coordinate_system();
375 if (_coordinate_system == cs) {
378 _coordinate_system = cs;
381 if (_internal_coordinate_system == CS_default ||
382 _internal_coordinate_system == _coordinate_system) {
383 _cs_transform = TransformState::make_identity();
384 _inv_cs_transform = TransformState::make_identity();
388 TransformState::make_mat
389 (LMatrix4::convert_mat(_coordinate_system,
390 _internal_coordinate_system));
392 TransformState::make_mat
393 (LMatrix4::convert_mat(_internal_coordinate_system,
394 _coordinate_system));
409 return _internal_coordinate_system;
418 return _prepared_objects;
452 void *callback_arg) {
454 PreparedGraphicsObjects::Textures::const_iterator ti;
455 for (ti = _prepared_objects->_prepared_textures.begin();
456 ti != _prepared_objects->_prepared_textures.end();
458 bool result = (*func)(*ti, callback_arg);
485 _flash_texture = tex;
496 _flash_texture =
nullptr;
507 return _flash_texture;
521 _scene_setup = scene_setup;
522 _current_lens = scene_setup->
get_lens();
523 if (_current_lens ==
nullptr) {
529 _projection_mat = calc_projection_mat(_current_lens);
530 if (_projection_mat ==
nullptr) {
533 _projection_mat_inv = _projection_mat->get_inverse();
717 nassertv(_current_occlusion_query ==
nullptr);
727end_occlusion_query() {
728 nassertr(_current_occlusion_query !=
nullptr,
nullptr);
730 _current_occlusion_query =
nullptr;
739issue_timer_query(
int pstats_index) {
749 nassert_raise(
"Compute shaders not supported by GSG");
765 int mi = state->_last_mi;
768 if (munger->is_registered()) {
774 mi = mungers.
find(_id);
777 if (munger->is_registered()) {
778 state->_last_mi = mi;
788 PT(
GeomMunger) munger = make_geom_munger(state, current_thread);
789 nassertr(munger !=
nullptr && munger->is_registered(), munger);
790 nassertr(munger->is_of_type(StateMunger::get_class_type()), munger);
792 state->_last_mi = mungers.
store(_id, munger);
815 switch (_internal_coordinate_system) {
830 <<
"Invalid coordinate system in compute_distance_to: "
831 << (int)_internal_coordinate_system <<
"\n";
865 if (altered & spec._dep[0]) {
866 const LMatrix4 *t =
fetch_specified_part(spec._part[0], spec._arg[0], spec._cache[0], spec._index);
867 if (t != &spec._cache[0]) {
871 if (altered & spec._dep[1]) {
872 const LMatrix4 *t =
fetch_specified_part(spec._part[1], spec._arg[1], spec._cache[1], spec._index);
873 if (t != &spec._cache[1]) {
879 case Shader::SMF_compose:
880 spec._value.multiply(spec._cache[0], spec._cache[1]);
882 case Shader::SMF_transform_dlight:
883 spec._value = spec._cache[0];
884 v = spec._cache[1].xform_vec(spec._cache[0].get_row3(2));
886 spec._value.set_row(2, v);
887 v = spec._cache[1].xform_vec(spec._cache[0].get_row3(3));
889 spec._value.set_row(3, v);
891 case Shader::SMF_transform_plight:
894 spec._value = spec._cache[0];
895 LPoint3 point = spec._cache[1].xform_point(spec._cache[0].get_row3(2));
896 spec._value(2, 0) = point[0];
897 spec._value(2, 1) = point[1];
898 spec._value(2, 2) = point[2];
901 case Shader::SMF_transform_slight:
902 spec._value = spec._cache[0];
903 spec._value.set_row(2, spec._cache[1].xform_point(spec._cache[0].get_row3(2)));
904 v = spec._cache[1].xform_vec(spec._cache[0].get_row3(3));
906 spec._value.set_row(3, v);
908 case Shader::SMF_first:
909 return &spec._cache[0];
912 spec._value = LMatrix4::ident_mat();
922 LMatrix4 &t,
int index) {
924 case Shader::SMO_identity: {
925 return &LMatrix4::ident_mat();
927 case Shader::SMO_window_size:
928 case Shader::SMO_pixel_size: {
929 LVecBase2i pixel_size = _current_display_region->get_pixel_size();
930 t = LMatrix4::translate_mat(pixel_size[0], pixel_size[1], 0);
933 case Shader::SMO_frame_time: {
935 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time);
938 case Shader::SMO_frame_delta: {
940 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt);
943 case Shader::SMO_texpad_x: {
944 Texture *tex = _target_shader->get_shader_input_texture(name);
945 nassertr(tex !=
nullptr, &LMatrix4::zeros_mat());
952 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cx, cy, cz, 0);
955 case Shader::SMO_texpix_x: {
956 Texture *tex = _target_shader->get_shader_input_texture(name);
957 nassertr(tex !=
nullptr, &LMatrix4::zeros_mat());
961 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, px, py, pz, 0);
964 case Shader::SMO_attr_material: {
966 _target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
968 if (target_material->
is_off()) {
969 t.set(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0);
978 t.set(amb[0], amb[1], amb[2], amb[3],
979 dif[0], dif[1], dif[2], dif[3],
980 emm[0], emm[1], emm[2], emm[3],
981 spc[0], spc[1], spc[2], spc[3]);
984 case Shader::SMO_attr_material2: {
986 _target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
987 if (target_material->
is_off()) {
988 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
996 case Shader::SMO_attr_color: {
998 _target_rs->get_attrib_def(ColorAttrib::get_class_slot());
1000 return &LMatrix4::ones_mat();
1002 LVecBase4 c = target_color->
get_color();
1003 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
1006 case Shader::SMO_attr_colorscale: {
1008 _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot());
1010 return &LMatrix4::ones_mat();
1012 LVecBase4 cs = target_color->
get_scale();
1013 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cs[0], cs[1], cs[2], cs[3]);
1016 case Shader::SMO_attr_fog: {
1018 _target_rs->get_attrib_def(FogAttrib::get_class_slot());
1020 if (fog ==
nullptr) {
1021 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1);
1024 PN_stdfloat start, end;
1026 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1030 case Shader::SMO_attr_fogcolor: {
1032 _target_rs->get_attrib_def(FogAttrib::get_class_slot());
1034 if (fog ==
nullptr) {
1035 return &LMatrix4::ones_mat();
1038 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
1041 case Shader::SMO_alight_x: {
1042 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1043 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1045 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1047 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
1050 case Shader::SMO_satten_x: {
1051 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1052 nassertr(!np.
is_empty(), &LMatrix4::ones_mat());
1054 DCAST_INTO_R(lt, np.
node(), &LMatrix4::ones_mat());
1057 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a[0], a[1], a[2], x);
1060 case Shader::SMO_dlight_x: {
1062 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1063 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1065 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1068 t = np.get_net_transform()->
get_mat() *
1069 _scene_setup->get_world_transform()->get_mat();
1072 LVecBase3 h = d + LVecBase3(0,-1,0);
1074 t.set(c[0], c[1], c[2], c[3],
1075 s[0], s[1], s[2], c[3],
1076 d[0], d[1], d[2], 0,
1077 h[0], h[1], h[2], 0);
1080 case Shader::SMO_plight_x: {
1082 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1083 nassertr(!np.
is_empty(), &LMatrix4::ones_mat());
1085 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1088 t = np.get_net_transform()->
get_mat() *
1089 _scene_setup->get_world_transform()->get_mat();
1090 LVecBase3 p = (t.xform_point(lt->
get_point()));
1093 PN_stdfloat lnear = lens->
get_near();
1094 PN_stdfloat lfar = lens->
get_far();
1095 t.set(c[0], c[1], c[2], c[3],
1096 s[0], s[1], s[2], s[3],
1097 p[0], p[1], p[2], lnear,
1098 a[0], a[1], a[2], lfar);
1101 case Shader::SMO_slight_x: {
1103 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1104 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1106 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1108 nassertr(lens !=
nullptr, &LMatrix4::zeros_mat());
1111 PN_stdfloat cutoff = ccos(deg_2_rad(lens->
get_hfov() * 0.5f));
1112 t = np.get_net_transform()->
get_mat() *
1113 _scene_setup->get_world_transform()->get_mat();
1116 t.set(c[0], c[1], c[2], c[3],
1117 s[0], s[1], s[2], s[3],
1118 p[0], p[1], p[2], 0,
1119 d[0], d[1], d[2], cutoff);
1122 case Shader::SMO_light_ambient: {
1123 LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
1125 _target_rs->get_attrib_def(LightAttrib::get_class_slot());
1130 t.set_row(3, LVecBase4(1, 1, 1, 1));
1132 t.set_row(3, target_light->get_ambient_contribution());
1136 case Shader::SMO_texmat_i: {
1139 if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
1143 return &LMatrix4::ident_mat();
1146 case Shader::SMO_inv_texmat_i: {
1149 if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
1150 index < ta->get_num_on_stages()) {
1151 t = tma->get_transform(ta->
get_on_stage(index))->get_inverse()->get_mat();
1154 return &LMatrix4::ident_mat();
1157 case Shader::SMO_texscale_i: {
1160 if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
1161 index < ta->get_num_on_stages()) {
1162 LVecBase3 scale = tma->get_transform(ta->
get_on_stage(index))->get_scale();
1163 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, scale[0], scale[1], scale[2], 0);
1166 return &LMatrix4::ident_mat();
1169 case Shader::SMO_texcolor_i: {
1171 if (_target_rs->get_attrib(ta) && index < ta->get_num_on_stages()) {
1176 return &LMatrix4::zeros_mat();
1179 case Shader::SMO_texconst_i: {
1182 if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tga) &&
1183 index < ta->get_num_on_stages()) {
1184 LVecBase3 value = tga->get_constant_value(ta->
get_on_stage(index));
1185 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, value[0], value[1], value[2], 1);
1188 return &LMatrix4::ident_mat();
1191 case Shader::SMO_tex_is_alpha_i: {
1195 if (_target_rs->get_attrib(ta) &&
1196 index < ta->get_num_on_stages()) {
1198 PN_stdfloat v = (ta->
get_on_texture(ts)->get_format() == Texture::F_alpha);
1199 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v, v, v, 0);
1202 return &LMatrix4::zeros_mat();
1205 case Shader::SMO_plane_x: {
1206 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1207 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1209 DCAST_INTO_R(plane_node, np.
node(), &LMatrix4::zeros_mat());
1211 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, p[0], p[1], p[2], p[3]);
1214 case Shader::SMO_clipplane_x: {
1216 _target_rs->get_attrib_def(cpa);
1217 int planenr = atoi(name->
get_name().c_str());
1219 return &LMatrix4::zeros_mat();
1222 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1224 DCAST_INTO_R(plane_node, np.
node(), &LMatrix4::zeros_mat());
1229 if (!transform->is_identity()) {
1230 plane.xform(transform->get_mat());
1232 t.set_row(3, plane);
1235 case Shader::SMO_apiview_clipplane_i: {
1237 _target_rs->get_attrib_def(cpa);
1239 return &LMatrix4::zeros_mat();
1243 nassertr(!plane.
is_empty(), &LMatrix4::zeros_mat());
1245 DCAST_INTO_R(plane_node, plane.
node(), &LMatrix4::zeros_mat());
1248 _scene_setup->get_cs_world_transform()->compose(
1249 plane.
get_transform(_scene_setup->get_scene_root().get_parent()));
1251 LPlane xformed_plane = plane_node->
get_plane() * transform->get_mat();
1252 t.set_row(3, xformed_plane);
1255 case Shader::SMO_mat_constant_x: {
1256 return &_target_shader->get_shader_input_matrix(name, t);
1258 case Shader::SMO_vec_constant_x: {
1259 const LVecBase4 &input = _target_shader->get_shader_input_vector(name);
1260 const PN_stdfloat *data = input.get_data();
1261 t.set(data[0], data[1], data[2], data[3],
1262 data[0], data[1], data[2], data[3],
1263 data[0], data[1], data[2], data[3],
1264 data[0], data[1], data[2], data[3]);
1267 case Shader::SMO_world_to_view: {
1268 return &(_scene_setup->get_world_transform()->get_mat());
1270 case Shader::SMO_view_to_world: {
1271 return &(_scene_setup->get_camera_transform()->get_mat());
1273 case Shader::SMO_model_to_view: {
1274 t = _inv_cs_transform->compose(_internal_transform)->get_mat();
1277 case Shader::SMO_model_to_apiview: {
1278 return &(_internal_transform->get_mat());
1280 case Shader::SMO_view_to_model: {
1281 t = _internal_transform->invert_compose(_cs_transform)->get_mat();
1284 case Shader::SMO_apiview_to_model: {
1285 t = _internal_transform->get_inverse()->get_mat();
1288 case Shader::SMO_apiview_to_view: {
1289 return &(_inv_cs_transform->get_mat());
1291 case Shader::SMO_view_to_apiview: {
1292 return &(_cs_transform->get_mat());
1294 case Shader::SMO_clip_to_view: {
1295 if (_current_lens->get_coordinate_system() == _coordinate_system) {
1296 return &(_current_lens->get_projection_mat_inv(_current_stereo_channel));
1298 t = _current_lens->get_projection_mat_inv(_current_stereo_channel) *
1299 LMatrix4::convert_mat(_current_lens->get_coordinate_system(), _coordinate_system);
1303 case Shader::SMO_view_to_clip: {
1304 if (_current_lens->get_coordinate_system() == _coordinate_system) {
1305 return &(_current_lens->get_projection_mat(_current_stereo_channel));
1307 t = LMatrix4::convert_mat(_coordinate_system, _current_lens->get_coordinate_system()) *
1308 _current_lens->get_projection_mat(_current_stereo_channel);
1312 case Shader::SMO_apiclip_to_view: {
1313 t = _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat();
1316 case Shader::SMO_view_to_apiclip: {
1317 t = _cs_transform->get_mat() * _projection_mat->get_mat();
1320 case Shader::SMO_apiclip_to_apiview: {
1321 return &(_projection_mat_inv->get_mat());
1323 case Shader::SMO_apiview_to_apiclip: {
1324 return &(_projection_mat->get_mat());
1326 case Shader::SMO_view_x_to_view: {
1327 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1328 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1329 t = np.get_net_transform()->
get_mat() *
1330 _scene_setup->get_world_transform()->get_mat();
1333 case Shader::SMO_view_to_view_x: {
1334 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1335 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1336 t = _scene_setup->get_camera_transform()->get_mat() *
1337 np.get_net_transform()->get_inverse()->
get_mat();
1340 case Shader::SMO_apiview_x_to_view: {
1341 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1342 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1343 t = LMatrix4::convert_mat(_internal_coordinate_system, _coordinate_system) *
1344 np.get_net_transform()->
get_mat() *
1345 _scene_setup->get_world_transform()->get_mat();
1348 case Shader::SMO_view_to_apiview_x: {
1349 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1350 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1351 t = (_scene_setup->get_camera_transform()->get_mat() *
1352 np.get_net_transform()->get_inverse()->
get_mat() *
1353 LMatrix4::convert_mat(_coordinate_system, _internal_coordinate_system));
1356 case Shader::SMO_clip_x_to_view: {
1357 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1358 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1360 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1364 np.get_net_transform()->
get_mat() *
1365 _scene_setup->get_world_transform()->get_mat();
1368 case Shader::SMO_view_to_clip_x: {
1369 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1370 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1372 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1374 t = _scene_setup->get_camera_transform()->get_mat() *
1375 np.get_net_transform()->get_inverse()->
get_mat() *
1380 case Shader::SMO_apiclip_x_to_view: {
1381 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1382 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1384 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1386 t = calc_projection_mat(lens)->get_inverse()->get_mat() *
1388 np.get_net_transform()->
get_mat() *
1389 _scene_setup->get_world_transform()->get_mat();
1392 case Shader::SMO_view_to_apiclip_x: {
1393 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1394 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1396 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1398 t = _scene_setup->get_camera_transform()->get_mat() *
1399 np.get_net_transform()->get_inverse()->
get_mat() *
1401 calc_projection_mat(lens)->get_mat();
1404 case Shader::SMO_mat_constant_x_attrib: {
1405 if (_target_shader->has_shader_input(name)) {
1408 return &_target_shader->get_shader_input_matrix(name, t);
1412 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1416 case Shader::SMO_vec_constant_x_attrib: {
1417 if (_target_shader->has_shader_input(name)) {
1420 const LVecBase4 &data = _target_shader->get_shader_input_vector(name);
1421 t.set(data[0], data[1], data[2], data[3],
1422 data[0], data[1], data[2], data[3],
1423 data[0], data[1], data[2], data[3],
1424 data[0], data[1], data[2], data[3]);
1429 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1433 case Shader::SMO_light_source_i_attrib: {
1435 _target_rs->get_attrib_def(target_light);
1440 if (index >= 0 && (
size_t)index < num_lights) {
1442 nassertr(!light.
is_empty(), &LMatrix4::ident_mat());
1444 nassertr(light_obj !=
nullptr, &LMatrix4::ident_mat());
1448 }
else if (index == 0) {
1452 return &LMatrix4::ones_mat();
1456 case Shader::SMO_light_source_i_packed: {
1459 _target_rs->get_attrib_def(target_light);
1464 if (index >= 0 && (
size_t)index < num_lights) {
1466 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1469 nassertr(light !=
nullptr, &LMatrix4::zeros_mat());
1473 LMatrix4 mat = np.get_net_transform()->
get_mat() *
1474 _scene_setup->get_world_transform()->get_mat();
1476 if (node->
is_of_type(DirectionalLight::get_class_type())) {
1477 LVecBase3 d = mat.xform_vec(((
const DirectionalLight *)node)->get_direction());
1479 t.set_row(2, LVecBase4(d, 0));
1480 t.set_row(3, LVecBase4(-d, 0));
1482 }
else if (node->
is_of_type(LightLensNode::get_class_type())) {
1486 t.set_row(3, LVecBase4(p));
1490 if (node->
is_of_type(Spotlight::get_class_type())) {
1491 PN_stdfloat cutoff = ccos(deg_2_rad(lens->
get_hfov() * 0.5f));
1493 t.set_cell(1, 3, ((
const Spotlight *)node)->get_exponent());
1494 t.set_row(2, LVecBase4(d, cutoff));
1496 }
else if (node->
is_of_type(PointLight::get_class_type())) {
1497 t.set_cell(1, 3, lens->
get_far());
1498 t.set_cell(3, 3, lens->
get_near());
1500 if (node->
is_of_type(SphereLight::get_class_type())) {
1501 t.set_cell(2, 3, ((
const SphereLight *)node)->get_radius());
1505 }
else if (index == 0) {
1508 t.set_row(0, LVecBase4(1, 1, 1, 1));
1512 case Shader::SMO_attr_pointparams: {
1514 _target_rs->get_attrib_def(target_render_mode);
1516 PN_stdfloat thickness = target_render_mode->
get_thickness();
1517 PN_stdfloat catten = thickness;
1518 PN_stdfloat patten = 0.0f;
1520 LVecBase2i pixel_size = _current_display_region->get_pixel_size();
1522 LVector3 height(0.0f, thickness, 1.0f);
1523 height = height * _projection_mat->get_mat();
1524 height = height * _internal_transform->get_scale()[1];
1525 PN_stdfloat s = height[1] * pixel_size[1];
1527 if (_current_lens->is_orthographic()) {
1536 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, thickness, catten, patten, 0.0f);
1540 nassertr(
false , &LMatrix4::ident_mat());
1541 return &LMatrix4::ident_mat();
1563 static const CPT_InternalName IN_constantAttenuation(
"constantAttenuation");
1565 static const CPT_InternalName IN_quadraticAttenuation(
"quadraticAttenuation");
1573 if (attrib == IN_color) {
1574 if (node ==
nullptr) {
1575 return &LMatrix4::ident_mat();
1578 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1583 }
else if (attrib == IN_ambient) {
1584 if (node ==
nullptr) {
1585 return &LMatrix4::ident_mat();
1588 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1594 t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
1598 }
else if (attrib == IN_diffuse) {
1599 if (node ==
nullptr) {
1600 return &LMatrix4::ident_mat();
1603 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1606 t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
1613 }
else if (attrib == IN_specular) {
1614 if (node ==
nullptr) {
1615 return &LMatrix4::ident_mat();
1618 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1622 }
else if (attrib == IN_position) {
1624 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
1628 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1630 }
else if (node->
is_of_type(DirectionalLight::get_class_type())) {
1632 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1635 LVector3 dir = -(light->
get_direction() * transform->get_mat());
1636 dir *= _scene_setup->get_cs_world_transform()->
get_mat();
1637 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 0);
1641 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1643 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1646 _scene_setup->get_cs_world_transform()->compose(
1647 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1649 const LMatrix4 &light_mat = transform->get_mat();
1651 t = LMatrix4::translate_mat(pos);
1655 }
else if (attrib == IN_halfVector) {
1657 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
1661 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1663 }
else if (node->
is_of_type(DirectionalLight::get_class_type())) {
1665 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1668 LVector3 dir = -(light->
get_direction() * transform->get_mat());
1669 dir *= _scene_setup->get_cs_world_transform()->
get_mat();
1671 dir += LVector3(0, 0, 1);
1673 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 1);
1677 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1679 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1682 _scene_setup->get_cs_world_transform()->compose(
1683 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1685 const LMatrix4 &light_mat = transform->get_mat();
1688 pos += LVector3(0, 0, 1);
1690 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pos[0],pos[1],pos[2], 1);
1694 }
else if (attrib == IN_spotDirection) {
1695 if (node ==
nullptr) {
1696 t.set_row(3, LVector3(0.0f, 0.0f, -1.0f));
1700 t.set_row(3, LVector3(0.0f, 0.0f, 0.0f));
1704 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1706 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1709 _scene_setup->get_cs_world_transform()->compose(
1710 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1712 const LMatrix4 &light_mat = transform->get_mat();
1718 }
else if (attrib == IN_spotCutoff) {
1719 if (node !=
nullptr &&
1720 node->
is_of_type(Spotlight::get_class_type())) {
1722 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1724 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1726 float cutoff = lens->
get_hfov() * 0.5f;
1727 t.set_row(3, LVecBase4(cutoff));
1731 t.set_row(3, LVecBase4(180));
1735 }
else if (attrib == IN_spotCosCutoff) {
1736 if (node !=
nullptr &&
1737 node->
is_of_type(Spotlight::get_class_type())) {
1739 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1741 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1743 float cutoff = lens->
get_hfov() * 0.5f;
1744 t.set_row(3, LVecBase4(ccos(deg_2_rad(cutoff))));
1748 t.set_row(3, LVecBase4(-1));
1752 }
else if (attrib == IN_spotExponent) {
1753 if (node ==
nullptr) {
1754 return &LMatrix4::zeros_mat();
1757 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1762 }
else if (attrib == IN_attenuation) {
1763 if (node !=
nullptr) {
1765 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1769 t.set_row(3, LVecBase4(1, 0, 0, 0));
1773 }
else if (attrib == IN_constantAttenuation) {
1774 if (node ==
nullptr) {
1775 return &LMatrix4::ones_mat();
1778 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1783 }
else if (attrib == IN_linearAttenuation) {
1784 if (node ==
nullptr) {
1785 return &LMatrix4::zeros_mat();
1788 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1793 }
else if (attrib == IN_quadraticAttenuation) {
1794 if (node ==
nullptr) {
1795 return &LMatrix4::zeros_mat();
1798 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1803 }
else if (attrib == IN_shadowViewMatrix) {
1804 static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f,
1805 0.0f, 0.5f, 0.0f, 0.0f,
1806 0.0f, 0.0f, 0.5f, 0.0f,
1807 0.5f, 0.5f, 0.5f, 1.0f);
1809 if (node ==
nullptr) {
1814 DCAST_INTO_R(lnode, node, &LMatrix4::ident_mat());
1817 t = _inv_cs_transform->get_mat() *
1818 _scene_setup->get_camera_transform()->get_mat() *
1819 np.get_net_transform()->get_inverse()->
get_mat() *
1822 if (!node->
is_of_type(PointLight::get_class_type())) {
1829 <<
"Shader input requests invalid attribute " << *attrib
1830 <<
" from node " << np <<
"\n";
1831 return &LMatrix4::ident_mat();
1842 static PT(
Texture) default_add_tex;
1843 static PT(
Texture) default_normal_height_tex;
1845 switch (spec._part) {
1846 case Shader::STO_named_input:
1848 if (!_target_shader->has_shader_input(spec._name)) {
1851 if (parent != InternalName::get_root() &&
1852 _target_shader->has_shader_input(parent)) {
1855 const string &basename = spec._name->get_basename();
1856 NodePath np = _target_shader->get_shader_input_nodepath(parent);
1858 if (basename ==
"shadowMap") {
1859 PT(
Texture) tex = get_shadow_map(np);
1860 if (tex !=
nullptr) {
1861 sampler = tex->get_default_sampler();
1866 if (spec._stage == 0) {
1868 <<
"Shader input " << *parent
1869 <<
" has no member named " << basename <<
".\n";
1877 if (spec._stage == 0) {
1879 <<
"Shader input " << *spec._name <<
" is not present.\n";
1885 return _target_shader->get_shader_input_texture(spec._name, &sampler);
1889 case Shader::STO_stage_i:
1894 _target_rs->get_attrib_def(texattrib);
1905 case Shader::STO_light_i_shadow_map:
1908 _target_rs->get_attrib_def(target_light);
1915 if (spec._stage >= 0 && (
size_t)spec._stage < num_lights) {
1917 nassertr(!light.
is_empty(),
nullptr);
1919 nassertr(light_obj !=
nullptr,
nullptr);
1922 if (lln !=
nullptr && lln->_shadow_caster) {
1923 tex = get_shadow_map(light);
1925 tex = get_dummy_shadow_map((Texture::TextureType)spec._desired_type);
1929 tex = get_dummy_shadow_map((Texture::TextureType)spec._desired_type);
1931 if (tex !=
nullptr) {
1932 sampler = tex->get_default_sampler();
1937 case Shader::STO_ff_stage_i:
1942 _target_rs->get_attrib_def(texattrib);
1953 case Shader::STO_stage_modulate_i:
1956 if (_target_rs->get_attrib(texattrib)) {
1960 TextureStage::Mode mode = stage->
get_mode();
1962 if (mode == TextureStage::M_modulate ||
1963 mode == TextureStage::M_modulate_glow ||
1964 mode == TextureStage::M_modulate_gloss) {
1965 if (si++ == spec._stage) {
1976 case Shader::STO_stage_add_i:
1979 if (_target_rs->get_attrib(texattrib)) {
1983 TextureStage::Mode mode = stage->
get_mode();
1985 if (mode == TextureStage::M_add) {
1986 if (si++ == spec._stage) {
1995 if (default_add_tex ==
nullptr) {
1997 tex->setup_2d_texture(1, 1, Texture::T_unsigned_byte, Texture::F_luminance);
1998 tex->set_clear_color(LColor(0, 0, 0, 1));
1999 default_add_tex = std::move(tex);
2001 return default_add_tex;
2004 case Shader::STO_stage_normal_i:
2007 if (_target_rs->get_attrib(texattrib)) {
2011 TextureStage::Mode mode = stage->
get_mode();
2013 if (mode == TextureStage::M_normal ||
2014 mode == TextureStage::M_normal_height) {
2015 if (si++ == spec._stage) {
2024 if (default_normal_height_tex ==
nullptr) {
2026 tex->setup_2d_texture(1, 1, Texture::T_unsigned_byte, Texture::F_rgba);
2027 tex->set_clear_color(LColor(0.5, 0.5, 1, 0));
2028 default_normal_height_tex = std::move(tex);
2030 return default_normal_height_tex;
2033 case Shader::STO_stage_gloss_i:
2036 if (_target_rs->get_attrib(texattrib)) {
2040 TextureStage::Mode mode = stage->
get_mode();
2042 if (mode == TextureStage::M_gloss ||
2043 mode == TextureStage::M_modulate_gloss ||
2044 mode == TextureStage::M_normal_gloss) {
2045 if (si++ == spec._stage) {
2056 case Shader::STO_stage_height_i:
2059 if (_target_rs->get_attrib(texattrib)) {
2063 TextureStage::Mode mode = stage->
get_mode();
2065 if (mode == TextureStage::M_height ||
2066 mode == TextureStage::M_normal_height) {
2067 if (si++ == spec._stage) {
2076 if (default_normal_height_tex ==
nullptr) {
2078 tex->setup_2d_texture(1, 1, Texture::T_unsigned_byte, Texture::F_rgba);
2079 tex->set_clear_color(LColor(0.5, 0.5, 1, 0));
2080 default_normal_height_tex = std::move(tex);
2082 return default_normal_height_tex;
2085 case Shader::STO_stage_selector_i:
2088 if (_target_rs->get_attrib(texattrib)) {
2092 TextureStage::Mode mode = stage->
get_mode();
2094 if (mode == TextureStage::M_selector) {
2095 if (si++ == spec._stage) {
2106 case Shader::STO_stage_emission_i:
2109 if (_target_rs->get_attrib(texattrib)) {
2113 TextureStage::Mode mode = stage->
get_mode();
2115 if (mode == TextureStage::M_emission) {
2116 if (si++ == spec._stage) {
2128 nassertr(
false,
nullptr);
2140 return (_target_shader->get_shader_input_ptr(spec._arg));
2149 _current_display_region = dr->get_object();
2152 _effective_incomplete_render = _incomplete_render && _current_display_region->get_incomplete_render();
2154 _stereo_buffer_mask = ~0;
2159 switch (output_channel) {
2161 output_channel = Lens::SC_right;
2164 case Lens::SC_right:
2165 output_channel = Lens::SC_left;
2173 switch (output_channel) {
2176 if (_current_properties->is_stereo()) {
2181 case Lens::SC_right:
2183 if (_current_properties->is_stereo()) {
2189 case Lens::SC_stereo:
2190 _color_write_mask = ColorWriteAttrib::C_all;
2213 reissue_transforms();
2216 _state_rs = RenderState::make_empty();
2217 _state_mask.
clear();
2227 nassertv(_engine !=
nullptr);
2229 DCAST_INTO_V(win, window);
2252calc_projection_mat(
const Lens *lens) {
2253 if (lens ==
nullptr) {
2261 return TransformState::make_identity();
2274 _prepared_objects->begin_frame(
this, current_thread);
2281 _state_rs = RenderState::make_empty();
2282 _state_mask.
clear();
2288 if (_last_query_frame < frame) {
2289 _last_query_frame = frame;
2290 _timer_queries_pcollector.clear_level();
2297 if (_timer_queries_active) {
2300 issue_timer_query(0x8000);
2301 issue_timer_query(0x0000);
2306 return !_needs_reset;
2337 _scene_setup = _scene_null;
2343 for (i = 0; i < _num_lights_enabled; ++i) {
2344 enable_light(i,
false);
2346 _num_lights_enabled = 0;
2349 for (i = 0; i < _num_clip_planes_enabled; ++i) {
2350 enable_clip_plane(i,
false);
2352 _num_clip_planes_enabled = 0;
2355 _state_rs = RenderState::make_empty();
2356 _state_mask.
clear();
2365 _prepared_objects->end_frame(current_thread);
2368 _data_transferred_pcollector.flush_level();
2370 _primitive_batches_pcollector.flush_level();
2371 _primitive_batches_tristrip_pcollector.flush_level();
2372 _primitive_batches_trifan_pcollector.flush_level();
2373 _primitive_batches_tri_pcollector.flush_level();
2374 _primitive_batches_patch_pcollector.flush_level();
2375 _primitive_batches_other_pcollector.flush_level();
2376 _vertices_tristrip_pcollector.flush_level();
2377 _vertices_trifan_pcollector.flush_level();
2378 _vertices_tri_pcollector.flush_level();
2379 _vertices_patch_pcollector.flush_level();
2380 _vertices_other_pcollector.flush_level();
2382 _state_pcollector.flush_level();
2383 _texture_state_pcollector.flush_level();
2384 _transform_state_pcollector.flush_level();
2385 _draw_primitive_pcollector.flush_level();
2388 _prepared_objects->_graphics_memory_lru.begin_epoch();
2402 PStatClient *client = PStatClient::get_global_pstats();
2404 if (!client->client_is_connected()) {
2405 _timer_queries_active =
false;
2409 if (!_timer_queries_active) {
2410 if (pstats_gpu_timing && _supports_timer_query) {
2412 _timer_queries_active =
true;
2420 if (_pstats_gpu_thread == -1) {
2423 PStatThread gpu_thread(client, _pstats_gpu_thread);
2427 if (!_pending_timer_queries.empty()) {
2428 int count = _pending_timer_queries.size();
2435 if (_last_num_queried > 0) {
2438 int i = std::min(_last_num_queried, count) - 1;
2440 if (_pending_timer_queries[i]->is_answer_ready()) {
2442 while (i < count - 1) {
2443 if (!_pending_timer_queries[++i]->is_answer_ready()) {
2451 if (_pending_timer_queries[--i]->is_answer_ready()) {
2462 int step = count / 2;
2463 int i = first + step;
2464 if (_pending_timer_queries[i]->is_answer_ready()) {
2477 _last_num_queried = first;
2479 for (
int i = 0; i < first; ++i) {
2482 double time_data = query->get_timestamp();
2484 if (query->_pstats_index == _command_latency_pcollector.get_index()) {
2487 cdef = client->get_collector_ptr(query->_pstats_index)->get_def(client, query->_pstats_index);
2488 _pstats_gpu_data.add_level(query->_pstats_index, time_data * cdef->_factor);
2490 }
else if (query->_pstats_index & 0x8000) {
2491 _pstats_gpu_data.add_stop(query->_pstats_index & 0x7fff, time_data);
2494 _pstats_gpu_data.add_start(query->_pstats_index & 0x7fff, time_data);
2500 if (query->_pstats_index == 0x8000) {
2502 _pstats_gpu_data.clear();
2509 _pending_timer_queries.erase(
2510 _pending_timer_queries.begin(),
2511 _pending_timer_queries.begin() + first
2513 _timer_queries_pcollector.add_level_now(first);
2536begin_decal_base_first() {
2539 if (decal_base_first ==
nullptr) {
2540 decal_base_first = RenderState::make
2541 (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
2542 RenderState::get_max_priority());
2544 return decal_base_first;
2554begin_decal_nested() {
2558 if (decal_nested ==
nullptr) {
2559 decal_nested = RenderState::make
2560 (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
2561 RenderState::get_max_priority());
2563 return decal_nested;
2577begin_decal_base_second() {
2582 if (decal_base_second ==
nullptr) {
2583 decal_base_second = RenderState::make
2584 (ColorWriteAttrib::make(ColorWriteAttrib::C_off),
2588 RenderState::get_max_priority());
2590 return decal_base_second;
2610 _data_reader = data_reader;
2614 return _data_reader->has_vertex() || (_target_shader && _target_shader->has_shader());
2713 _data_reader =
nullptr;
2721 _needs_reset =
false;
2724 _state_rs = RenderState::make_empty();
2725 _target_rs =
nullptr;
2726 _state_mask.
clear();
2727 _internal_transform = _cs_transform;
2729 _scene_setup = _scene_null;
2731 _color_write_mask = ColorWriteAttrib::C_all;
2733 _has_scene_graph_color =
false;
2734 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2735 _transform_stale =
true;
2736 _color_blend_involves_color_scale =
false;
2737 _texture_involves_color_scale =
false;
2738 _vertex_colors_enabled =
true;
2739 _lighting_enabled =
false;
2740 _num_lights_enabled = 0;
2741 _num_clip_planes_enabled = 0;
2742 _clip_planes_enabled =
false;
2744 _color_scale_enabled =
false;
2745 _current_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
2746 _has_texture_alpha_scale =
false;
2748 _has_material_force_color =
false;
2749 _material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2750 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
2752 _tex_gen_modifies_mat =
false;
2753 _last_max_stage_index = 0;
2803get_cs_transform_for(CoordinateSystem cs)
const {
2804 if (_coordinate_system == cs) {
2806 return _cs_transform;
2808 }
else if (_internal_coordinate_system == CS_default ||
2809 _internal_coordinate_system == cs) {
2810 return TransformState::make_identity();
2813 return TransformState::make_mat
2814 (LMatrix4::convert_mat(cs, _internal_coordinate_system));
2825get_cs_transform()
const {
2826 return _cs_transform;
2833void GraphicsStateGuardian::
2834do_issue_clip_plane() {
2835 int num_enabled = 0;
2836 int num_on_planes = 0;
2839 _target_rs->get_attrib_def(ClipPlaneAttrib::get_class_slot());
2841 if (target_clip_plane !=
nullptr) {
2842 CPT(
ClipPlaneAttrib) new_plane = target_clip_plane->filter_to_max(_max_clip_planes);
2845 for (
int li = 0; li < num_on_planes; li++) {
2846 NodePath plane = new_plane->get_on_plane(li);
2849 DCAST_INTO_V(plane_node, plane.
node());
2852 if (!_clip_planes_enabled) {
2853 enable_clip_planes(
true);
2854 _clip_planes_enabled =
true;
2857 enable_clip_plane(num_enabled,
true);
2858 if (num_enabled == 0) {
2859 begin_bind_clip_planes();
2862 bind_clip_plane(plane, num_enabled);
2869 for (i = num_enabled; i < _num_clip_planes_enabled; ++i) {
2870 enable_clip_plane(i,
false);
2872 _num_clip_planes_enabled = num_enabled;
2875 if (num_enabled == 0) {
2876 if (_clip_planes_enabled) {
2877 enable_clip_planes(
false);
2878 _clip_planes_enabled =
false;
2881 end_bind_clip_planes();
2896 _target_rs->get_attrib_def(ColorAttrib::get_class_slot());
2899 case ColorAttrib::T_flat:
2902 _scene_graph_color = target_color->
get_color();
2903 _has_scene_graph_color =
true;
2904 _vertex_colors_enabled =
false;
2907 case ColorAttrib::T_off:
2910 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2911 _has_scene_graph_color =
false;
2912 _vertex_colors_enabled =
false;
2915 case ColorAttrib::T_vertex:
2918 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2919 _has_scene_graph_color =
false;
2920 _vertex_colors_enabled =
true;
2924 if (_color_scale_via_lighting) {
2925 _state_mask.
clear_bit(LightAttrib::get_class_slot());
2926 _state_mask.
clear_bit(MaterialAttrib::get_class_slot());
2928 determine_light_color_scale();
2935void GraphicsStateGuardian::
2936do_issue_color_scale() {
2939 if (_has_texture_alpha_scale) {
2940 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2944 _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot());
2946 _color_scale_enabled = target_color_scale->
has_scale();
2947 _current_color_scale = target_color_scale->
get_scale();
2948 _has_texture_alpha_scale =
false;
2950 if (_color_blend_involves_color_scale) {
2951 _state_mask.
clear_bit(TransparencyAttrib::get_class_slot());
2953 if (_texture_involves_color_scale) {
2954 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2956 if (_color_scale_via_lighting) {
2957 _state_mask.
clear_bit(LightAttrib::get_class_slot());
2958 _state_mask.
clear_bit(MaterialAttrib::get_class_slot());
2960 determine_light_color_scale();
2963 if (_alpha_scale_via_texture && !_has_scene_graph_color &&
2967 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2968 _state_mask.
clear_bit(TexMatrixAttrib::get_class_slot());
2970 _has_texture_alpha_scale =
true;
2990 LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
2993 int num_enabled = 0;
2994 bool any_on_lights =
false;
2997 _target_rs->get_attrib_def(target_light);
2999 if (display_cat.is_spam()) {
3001 <<
"do_issue_light: " << target_light <<
"\n";
3003 if (target_light !=
nullptr) {
3008 for (
size_t li = 0; li < filtered_lights; ++li) {
3012 nassertv(light_obj !=
nullptr);
3015 if (!_lighting_enabled) {
3016 enable_lighting(
true);
3017 _lighting_enabled =
true;
3020 const LColor &color = light_obj->
get_color();
3022 if (color[0] != 0.0 || color[1] != 0.0 || color[2] != 0.0) {
3023 enable_light(num_enabled,
true);
3024 if (num_enabled == 0) {
3025 begin_bind_lights();
3028 light_obj->bind(
this, light, num_enabled);
3034 for (i = num_enabled; i < _num_lights_enabled; ++i) {
3035 enable_light(i,
false);
3037 _num_lights_enabled = num_enabled;
3040 if (!any_on_lights) {
3041 if (_color_scale_via_lighting && (_has_material_force_color || _light_color_scale != LVecBase4(1.0f, 1.0f, 1.0f, 1.0f))) {
3043 if (!_lighting_enabled) {
3044 enable_lighting(
true);
3045 _lighting_enabled =
true;
3047 set_ambient_light(LColor(1.0f, 1.0f, 1.0f, 1.0f));
3050 if (_lighting_enabled) {
3051 enable_lighting(
false);
3052 _lighting_enabled =
false;
3058 if (!_lighting_enabled) {
3059 enable_lighting(
true);
3060 _lighting_enabled =
true;
3063 set_ambient_light(target_light->get_ambient_contribution());
3066 if (num_enabled != 0) {
3128void GraphicsStateGuardian::
3129init_frame_pstats() {
3131 _data_transferred_pcollector.clear_level();
3132 _vertex_buffer_switch_pcollector.clear_level();
3133 _index_buffer_switch_pcollector.clear_level();
3135 _primitive_batches_pcollector.clear_level();
3136 _primitive_batches_tristrip_pcollector.clear_level();
3137 _primitive_batches_trifan_pcollector.clear_level();
3138 _primitive_batches_tri_pcollector.clear_level();
3139 _primitive_batches_patch_pcollector.clear_level();
3140 _primitive_batches_other_pcollector.clear_level();
3141 _vertices_tristrip_pcollector.clear_level();
3142 _vertices_trifan_pcollector.clear_level();
3143 _vertices_tri_pcollector.clear_level();
3144 _vertices_patch_pcollector.clear_level();
3145 _vertices_other_pcollector.clear_level();
3147 _state_pcollector.clear_level();
3148 _transform_state_pcollector.clear_level();
3149 _texture_state_pcollector.clear_level();
3159create_gamma_table (PN_stdfloat gamma,
unsigned short *red_table,
unsigned short *green_table,
unsigned short *blue_table) {
3167 for (i = 0; i < 256; i++) {
3170 PN_stdfloat gamma_correction;
3172 x = ((double) i / 255.0);
3173 gamma_correction = 1.0 / gamma;
3174 x = pow (x, (
double) gamma_correction);
3180 red_table [i] = (int)g;
3181 green_table [i] = (int)g;
3182 blue_table [i] = (int)g;
3191void GraphicsStateGuardian::
3192reissue_transforms() {
3200void GraphicsStateGuardian::
3201enable_lighting(
bool enable) {
3209void GraphicsStateGuardian::
3210set_ambient_light(
const LColor &color) {
3218void GraphicsStateGuardian::
3219enable_light(
int light_id,
bool enable) {
3230void GraphicsStateGuardian::
3231begin_bind_lights() {
3240void GraphicsStateGuardian::
3249void GraphicsStateGuardian::
3250enable_clip_planes(
bool enable) {
3258void GraphicsStateGuardian::
3259enable_clip_plane(
int plane_id,
bool enable) {
3270void GraphicsStateGuardian::
3271begin_bind_clip_planes() {
3279void GraphicsStateGuardian::
3280bind_clip_plane(
const NodePath &plane,
int plane_id) {
3289void GraphicsStateGuardian::
3290end_bind_clip_planes() {
3296void GraphicsStateGuardian::
3297determine_target_texture() {
3299 _target_rs->get_attrib_def(TextureAttrib::get_class_slot());
3301 _target_rs->get_attrib_def(TexGenAttrib::get_class_slot());
3303 nassertv(target_texture !=
nullptr &&
3304 target_tex_gen !=
nullptr);
3305 _target_texture = target_texture;
3306 _target_tex_gen = target_tex_gen;
3308 if (_has_texture_alpha_scale) {
3312 _target_texture = DCAST(
TextureAttrib, _target_texture->add_on_stage(stage, texture));
3313 _target_tex_gen = DCAST(
TexGenAttrib, _target_tex_gen->add_stage
3314 (stage, TexGenAttrib::M_constant, LTexCoord3(_current_color_scale[3], 0.0f, 0.0f)));
3318 _target_texture = _target_texture->filter_to_max(max_texture_stages);
3319 nassertv(_target_texture->get_num_on_stages() <= max_texture_stages);
3325void GraphicsStateGuardian::
3326determine_target_shader() {
3327 if (_target_rs->_generated_shader !=
nullptr) {
3328 _target_shader = (
const ShaderAttrib *)_target_rs->_generated_shader.p();
3331 _target_rs->get_attrib_def(ShaderAttrib::get_class_slot());
3338void GraphicsStateGuardian::
3347void GraphicsStateGuardian::
3354 _closing_gsg =
true;
3356 if (display_cat.is_debug()) {
3358 <<
this <<
" close_gsg " << get_type() <<
"\n";
3372 _prepared_objects.clear();
3374 _pending_timer_queries.clear();
3385void GraphicsStateGuardian::
3389 <<
"Deactivating " << get_type() <<
".\n";
3391 throw_event(
"panic-deactivate-gsg",
this);
3400void GraphicsStateGuardian::
3401determine_light_color_scale() {
3402 if (_has_scene_graph_color) {
3406 _has_material_force_color =
true;
3407 _material_force_color = _scene_graph_color;
3408 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3409 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3410 _material_force_color.set(_scene_graph_color[0] * _current_color_scale[0],
3411 _scene_graph_color[1] * _current_color_scale[1],
3412 _scene_graph_color[2] * _current_color_scale[2],
3413 _scene_graph_color[3] * _current_color_scale[3]);
3416 }
else if (!_vertex_colors_enabled) {
3420 _has_material_force_color =
true;
3421 _material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
3422 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3423 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3424 _material_force_color.componentwise_mult(_current_color_scale);
3430 _has_material_force_color =
false;
3431 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3432 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3433 _light_color_scale = _current_color_scale;
3444 if (state ==
nullptr) {
3445 state = RenderState::make(LightAttrib::make_all_off());
3454get_unclipped_state() {
3456 if (state ==
nullptr) {
3457 state = RenderState::make(ClipPlaneAttrib::make_all_off());
3466get_untextured_state() {
3468 if (state ==
nullptr) {
3469 state = RenderState::make(TextureAttrib::make_off());
3483 nassertr(_loader !=
nullptr,
nullptr);
3486 if (_current_display_region !=
nullptr) {
3487 priority = _current_display_region->get_texture_reload_priority();
3490 string task_name = string(
"reload:") + tc->
get_texture()->get_name();
3496 for (
size_t ti = 0; ti < num_tasks; ++ti) {
3498 if (task->
is_exact_type(TextureReloadRequest::get_class_type()) &&
3511 _supports_compressed_texture);
3512 request->set_priority(priority);
3513 _loader->load_async(request);
3522PT(
Texture) GraphicsStateGuardian::
3525 bool is_point = node->
is_of_type(PointLight::get_class_type());
3526 nassertr(node->
is_of_type(DirectionalLight::get_class_type()) ||
3527 node->
is_of_type(Spotlight::get_class_type()) ||
3531 if (light ==
nullptr || !light->_shadow_caster) {
3534 if (node->
is_of_type(PointLight::get_class_type())) {
3535 return get_dummy_shadow_map(Texture::TT_cube_map);
3537 return get_dummy_shadow_map(Texture::TT_2d_texture);
3542 nassertr(light->_shadow_map !=
nullptr,
nullptr);
3545 if (light->_sbuffers.count(
this) != 0) {
3547 return light->_shadow_map;
3550 if (display_cat.is_debug()) {
3552 <<
"Constructing shadow buffer for light '" << light->get_name()
3553 <<
"', size=" << light->_sb_size[0] <<
"x" << light->_sb_size[1]
3554 <<
", sort=" << light->_sb_sort <<
"\n";
3557 if (host ==
nullptr) {
3558 nassertr(_current_display_region !=
nullptr,
nullptr);
3559 host = _current_display_region->get_window();
3561 nassertr(host !=
nullptr,
nullptr);
3564 GraphicsOutput *sbuffer = make_shadow_buffer(light, light->_shadow_map,
3569 for (
int i = 0; i < 6; ++i) {
3572 dr->set_target_tex_page(i);
3573 dr->set_camera(light_np);
3574 dr->set_clear_depth_active(
true);
3579 dr->set_clear_depth_active(
true);
3582 light->_sbuffers[
this] = sbuffer;
3583 return light->_shadow_map;
3590PT(
Texture) GraphicsStateGuardian::
3591get_dummy_shadow_map(Texture::TextureType texture_type)
const {
3592 if (texture_type != Texture::TT_cube_map) {
3594 if (dummy_2d ==
nullptr) {
3595 dummy_2d =
new Texture(
"dummy-shadow-2d");
3596 dummy_2d->setup_2d_texture(1, 1, Texture::T_unsigned_byte, Texture::F_depth_component);
3597 dummy_2d->set_clear_color(1);
3600 dummy_2d->set_minfilter(SamplerState::FT_shadow);
3601 dummy_2d->set_magfilter(SamplerState::FT_shadow);
3603 dummy_2d->set_minfilter(SamplerState::FT_linear);
3604 dummy_2d->set_magfilter(SamplerState::FT_linear);
3609 static PT(
Texture) dummy_cube;
3610 if (dummy_cube ==
nullptr) {
3611 dummy_cube =
new Texture(
"dummy-shadow-cube");
3612 dummy_cube->setup_cube_map(1, Texture::T_unsigned_byte, Texture::F_depth_component);
3613 dummy_cube->set_clear_color(1);
3618 dummy_cube->set_minfilter(SamplerState::FT_shadow);
3619 dummy_cube->set_magfilter(SamplerState::FT_shadow);
3621 dummy_cube->set_minfilter(SamplerState::FT_linear);
3622 dummy_cube->set_magfilter(SamplerState::FT_linear);
3635 bool is_point = light->
is_of_type(PointLight::get_class_type());
3639 fbp.set_depth_bits(shadow_depth_bits);
3642 int flags = GraphicsPipe::BF_refuse_window;
3644 flags |= GraphicsPipe::BF_size_square;
3651 light->get_name(), light->_sb_sort, fbp, props, flags,
this, host);
3653 if (sbuffer !=
nullptr) {
3654 sbuffer->
add_render_texture(tex, GraphicsOutput::RTM_bind_or_copy, GraphicsOutput::RTP_depth);
3667 state->get_attrib_def(shader_attrib);
3670 if (_shader_generator ==
nullptr) {
3671 if (!_supports_basic_shaders) {
3674 _shader_generator =
new ShaderGenerator(_shader_caps, _supports_shadow_filter);
3676 if (state->_generated_shader ==
nullptr ||
3677 state->_generated_shader_seq != _generated_shader_seq) {
3683 state->get_attrib_def(sattr);
3684 if (sattr->get_flag(ShaderAttrib::F_hardware_skinning)) {
3689 state->_generated_shader = _shader_generator->synthesize_shader(state, spec);
3690 state->_generated_shader_seq = _generated_shader_seq;
3767operator << (std::ostream &out, GraphicsStateGuardian::ShaderModel sm) {
3768 static const char *sm_strings[] = {
"none",
"1.1",
"2.0",
"2.x",
"3.0",
"4.0",
"5.0",
"5.1"};
3769 nassertr(sm >= 0 && sm <= GraphicsStateGuardian::SM_51, out);
3770 out << sm_strings[sm];
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A light source that seems to illuminate all points in space at once.
This class represents a thread-safe handle to a promised future result of an asynchronous operation,...
A list of tasks, for instance as returned by some of the AsyncTaskManager query functions.
get_num_tasks
Returns the number of AsyncTasks in the collection.
get_task
Returns the nth AsyncTask in the collection.
A class to manage a loose queue of isolated tasks, which can be performed either synchronously (in th...
This class represents a concrete task performed by an AsyncManager.
get_priority
Returns the task's current priority value.
set_priority
Specifies a priority value for this task.
void clear_bit(int index)
Sets the nth bit off.
void clear()
Sets all the bits in the BitMask off.
This is a base class for those kinds of SavedContexts that occupy an easily-measured (and substantial...
This is a const pointer to an InternalName, and should be used in lieu of a CPT(InternalName) in func...
This functions similarly to a LightAttrib.
get_on_plane
Returns the nth plane enabled by the attribute, sorted in render order.
get_num_on_planes
Returns the number of planes that are enabled by the attribute.
get_frame_time
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
get_dt
Returns the elapsed time for the previous frame: the number of seconds elapsed between the last two c...
get_frame_count
Returns the number of times tick() has been called since the ClockObject was created,...
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
Indicates what color should be applied to renderable geometry.
get_color
If the type is T_flat or T_off, this returns the color that will be applied to geometry.
get_color_type
Returns the type of color specified by this ColorAttrib.
Applies a scale to colors in the scene graph and on vertices.
bool has_alpha_scale() const
Returns true if the ColorScaleAttrib has a non-identity scale in the alpha component (ignoring RGB),...
has_scale
Returns true if the ColorScaleAttrib has a non-identity scale, false otherwise (in which case it migh...
get_scale
Returns the scale to be applied to colors.
bool is_identity() const
Returns true if the ColorScaleAttrib is an identity attrib, false if it is either an off attrib or it...
A light shining from infinitely far away in a particular direction, like sunlight.
get_direction
Returns the direction in which the light is aimed.
get_specular_color
Returns the color of specular highlights generated by the light.
Encapsulates the data from a DisplayRegion, pre-fetched for one stage of the pipeline.
GraphicsOutput * get_window() const
Returns the GraphicsOutput that this DisplayRegion is ultimately associated with, or NULL if no windo...
int get_tex_view_offset()
Returns the current texture view offset for this DisplayRegion.
Lens::StereoChannel get_stereo_channel() const
Returns whether the DisplayRegion is specified as the left or right channel of a stereo pair,...
A rectangular subregion within a window for rendering into.
set_camera
Sets the camera that is associated with this DisplayRegion.
set_lens_index
Sets the lens index, allows for multiple lenses to be attached to a camera.
This is a base class for GraphicsWindow (actually, GraphicsOutput) and DisplayRegion,...
Applies a Fog to the geometry at and below this node.
get_fog
If the FogAttrib is not an 'off' FogAttrib, returns the fog that is associated.
Specifies how atmospheric fog effects are applied to geometry.
get_color
Returns the color of the fog.
get_exp_density
Returns the density of the fog for exponential calculations.
void get_linear_range(PN_stdfloat &onset, PN_stdfloat &opaque)
Retrieves the current onset and offset ranges.
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
int get_buffer_mask() const
Converts the non-aux bitplanes of the framebuffer into a RenderBuffer::Type.
This is a special class object that holds all the information returned by a particular GSG to indicat...
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
static void unregister_mungers_for_gsg(GraphicsStateGuardianBase *gsg)
Removes all the mungers from the registry that are associated with the indicated GSG.
Encapsulates the data from a Geom, pre-fetched for one stage of the pipeline.
Encapsulates the data from a GeomPrimitive, pre-fetched for one stage of the pipeline.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
This object describes how the vertex animation, if any, represented in a GeomVertexData is encoded.
void set_hardware(int num_transforms, bool indexed_transforms)
Specifies that vertex animation is to be performed by the graphics hardware (or at least by the graph...
This is the data for one array of a GeomVertexData structure.
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
A container for geometry primitives.
This class is the main interface to controlling the render process.
bool remove_window(GraphicsOutput *window)
Removes the indicated window or offscreen buffer from the set of windows that will be processed when ...
GraphicsOutput * make_output(GraphicsPipe *pipe, const std::string &name, int sort, const FrameBufferProperties &fb_prop, const WindowProperties &win_prop, int flags, GraphicsStateGuardian *gsg=nullptr, GraphicsOutput *host=nullptr)
Creates a new window (or buffer) and returns it.
An abstract base class for GraphicsOutput, for all the usual reasons.
This is a base class for the various different classes that represent the result of a frame of render...
void add_render_texture(Texture *tex, RenderTextureMode mode, RenderTexturePlane bitplane=RTP_COUNT)
Creates a new Texture object, suitable for rendering the contents of this buffer into,...
DisplayRegion * make_mono_display_region()
Creates a new DisplayRegion that covers the entire window.
unsigned int get_right_eye_color_mask() const
Returns the color mask in effect when rendering a right-eye view in red_blue stereo mode.
get_swap_eyes
Returns the current setting of the "swap eyes" flag.
unsigned int get_left_eye_color_mask() const
Returns the color mask in effect when rendering a left-eye view in red_blue stereo mode.
An object to create GraphicsOutputs that share a particular 3-D API.
static void remove_gsg(GraphicsStateGuardianBase *gsg)
Called by a GSG destructor to remove a GSG from the available list.
virtual bool framebuffer_copy_to_ram(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb)
Copy the pixels within the indicated display region from the framebuffer into system memory,...
virtual bool draw_points(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected points.
virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of triangle fans.
virtual void clear_before_callback()
Resets any non-standard graphics state that might give a callback apoplexy.
get_pipe
Returns the graphics pipe on which this GSG was created.
virtual bool depth_offset_decals()
Returns true if this GSG can implement decals using a DepthOffsetAttrib, or false if that is unreliab...
get_gamma
Get the current gamma setting.
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomVertexDataPipelineReader *data_reader, bool force)
Called before a sequence of draw_primitive() functions are called, this should prepare the vertex dat...
virtual bool update_texture(TextureContext *tc, bool force)
Ensures that the current Texture data is refreshed onto the GSG.
set_scene
Sets the SceneSetup object that indicates the initial camera position, etc.
GraphicsEngine * get_engine() const
Returns the graphics engine that created this GSG.
static TextureStage * get_alpha_scale_texture_stage()
Returns the TextureStage that will be used to apply an alpha scale, if get_alpha_scale_via_texture() ...
virtual TextureContext * prepare_texture(Texture *tex, int view)
Creates whatever structures the GSG requires to represent the texture internally, and returns a newly...
get_supports_multisample
Returns true if this particular GSG supports using the multisample bits to provide antialiasing,...
virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected triangles.
get_driver_version_minor
Returns the minor version of the video driver.
virtual void bind_light(PointLight *light_obj, const NodePath &light, int light_id)
Called the first time a particular light has been bound to a given id within a frame,...
virtual bool draw_lines(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected line segments.
virtual void release_shader_buffer(BufferContext *ibc)
Frees the resources previously allocated via a call to prepare_data(), including deleting the BufferC...
set_active
Sets the active flag associated with the GraphicsStateGuardian.
void traverse_prepared_textures(TextureCallback *func, void *callback_arg)
Calls the indicated function on all currently-prepared textures, or until the callback function retur...
get_flash_texture
Returns the current "flash texture", if any, or NULL if none.
virtual bool prepare_lens()
Makes the current lens (whichever lens was most recently specified with set_scene()) active,...
static void create_gamma_table(PN_stdfloat gamma, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table)
Create a gamma table.
virtual void clear_state_and_transform()
Forgets the current graphics state and current transform, so that the next call to set_state_and_tran...
get_driver_vendor
Returns the vendor of the video card driver.
virtual VertexBufferContext * prepare_vertex_buffer(GeomVertexArrayData *data)
Prepares the indicated buffer for retained-mode rendering.
virtual bool draw_patches(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of "patches", which can only be processed by a tessellation shader.
virtual bool framebuffer_copy_to_texture(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb)
Copy the pixels within the indicated display region from the framebuffer into texture memory.
virtual void prepare_display_region(DisplayRegionPipelineReader *dr)
Makes the specified DisplayRegion current.
get_driver_shader_version_minor
Returns the minor version of the shader model.
virtual void release_sampler(SamplerContext *sc)
Frees the resources previously allocated via a call to prepare_sampler(), including deleting the Samp...
get_prepared_objects
Returns the set of texture and geom objects that have been prepared with this GSG (and possibly other...
virtual void do_issue_light()
This implementation of do_issue_light() assumes we have a limited number of hardware lights available...
get_driver_renderer
Returns GL_Renderer.
void flush_timer_queries()
Called by the graphics engine on the draw thread to check the status of the running timer queries and...
virtual void release_vertex_buffer(VertexBufferContext *vbc)
Frees the resources previously allocated via a call to prepare_data(), including deleting the VertexB...
void do_issue_color()
This method is defined in the base class because it is likely that this functionality will be used fo...
const LMatrix4 * fetch_specified_part(Shader::ShaderMatInput input, InternalName *name, LMatrix4 &t, int index)
See fetch_specified_value.
virtual CoordinateSystem get_internal_coordinate_system() const
Returns the coordinate system used internally by the GSG.
virtual bool extract_texture_data(Texture *tex)
This method should only be called by the GraphicsEngine.
const LMatrix4 * fetch_specified_member(const NodePath &np, CPT_InternalName member, LMatrix4 &t)
Given a NodePath passed into a shader input that is a structure, fetches the value for the given memb...
get_driver_version_major
Returns major version of the video driver.
get_driver_shader_version_major
Returns the major version of the shader model.
virtual void release_geom(GeomContext *gc)
Frees the resources previously allocated via a call to prepare_geom(), including deleting the GeomCon...
get_supports_shadow_filter
Returns true if this particular GSG supports the filter mode FT_shadow for depth textures.
virtual SamplerContext * prepare_sampler(const SamplerState &sampler)
Creates whatever structures the GSG requires to represent the sampler internally, and returns a newly...
RenderBuffer get_render_buffer(int buffer_type, const FrameBufferProperties &prop)
Returns a RenderBuffer object suitable for operating on the requested set of buffers.
virtual void ensure_generated_shader(const RenderState *state)
Ensures that an appropriate shader has been generated for the given state.
PT(Texture) fetch_specified_texture(Shader const Shader::ShaderPtrData * fetch_ptr_parameter(const Shader::ShaderPtrSpec &spec)
Return a pointer to struct ShaderPtrData.
get_max_texture_stages
Returns the maximum number of simultaneous textures that may be applied to geometry with multitexturi...
virtual void end_frame(Thread *current_thread)
Called after each frame is rendered, to allow the GSG a chance to do any internal cleanup after rende...
virtual bool draw_lines_adj(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected line segments with adjacency information.
virtual bool has_extension(const std::string &extension) const
Returns true if the GSG implements the extension identified by the given string.
virtual bool draw_linestrips_adj(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of line strips with adjacency information.
virtual void end_scene()
Called between begin_frame() and end_frame() to mark the end of drawing commands for a "scene" (usual...
virtual void release_shader(ShaderContext *sc)
Releases the resources allocated by prepare_shader.
virtual GeomContext * prepare_geom(Geom *geom)
Prepares the indicated Geom for retained-mode rendering, by creating whatever structures are necessar...
virtual void reset()
Resets all internal state as if the gsg were newly created.
virtual int get_supported_geom_rendering() const
Returns the union of Geom::GeomRendering values that this particular GSG can support directly.
virtual void release_texture(TextureContext *tc)
Frees the resources previously allocated via a call to prepare_texture(), including deleting the Text...
get_driver_version
Returns driver version This has an implementation-defined meaning, and may be "" if the particular gr...
PN_stdfloat compute_distance_to(const LPoint3 &point) const
This function will compute the distance to the indicated point, assumed to be in eye coordinates,...
virtual void begin_occlusion_query()
Begins a new occlusion query.
const LMatrix4 * fetch_specified_value(Shader::ShaderMatSpec &spec, int altered)
The gsg contains a large number of useful matrices:
virtual IndexBufferContext * prepare_index_buffer(GeomPrimitive *data)
Prepares the indicated buffer for retained-mode rendering.
virtual void finish_decal()
Called during draw to clean up after decals are finished.
virtual bool draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of triangle strips.
get_scene
Returns the current SceneSetup object.
set_flash_texture
Sets the "flash texture".
virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of line strips.
virtual void set_state_and_transform(const RenderState *state, const TransformState *transform)
Simultaneously resets the render state and the transform state.
virtual bool get_supports_cg_profile(const std::string &name) const
Returns true if this particular GSG supports the specified Cg Shader Profile.
virtual bool draw_tristrips_adj(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of triangle strips with adjacency information.
virtual void clear(DrawableRegion *clearable)
Clears the framebuffer within the current DisplayRegion, according to the flags indicated by the give...
virtual bool begin_frame(Thread *current_thread)
Called before each frame is rendered, to allow the GSG a chance to do any internal cleanup before beg...
set_coordinate_system
Changes the coordinate system in effect on this particular gsg.
virtual BufferContext * prepare_shader_buffer(ShaderBuffer *data)
Prepares the indicated buffer for retained-mode rendering.
virtual void remove_window(GraphicsOutputBase *window)
This is simply a transparent call to GraphicsEngine::remove_window().
virtual void restore_gamma()
Restore original gamma setting.
virtual bool draw_triangles_adj(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected triangles with adjacency information.
virtual void dispatch_compute(int size_x, int size_y, int size_z)
Dispatches a currently bound compute shader using the given work group counts.
virtual void release_index_buffer(IndexBufferContext *ibc)
Frees the resources previously allocated via a call to prepare_data(), including deleting the IndexBu...
void clear_flash_texture()
Resets the "flash texture", so that no textures will flash.
virtual void end_draw_primitives()
Called after a sequence of draw_primitive() functions are called, this should do whatever cleanup is ...
virtual ShaderContext * prepare_shader(Shader *shader)
Compile a vertex/fragment shader body.
virtual bool begin_scene()
Called between begin_frame() and end_frame() to mark the beginning of drawing commands for a "scene" ...
This is a special class object that holds all the information returned by a particular GSG to indicat...
Encodes a string name in a hash table, mapping it to a pointer.
get_basename
Return the name represented by just this particular InternalName object, ignoring its parents names.
get_name
Returns the complete name represented by the InternalName and all of its parents.
get_parent
Return the parent of this InternalName.
A node that contains a Lens.
Lens * get_lens(int index=0) const
Returns a pointer to the particular Lens associated with this LensNode, or NULL if there is not yet a...
A base class for any number of different kinds of lenses, linear and otherwise.
virtual bool is_linear() const
Returns true if the lens represents a linear projection (e.g.
get_far
Returns the position of the far plane (or cylinder, sphere, whatever).
get_near
Returns the position of the near plane (or cylinder, sphere, whatever).
const LMatrix4 & get_projection_mat_inv(StereoChannel channel=SC_mono) const
Returns the matrix that transforms from a 2-d point on the film to a 3-d vector in space,...
PN_stdfloat get_hfov() const
Returns the horizontal component of fov only.
get_nodal_point
Returns the center point of the lens: the point from which the lens is viewing.
get_coordinate_system
Returns the coordinate system that all 3-d computations are performed within for this Lens.
const LVector3 & get_view_vector() const
Returns the axis along which the lens is facing.
const LMatrix4 & get_projection_mat(StereoChannel channel=SC_mono) const
Returns the complete transformation matrix from a 3-d point in space to a point on the film,...
Indicates which set of lights should be considered "on" to illuminate geometry at this level and belo...
bool has_any_on_light() const
Returns true if any light is turned on by the attrib, false otherwise.
size_t get_num_non_ambient_lights() const
Returns the number of non-ambient lights that are turned on by this attribute.
get_on_light
Returns the nth light turned on by the attribute, sorted in render order.
A derivative of Light and of Camera.
Similar to MutexHolder, but for a light reentrant mutex.
The abstract interface to all kinds of lights.
virtual PN_stdfloat get_exponent() const
For spotlights, returns the exponent that controls the amount of light falloff from the center of the...
virtual const LVecBase3 & get_attenuation() const
Returns the terms of the attenuation equation for the light.
get_color
Returns the basic color of the light.
virtual const LColor & get_specular_color() const
Returns the color of specular highlights generated by the light.
static Loader * get_global_ptr()
Returns a pointer to the global Loader.
Indicates which, if any, material should be applied to geometry.
bool is_off() const
Returns true if the MaterialAttrib is an 'off' MaterialAttrib, indicating that it should disable the ...
get_material
If the MaterialAttrib is not an 'off' MaterialAttrib, returns the material that is associated.
Defines the way an object appears in the presence of lighting.
get_ambient
Returns the ambient color setting, if it has been set.
get_emission
Returns the emission color setting, if it has been set.
get_base_color
Returns the base_color color setting, if it has been set.
get_refractive_index
Returns the index of refraction, or 1 if none has been set for this material.
get_specular
Returns the specular color setting, if it has been set.
get_metallic
Returns the metallic setting, if it has been set.
get_roughness
Returns the roughness previously specified by set_roughness.
get_shininess
Returns the shininess exponent of the material.
get_diffuse
Returns the diffuse color setting, if it has been set.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
bool is_empty() const
Returns true if the NodePath contains no nodes.
const LMatrix4 & get_mat() const
Returns the transform matrix that has been applied to the referenced node, or the identity matrix if ...
PandaNode * node() const
Returns the referenced node of the path.
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
Returned from a GSG in response to begin_occlusion_query() .
Manages the communications to report statistics via a network connection to a remote PStatServer.
static bool is_connected()
Returns true if the client believes it is connected to a working PStatServer, false otherwise.
Defines the details about the Collectors: the name, the suggested color, etc.
A lightweight class that represents a single element that may be timed and/or counted via stats.
This is a special type of PStatTimer that also uses a timer query on the GSG to measure how long a ta...
A lightweight class that represents a single thread of execution to PStats.
void add_frame(const PStatFrameData &frame_data)
This is a slightly lower-level version of new_frame that also specifies the data to send for this fra...
A basic node of the scene graph or data graph.
virtual bool is_ambient_light() const
Returns true if this is an AmbientLight, false if it is not a light, or it is some other kind of ligh...
virtual Light * as_light()
Cross-casts the node to a Light pointer, if it is one of the four kinds of Light nodes,...
A node that contains a plane.
get_clip_effect
Returns the clip_effect bits for this clip plane.
get_plane
Returns the plane represented by the PlaneNode.
A light originating from a single point in space, and shining in all directions.
get_specular_color
Returns the color of specular highlights generated by the light.
get_point
Returns the point in space at which the light is located.
get_attenuation
Returns the terms of the attenuation equation for the light.
A table of objects that are saved within the graphics context for reference by handle later.
Similar to MutexHolder, but for a reentrant mutex.
A RenderBuffer is an arbitrary subset of the various layers (depth buffer, color buffer,...
Specifies how polygons are to be drawn.
get_perspective
Returns the perspective flag.
get_thickness
Returns the line width or point thickness.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
This is a special class object that holds a handle to the sampler state object given by the graphics ...
Represents a set of settings that indicate how a texture is sampled.
This object holds the camera position, etc., and other general setup information for rendering a part...
const Lens * get_lens() const
Returns the particular Lens used for rendering.
bool auto_shader() const
If true, then this ShaderAttrib does not contain an explicit shader - instead, it requests the automa...
This is a generic buffer object that lives in graphics memory.
The ShaderContext is meant to contain the compiled version of a shader string.
const Key & get_key(size_t n) const
Returns the key in the nth entry of the table.
int store(const Key &key, const Value &data)
Records the indicated key/data pair in the map.
const Value & get_data(size_t n) const
Returns the data in the nth entry of the table.
int find(const Key &key) const
Searches for the indicated key in the table.
bool remove(const Key &key)
Removes the indicated key and its associated data from the table.
void remove_element(size_t n)
Removes the nth entry from the table.
bool is_empty() const
Returns true if the table is empty; i.e.
size_t get_num_entries() const
Returns the number of active entries in the table.
A sphere light is like a point light, except that it represents a sphere with a radius,...
A light originating from a single point in space, and shining in a particular direction,...
get_specular_color
Returns the color of specular highlights generated by the light.
get_exponent
Returns the exponent that controls the amount of light falloff from the center of the spotlight.
get_attenuation
Returns the terms of the attenuation equation for the light.
Computes texture coordinates for geometry automatically based on vertex position and/or normal.
Applies a transform matrix to UV's before they are rendered.
Indicates the set of TextureStages and their associated Textures that should be applied to (or remove...
get_num_on_ff_stages
Returns the number of on-stages that are relevant to the classic fixed function pipeline.
get_num_on_stages
Returns the number of stages that are turned on by the attribute.
get_on_texture
Returns the texture associated with the indicated stage, or NULL if no texture is associated.
get_on_stage
Returns the nth stage turned on by the attribute, sorted in render order.
get_on_sampler
Returns the sampler associated with the indicated stage, or the one associated with its texture if no...
get_on_ff_stage
Returns the nth stage turned on by the attribute, sorted in render order, including only those releva...
This is a special class object that holds all the information returned by a particular GSG to indicat...
Texture * get_texture() const
Returns the pointer to the associated Texture object.
static Texture * get_alpha_scale_map()
Returns a standard Texture object that has been created with Texture::generate_alpha_scale_map().
This loader request will call Texture::get_ram_image() in a sub-thread, to force the texture's image ...
Defines the properties of a named stage of the multitexture pipeline.
get_color
return the color for this stage
get_tex_view_offset
Returns the current setting of the tex_view_offset.
get_mode
Return the mode of this stage.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
int get_pad_y_size() const
Returns size of the pad region.
get_y_size
Returns the height of the texture image in texels.
get_z_size
Returns the depth of the texture image in texels.
int get_pad_x_size() const
Returns size of the pad region.
int get_pad_z_size() const
Returns size of the pad region.
get_x_size
Returns the width of the texture image in texels.
A thread; that is, a lightweight process.
TypeHandle is the identifier used to differentiate C++ class types.
bool is_exact_type(TypeHandle handle) const
Returns true if the current object is the indicated type exactly.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
This is a special class object that holds all the information returned by a particular GSG to indicat...
A container for the various kinds of properties we might ask to have on a graphics window before we o...
static WindowProperties size(const LVecBase2i &size)
Returns a WindowProperties structure with only the size specified.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.