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);
1913 if (spec._stage >= 0 && (
size_t)spec._stage < num_lights) {
1915 nassertr(!light.
is_empty(),
nullptr);
1917 nassertr(light_obj !=
nullptr,
nullptr);
1921 if (lln !=
nullptr && lln->_shadow_caster) {
1922 tex = get_shadow_map(light);
1924 tex = get_dummy_shadow_map((Texture::TextureType)spec._desired_type);
1927 if (tex !=
nullptr) {
1928 sampler = tex->get_default_sampler();
1933 PT(
Texture) tex = get_dummy_shadow_map((Texture::TextureType)spec._desired_type);
1934 if (tex !=
nullptr) {
1935 sampler = tex->get_default_sampler();
1942 case Shader::STO_ff_stage_i:
1947 _target_rs->get_attrib_def(texattrib);
1958 case Shader::STO_stage_modulate_i:
1961 if (_target_rs->get_attrib(texattrib)) {
1965 TextureStage::Mode mode = stage->
get_mode();
1967 if (mode == TextureStage::M_modulate ||
1968 mode == TextureStage::M_modulate_glow ||
1969 mode == TextureStage::M_modulate_gloss) {
1970 if (si++ == spec._stage) {
1981 case Shader::STO_stage_add_i:
1984 if (_target_rs->get_attrib(texattrib)) {
1988 TextureStage::Mode mode = stage->
get_mode();
1990 if (mode == TextureStage::M_add) {
1991 if (si++ == spec._stage) {
2000 if (default_add_tex ==
nullptr) {
2002 tex->setup_2d_texture(1, 1, Texture::T_unsigned_byte, Texture::F_luminance);
2003 tex->set_clear_color(LColor(0, 0, 0, 1));
2004 default_add_tex = std::move(tex);
2006 return default_add_tex;
2010 case Shader::STO_stage_normal_i:
2013 if (_target_rs->get_attrib(texattrib)) {
2017 TextureStage::Mode mode = stage->
get_mode();
2019 if (mode == TextureStage::M_normal ||
2020 mode == TextureStage::M_normal_height) {
2021 if (si++ == spec._stage) {
2030 if (default_normal_height_tex ==
nullptr) {
2032 tex->setup_2d_texture(1, 1, Texture::T_unsigned_byte, Texture::F_rgba);
2033 tex->set_clear_color(LColor(0.5, 0.5, 1, 0));
2034 default_normal_height_tex = std::move(tex);
2036 return default_normal_height_tex;
2040 case Shader::STO_stage_gloss_i:
2043 if (_target_rs->get_attrib(texattrib)) {
2047 TextureStage::Mode mode = stage->
get_mode();
2049 if (mode == TextureStage::M_gloss ||
2050 mode == TextureStage::M_modulate_gloss ||
2051 mode == TextureStage::M_normal_gloss) {
2052 if (si++ == spec._stage) {
2063 case Shader::STO_stage_height_i:
2066 if (_target_rs->get_attrib(texattrib)) {
2070 TextureStage::Mode mode = stage->
get_mode();
2072 if (mode == TextureStage::M_height ||
2073 mode == TextureStage::M_normal_height) {
2074 if (si++ == spec._stage) {
2083 if (default_normal_height_tex ==
nullptr) {
2085 tex->setup_2d_texture(1, 1, Texture::T_unsigned_byte, Texture::F_rgba);
2086 tex->set_clear_color(LColor(0.5, 0.5, 1, 0));
2087 default_normal_height_tex = std::move(tex);
2089 return default_normal_height_tex;
2093 case Shader::STO_stage_selector_i:
2096 if (_target_rs->get_attrib(texattrib)) {
2100 TextureStage::Mode mode = stage->
get_mode();
2102 if (mode == TextureStage::M_selector) {
2103 if (si++ == spec._stage) {
2114 case Shader::STO_stage_emission_i:
2117 if (_target_rs->get_attrib(texattrib)) {
2121 TextureStage::Mode mode = stage->
get_mode();
2123 if (mode == TextureStage::M_emission) {
2124 if (si++ == spec._stage) {
2136 nassertr(
false,
nullptr);
2148 return (_target_shader->get_shader_input_ptr(spec._arg));
2157 _current_display_region = dr->get_object();
2160 _effective_incomplete_render = _incomplete_render && _current_display_region->get_incomplete_render();
2162 _stereo_buffer_mask = ~0;
2167 switch (output_channel) {
2169 output_channel = Lens::SC_right;
2172 case Lens::SC_right:
2173 output_channel = Lens::SC_left;
2181 switch (output_channel) {
2184 if (_current_properties->is_stereo()) {
2189 case Lens::SC_right:
2191 if (_current_properties->is_stereo()) {
2197 case Lens::SC_stereo:
2198 _color_write_mask = ColorWriteAttrib::C_all;
2221 reissue_transforms();
2224 _state_rs = RenderState::make_empty();
2225 _state_mask.
clear();
2235 nassertv(_engine !=
nullptr);
2237 DCAST_INTO_V(win, window);
2260calc_projection_mat(
const Lens *lens) {
2261 if (lens ==
nullptr) {
2269 return TransformState::make_identity();
2282 _prepared_objects->begin_frame(
this, current_thread);
2289 _state_rs = RenderState::make_empty();
2290 _state_mask.
clear();
2296 if (_last_query_frame < frame) {
2297 _last_query_frame = frame;
2298 _timer_queries_pcollector.clear_level();
2305 if (_timer_queries_active) {
2308 issue_timer_query(0x8000);
2309 issue_timer_query(0x0000);
2314 return !_needs_reset;
2345 _scene_setup = _scene_null;
2351 for (i = 0; i < _num_lights_enabled; ++i) {
2352 enable_light(i,
false);
2354 _num_lights_enabled = 0;
2357 for (i = 0; i < _num_clip_planes_enabled; ++i) {
2358 enable_clip_plane(i,
false);
2360 _num_clip_planes_enabled = 0;
2363 _state_rs = RenderState::make_empty();
2364 _state_mask.
clear();
2373 _prepared_objects->end_frame(current_thread);
2376 _data_transferred_pcollector.flush_level();
2378 _primitive_batches_pcollector.flush_level();
2379 _primitive_batches_tristrip_pcollector.flush_level();
2380 _primitive_batches_trifan_pcollector.flush_level();
2381 _primitive_batches_tri_pcollector.flush_level();
2382 _primitive_batches_patch_pcollector.flush_level();
2383 _primitive_batches_other_pcollector.flush_level();
2384 _vertices_tristrip_pcollector.flush_level();
2385 _vertices_trifan_pcollector.flush_level();
2386 _vertices_tri_pcollector.flush_level();
2387 _vertices_patch_pcollector.flush_level();
2388 _vertices_other_pcollector.flush_level();
2390 _state_pcollector.flush_level();
2391 _texture_state_pcollector.flush_level();
2392 _transform_state_pcollector.flush_level();
2393 _draw_primitive_pcollector.flush_level();
2396 _prepared_objects->_graphics_memory_lru.begin_epoch();
2410 PStatClient *client = PStatClient::get_global_pstats();
2412 if (!client->client_is_connected()) {
2413 _timer_queries_active =
false;
2417 if (!_timer_queries_active) {
2418 if (pstats_gpu_timing && _supports_timer_query) {
2420 _timer_queries_active =
true;
2428 if (_pstats_gpu_thread == -1) {
2431 PStatThread gpu_thread(client, _pstats_gpu_thread);
2435 if (!_pending_timer_queries.empty()) {
2436 int count = _pending_timer_queries.size();
2443 if (_last_num_queried > 0) {
2446 int i = std::min(_last_num_queried, count) - 1;
2448 if (_pending_timer_queries[i]->is_answer_ready()) {
2450 while (i < count - 1) {
2451 if (!_pending_timer_queries[++i]->is_answer_ready()) {
2459 if (_pending_timer_queries[--i]->is_answer_ready()) {
2470 int step = count / 2;
2471 int i = first + step;
2472 if (_pending_timer_queries[i]->is_answer_ready()) {
2485 _last_num_queried = first;
2487 for (
int i = 0; i < first; ++i) {
2490 double time_data = query->get_timestamp();
2492 if (query->_pstats_index == _command_latency_pcollector.get_index()) {
2495 cdef = client->get_collector_ptr(query->_pstats_index)->get_def(client, query->_pstats_index);
2496 _pstats_gpu_data.add_level(query->_pstats_index, time_data * cdef->_factor);
2498 }
else if (query->_pstats_index & 0x8000) {
2499 _pstats_gpu_data.add_stop(query->_pstats_index & 0x7fff, time_data);
2502 _pstats_gpu_data.add_start(query->_pstats_index & 0x7fff, time_data);
2508 if (query->_pstats_index == 0x8000) {
2510 _pstats_gpu_data.clear();
2517 _pending_timer_queries.erase(
2518 _pending_timer_queries.begin(),
2519 _pending_timer_queries.begin() + first
2521 _timer_queries_pcollector.add_level_now(first);
2544begin_decal_base_first() {
2547 if (decal_base_first ==
nullptr) {
2548 decal_base_first = RenderState::make
2549 (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
2550 RenderState::get_max_priority());
2552 return decal_base_first;
2562begin_decal_nested() {
2566 if (decal_nested ==
nullptr) {
2567 decal_nested = RenderState::make
2568 (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
2569 RenderState::get_max_priority());
2571 return decal_nested;
2585begin_decal_base_second() {
2590 if (decal_base_second ==
nullptr) {
2591 decal_base_second = RenderState::make
2592 (ColorWriteAttrib::make(ColorWriteAttrib::C_off),
2596 RenderState::get_max_priority());
2598 return decal_base_second;
2618 _data_reader = data_reader;
2622 return _data_reader->has_vertex() || (_target_shader && _target_shader->has_shader());
2721 _data_reader =
nullptr;
2729 _needs_reset =
false;
2732 _state_rs = RenderState::make_empty();
2733 _target_rs =
nullptr;
2734 _state_mask.
clear();
2735 _internal_transform = _cs_transform;
2737 _scene_setup = _scene_null;
2739 _color_write_mask = ColorWriteAttrib::C_all;
2741 _has_scene_graph_color =
false;
2742 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2743 _transform_stale =
true;
2744 _color_blend_involves_color_scale =
false;
2745 _texture_involves_color_scale =
false;
2746 _vertex_colors_enabled =
true;
2747 _lighting_enabled =
false;
2748 _num_lights_enabled = 0;
2749 _num_clip_planes_enabled = 0;
2750 _clip_planes_enabled =
false;
2752 _color_scale_enabled =
false;
2753 _current_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
2754 _has_texture_alpha_scale =
false;
2756 _has_material_force_color =
false;
2757 _material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2758 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
2760 _tex_gen_modifies_mat =
false;
2761 _last_max_stage_index = 0;
2811get_cs_transform_for(CoordinateSystem cs)
const {
2812 if (_coordinate_system == cs) {
2814 return _cs_transform;
2816 }
else if (_internal_coordinate_system == CS_default ||
2817 _internal_coordinate_system == cs) {
2818 return TransformState::make_identity();
2821 return TransformState::make_mat
2822 (LMatrix4::convert_mat(cs, _internal_coordinate_system));
2833get_cs_transform()
const {
2834 return _cs_transform;
2841void GraphicsStateGuardian::
2842do_issue_clip_plane() {
2843 int num_enabled = 0;
2844 int num_on_planes = 0;
2847 _target_rs->get_attrib_def(ClipPlaneAttrib::get_class_slot());
2849 if (target_clip_plane !=
nullptr) {
2850 CPT(
ClipPlaneAttrib) new_plane = target_clip_plane->filter_to_max(_max_clip_planes);
2853 for (
int li = 0; li < num_on_planes; li++) {
2854 NodePath plane = new_plane->get_on_plane(li);
2857 DCAST_INTO_V(plane_node, plane.
node());
2860 if (!_clip_planes_enabled) {
2861 enable_clip_planes(
true);
2862 _clip_planes_enabled =
true;
2865 enable_clip_plane(num_enabled,
true);
2866 if (num_enabled == 0) {
2867 begin_bind_clip_planes();
2870 bind_clip_plane(plane, num_enabled);
2877 for (i = num_enabled; i < _num_clip_planes_enabled; ++i) {
2878 enable_clip_plane(i,
false);
2880 _num_clip_planes_enabled = num_enabled;
2883 if (num_enabled == 0) {
2884 if (_clip_planes_enabled) {
2885 enable_clip_planes(
false);
2886 _clip_planes_enabled =
false;
2889 end_bind_clip_planes();
2904 _target_rs->get_attrib_def(ColorAttrib::get_class_slot());
2907 case ColorAttrib::T_flat:
2910 _scene_graph_color = target_color->
get_color();
2911 _has_scene_graph_color =
true;
2912 _vertex_colors_enabled =
false;
2915 case ColorAttrib::T_off:
2918 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2919 _has_scene_graph_color =
false;
2920 _vertex_colors_enabled =
false;
2923 case ColorAttrib::T_vertex:
2926 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2927 _has_scene_graph_color =
false;
2928 _vertex_colors_enabled =
true;
2932 if (_color_scale_via_lighting) {
2933 _state_mask.
clear_bit(LightAttrib::get_class_slot());
2934 _state_mask.
clear_bit(MaterialAttrib::get_class_slot());
2936 determine_light_color_scale();
2943void GraphicsStateGuardian::
2944do_issue_color_scale() {
2947 if (_has_texture_alpha_scale) {
2948 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2952 _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot());
2954 _color_scale_enabled = target_color_scale->
has_scale();
2955 _current_color_scale = target_color_scale->
get_scale();
2956 _has_texture_alpha_scale =
false;
2958 if (_color_blend_involves_color_scale) {
2959 _state_mask.
clear_bit(TransparencyAttrib::get_class_slot());
2961 if (_texture_involves_color_scale) {
2962 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2964 if (_color_scale_via_lighting) {
2965 _state_mask.
clear_bit(LightAttrib::get_class_slot());
2966 _state_mask.
clear_bit(MaterialAttrib::get_class_slot());
2968 determine_light_color_scale();
2971 if (_alpha_scale_via_texture && !_has_scene_graph_color &&
2975 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2976 _state_mask.
clear_bit(TexMatrixAttrib::get_class_slot());
2978 _has_texture_alpha_scale =
true;
2998 LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
3001 int num_enabled = 0;
3002 bool any_on_lights =
false;
3005 _target_rs->get_attrib_def(target_light);
3007 if (display_cat.is_spam()) {
3009 <<
"do_issue_light: " << target_light <<
"\n";
3011 if (target_light !=
nullptr) {
3016 for (
size_t li = 0; li < filtered_lights; ++li) {
3020 nassertv(light_obj !=
nullptr);
3023 if (!_lighting_enabled) {
3024 enable_lighting(
true);
3025 _lighting_enabled =
true;
3028 const LColor &color = light_obj->
get_color();
3030 if (color[0] != 0.0 || color[1] != 0.0 || color[2] != 0.0) {
3031 enable_light(num_enabled,
true);
3032 if (num_enabled == 0) {
3033 begin_bind_lights();
3036 light_obj->bind(
this, light, num_enabled);
3042 for (i = num_enabled; i < _num_lights_enabled; ++i) {
3043 enable_light(i,
false);
3045 _num_lights_enabled = num_enabled;
3048 if (!any_on_lights) {
3049 if (_color_scale_via_lighting && (_has_material_force_color || _light_color_scale != LVecBase4(1.0f, 1.0f, 1.0f, 1.0f))) {
3051 if (!_lighting_enabled) {
3052 enable_lighting(
true);
3053 _lighting_enabled =
true;
3055 set_ambient_light(LColor(1.0f, 1.0f, 1.0f, 1.0f));
3058 if (_lighting_enabled) {
3059 enable_lighting(
false);
3060 _lighting_enabled =
false;
3066 if (!_lighting_enabled) {
3067 enable_lighting(
true);
3068 _lighting_enabled =
true;
3071 set_ambient_light(target_light->get_ambient_contribution());
3074 if (num_enabled != 0) {
3136void GraphicsStateGuardian::
3137init_frame_pstats() {
3139 _data_transferred_pcollector.clear_level();
3140 _vertex_buffer_switch_pcollector.clear_level();
3141 _index_buffer_switch_pcollector.clear_level();
3143 _primitive_batches_pcollector.clear_level();
3144 _primitive_batches_tristrip_pcollector.clear_level();
3145 _primitive_batches_trifan_pcollector.clear_level();
3146 _primitive_batches_tri_pcollector.clear_level();
3147 _primitive_batches_patch_pcollector.clear_level();
3148 _primitive_batches_other_pcollector.clear_level();
3149 _vertices_tristrip_pcollector.clear_level();
3150 _vertices_trifan_pcollector.clear_level();
3151 _vertices_tri_pcollector.clear_level();
3152 _vertices_patch_pcollector.clear_level();
3153 _vertices_other_pcollector.clear_level();
3155 _state_pcollector.clear_level();
3156 _transform_state_pcollector.clear_level();
3157 _texture_state_pcollector.clear_level();
3167create_gamma_table (PN_stdfloat gamma,
unsigned short *red_table,
unsigned short *green_table,
unsigned short *blue_table) {
3175 for (i = 0; i < 256; i++) {
3178 PN_stdfloat gamma_correction;
3180 x = ((double) i / 255.0);
3181 gamma_correction = 1.0 / gamma;
3182 x = pow (x, (
double) gamma_correction);
3188 red_table [i] = (int)g;
3189 green_table [i] = (int)g;
3190 blue_table [i] = (int)g;
3199void GraphicsStateGuardian::
3200reissue_transforms() {
3208void GraphicsStateGuardian::
3209enable_lighting(
bool enable) {
3217void GraphicsStateGuardian::
3218set_ambient_light(
const LColor &color) {
3226void GraphicsStateGuardian::
3227enable_light(
int light_id,
bool enable) {
3238void GraphicsStateGuardian::
3239begin_bind_lights() {
3248void GraphicsStateGuardian::
3257void GraphicsStateGuardian::
3258enable_clip_planes(
bool enable) {
3266void GraphicsStateGuardian::
3267enable_clip_plane(
int plane_id,
bool enable) {
3278void GraphicsStateGuardian::
3279begin_bind_clip_planes() {
3287void GraphicsStateGuardian::
3288bind_clip_plane(
const NodePath &plane,
int plane_id) {
3297void GraphicsStateGuardian::
3298end_bind_clip_planes() {
3304void GraphicsStateGuardian::
3305determine_target_texture() {
3307 _target_rs->get_attrib_def(TextureAttrib::get_class_slot());
3309 _target_rs->get_attrib_def(TexGenAttrib::get_class_slot());
3311 nassertv(target_texture !=
nullptr &&
3312 target_tex_gen !=
nullptr);
3313 _target_texture = target_texture;
3314 _target_tex_gen = target_tex_gen;
3316 if (_has_texture_alpha_scale) {
3320 _target_texture = DCAST(
TextureAttrib, _target_texture->add_on_stage(stage, texture));
3321 _target_tex_gen = DCAST(
TexGenAttrib, _target_tex_gen->add_stage
3322 (stage, TexGenAttrib::M_constant, LTexCoord3(_current_color_scale[3], 0.0f, 0.0f)));
3326 _target_texture = _target_texture->filter_to_max(max_texture_stages);
3327 nassertv(_target_texture->get_num_on_stages() <= max_texture_stages);
3333void GraphicsStateGuardian::
3334determine_target_shader() {
3335 if (_target_rs->_generated_shader !=
nullptr) {
3336 _target_shader = (
const ShaderAttrib *)_target_rs->_generated_shader.p();
3339 _target_rs->get_attrib_def(ShaderAttrib::get_class_slot());
3346void GraphicsStateGuardian::
3355void GraphicsStateGuardian::
3362 _closing_gsg =
true;
3364 if (display_cat.is_debug()) {
3366 <<
this <<
" close_gsg " << get_type() <<
"\n";
3380 _prepared_objects.clear();
3382 _pending_timer_queries.clear();
3393void GraphicsStateGuardian::
3397 <<
"Deactivating " << get_type() <<
".\n";
3399 throw_event(
"panic-deactivate-gsg",
this);
3408void GraphicsStateGuardian::
3409determine_light_color_scale() {
3410 if (_has_scene_graph_color) {
3414 _has_material_force_color =
true;
3415 _material_force_color = _scene_graph_color;
3416 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3417 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3418 _material_force_color.set(_scene_graph_color[0] * _current_color_scale[0],
3419 _scene_graph_color[1] * _current_color_scale[1],
3420 _scene_graph_color[2] * _current_color_scale[2],
3421 _scene_graph_color[3] * _current_color_scale[3]);
3424 }
else if (!_vertex_colors_enabled) {
3428 _has_material_force_color =
true;
3429 _material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
3430 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3431 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3432 _material_force_color.componentwise_mult(_current_color_scale);
3438 _has_material_force_color =
false;
3439 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3440 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3441 _light_color_scale = _current_color_scale;
3452 if (state ==
nullptr) {
3453 state = RenderState::make(LightAttrib::make_all_off());
3462get_unclipped_state() {
3464 if (state ==
nullptr) {
3465 state = RenderState::make(ClipPlaneAttrib::make_all_off());
3474get_untextured_state() {
3476 if (state ==
nullptr) {
3477 state = RenderState::make(TextureAttrib::make_off());
3491 nassertr(_loader !=
nullptr,
nullptr);
3494 if (_current_display_region !=
nullptr) {
3495 priority = _current_display_region->get_texture_reload_priority();
3498 string task_name = string(
"reload:") + tc->
get_texture()->get_name();
3504 for (
size_t ti = 0; ti < num_tasks; ++ti) {
3506 if (task->
is_exact_type(TextureReloadRequest::get_class_type()) &&
3519 _supports_compressed_texture);
3520 request->set_priority(priority);
3521 _loader->load_async(request);
3530PT(
Texture) GraphicsStateGuardian::
3533 bool is_point = node->
is_of_type(PointLight::get_class_type());
3534 nassertr(node->
is_of_type(DirectionalLight::get_class_type()) ||
3535 node->
is_of_type(Spotlight::get_class_type()) ||
3539 if (light ==
nullptr || !light->_shadow_caster) {
3542 if (node->
is_of_type(PointLight::get_class_type())) {
3543 return get_dummy_shadow_map(Texture::TT_cube_map);
3545 return get_dummy_shadow_map(Texture::TT_2d_texture);
3550 nassertr(light->_shadow_map !=
nullptr,
nullptr);
3553 if (light->_sbuffers.count(
this) != 0) {
3555 return light->_shadow_map;
3558 if (display_cat.is_debug()) {
3560 <<
"Constructing shadow buffer for light '" << light->get_name()
3561 <<
"', size=" << light->_sb_size[0] <<
"x" << light->_sb_size[1]
3562 <<
", sort=" << light->_sb_sort <<
"\n";
3565 if (host ==
nullptr) {
3566 nassertr(_current_display_region !=
nullptr,
nullptr);
3567 host = _current_display_region->get_window();
3569 nassertr(host !=
nullptr,
nullptr);
3572 GraphicsOutput *sbuffer = make_shadow_buffer(light, light->_shadow_map,
3577 for (
int i = 0; i < 6; ++i) {
3580 dr->set_target_tex_page(i);
3581 dr->set_camera(light_np);
3582 dr->set_clear_depth_active(
true);
3587 dr->set_clear_depth_active(
true);
3590 light->_sbuffers[
this] = sbuffer;
3591 return light->_shadow_map;
3598PT(
Texture) GraphicsStateGuardian::
3599get_dummy_shadow_map(Texture::TextureType texture_type)
const {
3600 if (texture_type != Texture::TT_cube_map) {
3602 if (dummy_2d ==
nullptr) {
3603 dummy_2d =
new Texture(
"dummy-shadow-2d");
3604 dummy_2d->setup_2d_texture(1, 1, Texture::T_unsigned_byte, Texture::F_depth_component);
3605 dummy_2d->set_clear_color(1);
3608 dummy_2d->set_minfilter(SamplerState::FT_shadow);
3609 dummy_2d->set_magfilter(SamplerState::FT_shadow);
3611 dummy_2d->set_minfilter(SamplerState::FT_linear);
3612 dummy_2d->set_magfilter(SamplerState::FT_linear);
3617 static PT(
Texture) dummy_cube;
3618 if (dummy_cube ==
nullptr) {
3619 dummy_cube =
new Texture(
"dummy-shadow-cube");
3620 dummy_cube->setup_cube_map(1, Texture::T_unsigned_byte, Texture::F_depth_component);
3621 dummy_cube->set_clear_color(1);
3626 dummy_cube->set_minfilter(SamplerState::FT_shadow);
3627 dummy_cube->set_magfilter(SamplerState::FT_shadow);
3629 dummy_cube->set_minfilter(SamplerState::FT_linear);
3630 dummy_cube->set_magfilter(SamplerState::FT_linear);
3643 bool is_point = light->
is_of_type(PointLight::get_class_type());
3647 fbp.set_depth_bits(shadow_depth_bits);
3650 int flags = GraphicsPipe::BF_refuse_window;
3652 flags |= GraphicsPipe::BF_size_square;
3659 light->get_name(), light->_sb_sort, fbp, props, flags,
this, host);
3661 if (sbuffer !=
nullptr) {
3662 sbuffer->
add_render_texture(tex, GraphicsOutput::RTM_bind_or_copy, GraphicsOutput::RTP_depth);
3675 state->get_attrib_def(shader_attrib);
3678 if (_shader_generator ==
nullptr) {
3679 if (!_supports_basic_shaders) {
3682 _shader_generator =
new ShaderGenerator(_shader_caps, _supports_shadow_filter);
3684 if (state->_generated_shader ==
nullptr ||
3685 state->_generated_shader_seq != _generated_shader_seq) {
3691 state->get_attrib_def(sattr);
3692 if (sattr->get_flag(ShaderAttrib::F_hardware_skinning)) {
3697 state->_generated_shader = _shader_generator->synthesize_shader(state, spec);
3698 state->_generated_shader_seq = _generated_shader_seq;
3775operator << (std::ostream &out, GraphicsStateGuardian::ShaderModel sm) {
3776 static const char *sm_strings[] = {
"none",
"1.1",
"2.0",
"2.x",
"3.0",
"4.0",
"5.0",
"5.1"};
3777 nassertr(sm >= 0 && sm <= GraphicsStateGuardian::SM_51, out);
3778 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.