66 PStatCollector GraphicsStateGuardian::_vertex_buffer_switch_pcollector(
"Buffer switch:Vertex");
67 PStatCollector GraphicsStateGuardian::_index_buffer_switch_pcollector(
"Buffer switch:Index");
68 PStatCollector GraphicsStateGuardian::_shader_buffer_switch_pcollector(
"Buffer switch:Shader");
69 PStatCollector GraphicsStateGuardian::_load_vertex_buffer_pcollector(
"Draw:Transfer data:Vertex buffer");
70 PStatCollector GraphicsStateGuardian::_load_index_buffer_pcollector(
"Draw:Transfer data:Index buffer");
71 PStatCollector GraphicsStateGuardian::_load_shader_buffer_pcollector(
"Draw:Transfer data:Shader buffer");
72 PStatCollector GraphicsStateGuardian::_create_vertex_buffer_pcollector(
"Draw:Transfer data:Create Vertex buffer");
73 PStatCollector GraphicsStateGuardian::_create_index_buffer_pcollector(
"Draw:Transfer data:Create Index buffer");
74 PStatCollector GraphicsStateGuardian::_create_shader_buffer_pcollector(
"Draw:Transfer data:Create Shader buffer");
75 PStatCollector GraphicsStateGuardian::_load_texture_pcollector(
"Draw:Transfer data:Texture");
76 PStatCollector GraphicsStateGuardian::_data_transferred_pcollector(
"Data transferred");
77 PStatCollector GraphicsStateGuardian::_texmgrmem_total_pcollector(
"Texture manager");
78 PStatCollector GraphicsStateGuardian::_texmgrmem_resident_pcollector(
"Texture manager:Resident");
79 PStatCollector GraphicsStateGuardian::_primitive_batches_pcollector(
"Primitive batches");
80 PStatCollector GraphicsStateGuardian::_primitive_batches_tristrip_pcollector(
"Primitive batches:Triangle strips");
81 PStatCollector GraphicsStateGuardian::_primitive_batches_trifan_pcollector(
"Primitive batches:Triangle fans");
82 PStatCollector GraphicsStateGuardian::_primitive_batches_tri_pcollector(
"Primitive batches:Triangles");
83 PStatCollector GraphicsStateGuardian::_primitive_batches_patch_pcollector(
"Primitive batches:Patches");
84 PStatCollector GraphicsStateGuardian::_primitive_batches_other_pcollector(
"Primitive batches:Other");
85 PStatCollector GraphicsStateGuardian::_vertices_tristrip_pcollector(
"Vertices:Triangle strips");
86 PStatCollector GraphicsStateGuardian::_vertices_trifan_pcollector(
"Vertices:Triangle fans");
87 PStatCollector GraphicsStateGuardian::_vertices_tri_pcollector(
"Vertices:Triangles");
88 PStatCollector GraphicsStateGuardian::_vertices_patch_pcollector(
"Vertices:Patches");
89 PStatCollector GraphicsStateGuardian::_vertices_other_pcollector(
"Vertices:Other");
90 PStatCollector GraphicsStateGuardian::_state_pcollector(
"State changes");
91 PStatCollector GraphicsStateGuardian::_transform_state_pcollector(
"State changes:Transforms");
92 PStatCollector GraphicsStateGuardian::_texture_state_pcollector(
"State changes:Textures");
93 PStatCollector GraphicsStateGuardian::_draw_primitive_pcollector(
"Draw:Primitive:Draw");
94 PStatCollector GraphicsStateGuardian::_draw_set_state_pcollector(
"Draw:Set State");
95 PStatCollector GraphicsStateGuardian::_flush_pcollector(
"Draw:Flush");
96 PStatCollector GraphicsStateGuardian::_compute_dispatch_pcollector(
"Draw:Compute dispatch");
98 PStatCollector GraphicsStateGuardian::_wait_occlusion_pcollector(
"Wait:Occlusion");
99 PStatCollector GraphicsStateGuardian::_wait_timer_pcollector(
"Wait:Timer Queries");
100 PStatCollector GraphicsStateGuardian::_timer_queries_pcollector(
"Timer queries");
101 PStatCollector GraphicsStateGuardian::_command_latency_pcollector(
"Command latency");
103 PStatCollector GraphicsStateGuardian::_prepare_pcollector(
"Draw:Prepare");
104 PStatCollector GraphicsStateGuardian::_prepare_texture_pcollector(
"Draw:Prepare:Texture");
105 PStatCollector GraphicsStateGuardian::_prepare_sampler_pcollector(
"Draw:Prepare:Sampler");
106 PStatCollector GraphicsStateGuardian::_prepare_geom_pcollector(
"Draw:Prepare:Geom");
107 PStatCollector GraphicsStateGuardian::_prepare_shader_pcollector(
"Draw:Prepare:Shader");
108 PStatCollector GraphicsStateGuardian::_prepare_vertex_buffer_pcollector(
"Draw:Prepare:Vertex buffer");
109 PStatCollector GraphicsStateGuardian::_prepare_index_buffer_pcollector(
"Draw:Prepare:Index buffer");
110 PStatCollector GraphicsStateGuardian::_prepare_shader_buffer_pcollector(
"Draw:Prepare:Shader buffer");
112 PStatCollector GraphicsStateGuardian::_draw_set_state_transform_pcollector(
"Draw:Set State:Transform");
113 PStatCollector GraphicsStateGuardian::_draw_set_state_alpha_test_pcollector(
"Draw:Set State:Alpha test");
114 PStatCollector GraphicsStateGuardian::_draw_set_state_antialias_pcollector(
"Draw:Set State:Antialias");
115 PStatCollector GraphicsStateGuardian::_draw_set_state_clip_plane_pcollector(
"Draw:Set State:Clip plane");
116 PStatCollector GraphicsStateGuardian::_draw_set_state_color_pcollector(
"Draw:Set State:Color");
117 PStatCollector GraphicsStateGuardian::_draw_set_state_cull_face_pcollector(
"Draw:Set State:Cull face");
118 PStatCollector GraphicsStateGuardian::_draw_set_state_depth_offset_pcollector(
"Draw:Set State:Depth offset");
119 PStatCollector GraphicsStateGuardian::_draw_set_state_depth_test_pcollector(
"Draw:Set State:Depth test");
120 PStatCollector GraphicsStateGuardian::_draw_set_state_depth_write_pcollector(
"Draw:Set State:Depth write");
121 PStatCollector GraphicsStateGuardian::_draw_set_state_render_mode_pcollector(
"Draw:Set State:Render mode");
122 PStatCollector GraphicsStateGuardian::_draw_set_state_rescale_normal_pcollector(
"Draw:Set State:Rescale normal");
123 PStatCollector GraphicsStateGuardian::_draw_set_state_shade_model_pcollector(
"Draw:Set State:Shade model");
124 PStatCollector GraphicsStateGuardian::_draw_set_state_blending_pcollector(
"Draw:Set State:Blending");
125 PStatCollector GraphicsStateGuardian::_draw_set_state_shader_pcollector(
"Draw:Set State:Shader");
126 PStatCollector GraphicsStateGuardian::_draw_set_state_shader_parameters_pcollector(
"Draw:Set State:Shader Parameters");
127 PStatCollector GraphicsStateGuardian::_draw_set_state_texture_pcollector(
"Draw:Set State:Texture");
128 PStatCollector GraphicsStateGuardian::_draw_set_state_tex_matrix_pcollector(
"Draw:Set State:Tex matrix");
129 PStatCollector GraphicsStateGuardian::_draw_set_state_tex_gen_pcollector(
"Draw:Set State:Tex gen");
130 PStatCollector GraphicsStateGuardian::_draw_set_state_material_pcollector(
"Draw:Set State:Material");
131 PStatCollector GraphicsStateGuardian::_draw_set_state_light_pcollector(
"Draw:Set State:Light");
132 PStatCollector GraphicsStateGuardian::_draw_set_state_stencil_pcollector(
"Draw:Set State:Stencil");
133 PStatCollector GraphicsStateGuardian::_draw_set_state_fog_pcollector(
"Draw:Set State:Fog");
134 PStatCollector GraphicsStateGuardian::_draw_set_state_scissor_pcollector(
"Draw:Set State:Scissor");
136 PT(
TextureStage) GraphicsStateGuardian::_alpha_scale_texture_stage =
nullptr;
138 TypeHandle GraphicsStateGuardian::_type_handle;
144 GraphicsStateGuardian::
145 GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
147 _internal_coordinate_system(internal_coordinate_system),
151 _coordinate_system = CS_invalid;
152 _internal_transform = TransformState::make_identity();
154 if (_internal_coordinate_system == CS_default) {
155 _internal_coordinate_system = get_default_coordinate_system();
158 set_coordinate_system(get_default_coordinate_system());
160 _data_reader =
nullptr;
161 _current_display_region =
nullptr;
162 _current_stereo_channel = Lens::SC_mono;
163 _current_tex_view_offset = 0;
164 _current_lens =
nullptr;
165 _projection_mat = TransformState::make_identity();
166 _projection_mat_inv = TransformState::make_identity();
170 _current_properties =
nullptr;
171 _closing_gsg =
false;
174 _stereo_buffer_mask = ~0;
175 _incomplete_render = allow_incomplete_render;
176 _effective_incomplete_render =
false;
179 _is_hardware =
false;
180 _prefers_triangle_strips =
false;
181 _max_vertices_per_array = INT_MAX;
182 _max_vertices_per_primitive = INT_MAX;
186 _max_texture_stages = 1;
190 _max_texture_dimension = -1;
191 _max_3d_texture_dimension = 0;
192 _max_2d_texture_array_layers = 0;
193 _max_cube_map_dimension = 0;
194 _max_buffer_texture_size = 0;
197 _supports_texture_combine =
false;
198 _supports_texture_saved_result =
false;
199 _supports_texture_dot3 =
false;
201 _supports_3d_texture =
false;
202 _supports_2d_texture_array =
false;
203 _supports_cube_map =
false;
204 _supports_buffer_texture =
false;
205 _supports_cube_map_array =
false;
206 _supports_tex_non_pow2 =
false;
207 _supports_texture_srgb =
false;
208 _supports_compressed_texture =
false;
209 _compressed_texture_formats.clear();
210 _compressed_texture_formats.set_bit(Texture::CM_off);
214 _max_clip_planes = -1;
217 _max_vertex_transforms = 0;
218 _max_vertex_transform_indices = 0;
220 _supports_occlusion_query =
false;
221 _supports_timer_query =
false;
224 _timer_queries_active =
false;
225 _last_query_frame = 0;
226 _last_num_queried = 0;
229 _pstats_gpu_thread = -1;
234 _copy_texture_inverted =
false;
237 _supports_multisample =
false;
238 _supports_generate_mipmap =
false;
239 _supports_depth_texture =
false;
240 _supports_depth_stencil =
false;
241 _supports_shadow_filter =
false;
242 _supports_sampler_objects =
false;
243 _supports_basic_shaders =
false;
244 _supports_geometry_shaders =
false;
245 _supports_tessellation_shaders =
false;
246 _supports_compute_shaders =
false;
247 _supports_glsl =
false;
248 _supports_hlsl =
false;
250 _supports_stencil =
false;
251 _supports_stencil_wrap =
false;
252 _supports_two_sided_stencil =
false;
253 _supports_geometry_instancing =
false;
254 _supports_indirect_draw =
false;
257 _supports_luminance_texture =
true;
260 _max_color_targets = 1;
261 _supports_dual_source_blending =
false;
263 _supported_geom_rendering = 0;
268 _color_scale_via_lighting = color_scale_via_lighting;
271 _alpha_scale_via_texture = alpha_scale_via_texture;
275 _runtime_color_scale =
false;
278 _auto_detect_shader_model = SM_00;
279 _shader_model = SM_00;
282 _texture_quality_override = Texture::QL_default;
286 static size_t next_index = 0;
293 GraphicsStateGuardian::
294 ~GraphicsStateGuardian() {
305 for (
size_t si = 0; si < size; ++si) {
307 state->_mungers.
remove(_id);
308 state->_munged_states.
remove(_id);
319 nassertr(_engine !=
nullptr, GraphicsEngine::get_global_ptr());
334 return _supports_multisample;
348 return _supported_geom_rendering;
371 if (cs == CS_default) {
372 cs = get_default_coordinate_system();
374 if (_coordinate_system == cs) {
377 _coordinate_system = cs;
380 if (_internal_coordinate_system == CS_default ||
381 _internal_coordinate_system == _coordinate_system) {
382 _cs_transform = TransformState::make_identity();
383 _inv_cs_transform = TransformState::make_identity();
387 TransformState::make_mat
388 (LMatrix4::convert_mat(_coordinate_system,
389 _internal_coordinate_system));
391 TransformState::make_mat
392 (LMatrix4::convert_mat(_internal_coordinate_system,
393 _coordinate_system));
408 return _internal_coordinate_system;
417 return _prepared_objects;
451 void *callback_arg) {
453 PreparedGraphicsObjects::Textures::const_iterator ti;
454 for (ti = _prepared_objects->_prepared_textures.begin();
455 ti != _prepared_objects->_prepared_textures.end();
457 bool result = (*func)(*ti, callback_arg);
484 _flash_texture = tex;
495 _flash_texture =
nullptr;
506 return _flash_texture;
520 _scene_setup = scene_setup;
521 _current_lens = scene_setup->
get_lens();
522 if (_current_lens ==
nullptr) {
528 _projection_mat = calc_projection_mat(_current_lens);
529 if (_projection_mat ==
nullptr) {
532 _projection_mat_inv = _projection_mat->get_inverse();
716 nassertv(_current_occlusion_query ==
nullptr);
726 end_occlusion_query() {
727 nassertr(_current_occlusion_query !=
nullptr,
nullptr);
729 _current_occlusion_query =
nullptr;
738 issue_timer_query(
int pstats_index) {
748 nassert_raise(
"Compute shaders not supported by GSG");
764 int mi = state->_last_mi;
767 if (munger->is_registered()) {
773 mi = mungers.
find(_id);
776 if (munger->is_registered()) {
777 state->_last_mi = mi;
787 PT(
GeomMunger) munger = make_geom_munger(state, current_thread);
788 nassertr(munger !=
nullptr && munger->is_registered(), munger);
789 nassertr(munger->is_of_type(StateMunger::get_class_type()), munger);
791 state->_last_mi = mungers.
store(_id, munger);
814 switch (_internal_coordinate_system) {
829 <<
"Invalid coordinate system in compute_distance_to: "
830 << (int)_internal_coordinate_system <<
"\n";
864 if (altered & spec._dep[0]) {
865 const LMatrix4 *t =
fetch_specified_part(spec._part[0], spec._arg[0], spec._cache[0], spec._index);
866 if (t != &spec._cache[0]) {
870 if (altered & spec._dep[1]) {
871 const LMatrix4 *t =
fetch_specified_part(spec._part[1], spec._arg[1], spec._cache[1], spec._index);
872 if (t != &spec._cache[1]) {
878 case Shader::SMF_compose:
879 spec._value.multiply(spec._cache[0], spec._cache[1]);
881 case Shader::SMF_transform_dlight:
882 spec._value = spec._cache[0];
883 v = spec._cache[1].xform_vec(spec._cache[0].get_row3(2));
885 spec._value.set_row(2, v);
886 v = spec._cache[1].xform_vec(spec._cache[0].get_row3(3));
888 spec._value.set_row(3, v);
890 case Shader::SMF_transform_plight:
893 spec._value = spec._cache[0];
894 LPoint3 point = spec._cache[1].xform_point(spec._cache[0].get_row3(2));
895 spec._value(2, 0) = point[0];
896 spec._value(2, 1) = point[1];
897 spec._value(2, 2) = point[2];
900 case Shader::SMF_transform_slight:
901 spec._value = spec._cache[0];
902 spec._value.set_row(2, spec._cache[1].xform_point(spec._cache[0].get_row3(2)));
903 v = spec._cache[1].xform_vec(spec._cache[0].get_row3(3));
905 spec._value.set_row(3, v);
907 case Shader::SMF_first:
908 return &spec._cache[0];
911 spec._value = LMatrix4::ident_mat();
921 LMatrix4 &t,
int index) {
923 case Shader::SMO_identity: {
924 return &LMatrix4::ident_mat();
926 case Shader::SMO_window_size:
927 case Shader::SMO_pixel_size: {
928 LVecBase2i pixel_size = _current_display_region->get_pixel_size();
929 t = LMatrix4::translate_mat(pixel_size[0], pixel_size[1], 0);
932 case Shader::SMO_frame_time: {
934 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time);
937 case Shader::SMO_frame_delta: {
939 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt);
942 case Shader::SMO_texpad_x: {
943 Texture *tex = _target_shader->get_shader_input_texture(name);
944 nassertr(tex !=
nullptr, &LMatrix4::zeros_mat());
951 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cx, cy, cz, 0);
954 case Shader::SMO_texpix_x: {
955 Texture *tex = _target_shader->get_shader_input_texture(name);
956 nassertr(tex !=
nullptr, &LMatrix4::zeros_mat());
960 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, px, py, pz, 0);
963 case Shader::SMO_attr_material: {
965 _target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
967 if (target_material->
is_off()) {
968 t.set(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0);
977 t.set(amb[0], amb[1], amb[2], amb[3],
978 dif[0], dif[1], dif[2], dif[3],
979 emm[0], emm[1], emm[2], emm[3],
980 spc[0], spc[1], spc[2], spc[3]);
983 case Shader::SMO_attr_material2: {
985 _target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
986 if (target_material->
is_off()) {
987 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
995 case Shader::SMO_attr_color: {
997 _target_rs->get_attrib_def(ColorAttrib::get_class_slot());
999 return &LMatrix4::ones_mat();
1001 LVecBase4 c = target_color->
get_color();
1002 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
1005 case Shader::SMO_attr_colorscale: {
1007 _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot());
1009 return &LMatrix4::ones_mat();
1011 LVecBase4 cs = target_color->
get_scale();
1012 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cs[0], cs[1], cs[2], cs[3]);
1015 case Shader::SMO_attr_fog: {
1017 _target_rs->get_attrib_def(FogAttrib::get_class_slot());
1019 if (fog ==
nullptr) {
1020 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1);
1023 PN_stdfloat start, end;
1025 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1029 case Shader::SMO_attr_fogcolor: {
1031 _target_rs->get_attrib_def(FogAttrib::get_class_slot());
1033 if (fog ==
nullptr) {
1034 return &LMatrix4::ones_mat();
1037 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
1040 case Shader::SMO_alight_x: {
1041 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1042 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1044 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1046 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
1049 case Shader::SMO_satten_x: {
1050 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1051 nassertr(!np.
is_empty(), &LMatrix4::ones_mat());
1053 DCAST_INTO_R(lt, np.
node(), &LMatrix4::ones_mat());
1056 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a[0], a[1], a[2], x);
1059 case Shader::SMO_dlight_x: {
1061 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1062 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1064 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1067 t = np.get_net_transform()->
get_mat() *
1068 _scene_setup->get_world_transform()->get_mat();
1071 LVecBase3 h = d + LVecBase3(0,-1,0);
1073 t.set(c[0], c[1], c[2], c[3],
1074 s[0], s[1], s[2], c[3],
1075 d[0], d[1], d[2], 0,
1076 h[0], h[1], h[2], 0);
1079 case Shader::SMO_plight_x: {
1081 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1082 nassertr(!np.
is_empty(), &LMatrix4::ones_mat());
1084 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1087 t = np.get_net_transform()->
get_mat() *
1088 _scene_setup->get_world_transform()->get_mat();
1089 LVecBase3 p = (t.xform_point(lt->
get_point()));
1092 PN_stdfloat lnear = lens->
get_near();
1093 PN_stdfloat lfar = lens->
get_far();
1094 t.set(c[0], c[1], c[2], c[3],
1095 s[0], s[1], s[2], s[3],
1096 p[0], p[1], p[2], lnear,
1097 a[0], a[1], a[2], lfar);
1100 case Shader::SMO_slight_x: {
1102 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1103 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1105 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1107 nassertr(lens !=
nullptr, &LMatrix4::zeros_mat());
1110 PN_stdfloat cutoff = ccos(deg_2_rad(lens->
get_hfov() * 0.5f));
1111 t = np.get_net_transform()->
get_mat() *
1112 _scene_setup->get_world_transform()->get_mat();
1115 t.set(c[0], c[1], c[2], c[3],
1116 s[0], s[1], s[2], s[3],
1117 p[0], p[1], p[2], 0,
1118 d[0], d[1], d[2], cutoff);
1121 case Shader::SMO_light_ambient: {
1122 LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
1124 _target_rs->get_attrib_def(LightAttrib::get_class_slot());
1129 t.set_row(3, LVecBase4(1, 1, 1, 1));
1131 t.set_row(3, target_light->get_ambient_contribution());
1135 case Shader::SMO_texmat_i: {
1138 if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
1142 return &LMatrix4::ident_mat();
1145 case Shader::SMO_inv_texmat_i: {
1148 if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
1149 index < ta->get_num_on_stages()) {
1150 t = tma->get_transform(ta->
get_on_stage(index))->get_inverse()->get_mat();
1153 return &LMatrix4::ident_mat();
1156 case Shader::SMO_texscale_i: {
1159 if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
1160 index < ta->get_num_on_stages()) {
1161 LVecBase3 scale = tma->get_transform(ta->
get_on_stage(index))->get_scale();
1162 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, scale[0], scale[1], scale[2], 0);
1165 return &LMatrix4::ident_mat();
1168 case Shader::SMO_texcolor_i: {
1170 if (_target_rs->get_attrib(ta) && index < ta->get_num_on_stages()) {
1175 return &LMatrix4::zeros_mat();
1178 case Shader::SMO_tex_is_alpha_i: {
1182 if (_target_rs->get_attrib(ta) &&
1183 index < ta->get_num_on_stages()) {
1185 PN_stdfloat v = (ta->
get_on_texture(ts)->get_format() == Texture::F_alpha);
1186 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v, v, v, 0);
1189 return &LMatrix4::zeros_mat();
1192 case Shader::SMO_plane_x: {
1193 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1194 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1196 DCAST_INTO_R(plane_node, np.
node(), &LMatrix4::zeros_mat());
1198 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, p[0], p[1], p[2], p[3]);
1201 case Shader::SMO_clipplane_x: {
1203 _target_rs->get_attrib_def(cpa);
1204 int planenr = atoi(name->
get_name().c_str());
1206 return &LMatrix4::zeros_mat();
1209 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1211 DCAST_INTO_R(plane_node, np.
node(), &LMatrix4::zeros_mat());
1216 if (!transform->is_identity()) {
1217 plane.xform(transform->get_mat());
1219 t.set_row(3, plane);
1222 case Shader::SMO_apiview_clipplane_i: {
1224 _target_rs->get_attrib_def(cpa);
1226 return &LMatrix4::zeros_mat();
1230 nassertr(!plane.
is_empty(), &LMatrix4::zeros_mat());
1232 DCAST_INTO_R(plane_node, plane.
node(), &LMatrix4::zeros_mat());
1235 _scene_setup->get_cs_world_transform()->compose(
1236 plane.
get_transform(_scene_setup->get_scene_root().get_parent()));
1238 LPlane xformed_plane = plane_node->
get_plane() * transform->get_mat();
1239 t.set_row(3, xformed_plane);
1242 case Shader::SMO_mat_constant_x: {
1243 return &_target_shader->get_shader_input_matrix(name, t);
1245 case Shader::SMO_vec_constant_x: {
1246 const LVecBase4 &input = _target_shader->get_shader_input_vector(name);
1247 const PN_stdfloat *data = input.get_data();
1248 t.set(data[0], data[1], data[2], data[3],
1249 data[0], data[1], data[2], data[3],
1250 data[0], data[1], data[2], data[3],
1251 data[0], data[1], data[2], data[3]);
1254 case Shader::SMO_world_to_view: {
1255 return &(_scene_setup->get_world_transform()->get_mat());
1257 case Shader::SMO_view_to_world: {
1258 return &(_scene_setup->get_camera_transform()->get_mat());
1260 case Shader::SMO_model_to_view: {
1261 t = _inv_cs_transform->compose(_internal_transform)->get_mat();
1264 case Shader::SMO_model_to_apiview: {
1265 return &(_internal_transform->get_mat());
1267 case Shader::SMO_view_to_model: {
1268 t = _internal_transform->invert_compose(_cs_transform)->get_mat();
1271 case Shader::SMO_apiview_to_model: {
1272 t = _internal_transform->get_inverse()->get_mat();
1275 case Shader::SMO_apiview_to_view: {
1276 return &(_inv_cs_transform->get_mat());
1278 case Shader::SMO_view_to_apiview: {
1279 return &(_cs_transform->get_mat());
1281 case Shader::SMO_clip_to_view: {
1282 if (_current_lens->get_coordinate_system() == _coordinate_system) {
1283 return &(_current_lens->get_projection_mat_inv(_current_stereo_channel));
1285 t = _current_lens->get_projection_mat_inv(_current_stereo_channel) *
1286 LMatrix4::convert_mat(_current_lens->get_coordinate_system(), _coordinate_system);
1290 case Shader::SMO_view_to_clip: {
1291 if (_current_lens->get_coordinate_system() == _coordinate_system) {
1292 return &(_current_lens->get_projection_mat(_current_stereo_channel));
1294 t = LMatrix4::convert_mat(_coordinate_system, _current_lens->get_coordinate_system()) *
1295 _current_lens->get_projection_mat(_current_stereo_channel);
1299 case Shader::SMO_apiclip_to_view: {
1300 t = _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat();
1303 case Shader::SMO_view_to_apiclip: {
1304 t = _cs_transform->get_mat() * _projection_mat->get_mat();
1307 case Shader::SMO_apiclip_to_apiview: {
1308 return &(_projection_mat_inv->get_mat());
1310 case Shader::SMO_apiview_to_apiclip: {
1311 return &(_projection_mat->get_mat());
1313 case Shader::SMO_view_x_to_view: {
1314 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1315 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1316 t = np.get_net_transform()->
get_mat() *
1317 _scene_setup->get_world_transform()->get_mat();
1320 case Shader::SMO_view_to_view_x: {
1321 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1322 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1323 t = _scene_setup->get_camera_transform()->get_mat() *
1324 np.get_net_transform()->get_inverse()->
get_mat();
1327 case Shader::SMO_apiview_x_to_view: {
1328 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1329 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1330 t = LMatrix4::convert_mat(_internal_coordinate_system, _coordinate_system) *
1331 np.get_net_transform()->
get_mat() *
1332 _scene_setup->get_world_transform()->get_mat();
1335 case Shader::SMO_view_to_apiview_x: {
1336 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1337 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1338 t = (_scene_setup->get_camera_transform()->get_mat() *
1339 np.get_net_transform()->get_inverse()->
get_mat() *
1340 LMatrix4::convert_mat(_coordinate_system, _internal_coordinate_system));
1343 case Shader::SMO_clip_x_to_view: {
1344 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1345 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1347 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1351 np.get_net_transform()->
get_mat() *
1352 _scene_setup->get_world_transform()->get_mat();
1355 case Shader::SMO_view_to_clip_x: {
1356 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1357 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1359 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1361 t = _scene_setup->get_camera_transform()->get_mat() *
1362 np.get_net_transform()->get_inverse()->
get_mat() *
1367 case Shader::SMO_apiclip_x_to_view: {
1368 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1369 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1371 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1373 t = calc_projection_mat(lens)->get_inverse()->get_mat() *
1375 np.get_net_transform()->
get_mat() *
1376 _scene_setup->get_world_transform()->get_mat();
1379 case Shader::SMO_view_to_apiclip_x: {
1380 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1381 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1383 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1385 t = _scene_setup->get_camera_transform()->get_mat() *
1386 np.get_net_transform()->get_inverse()->
get_mat() *
1388 calc_projection_mat(lens)->get_mat();
1391 case Shader::SMO_mat_constant_x_attrib: {
1392 if (_target_shader->has_shader_input(name)) {
1395 return &_target_shader->get_shader_input_matrix(name, t);
1399 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1403 case Shader::SMO_vec_constant_x_attrib: {
1404 if (_target_shader->has_shader_input(name)) {
1407 const LVecBase4 &data = _target_shader->get_shader_input_vector(name);
1408 t.set(data[0], data[1], data[2], data[3],
1409 data[0], data[1], data[2], data[3],
1410 data[0], data[1], data[2], data[3],
1411 data[0], data[1], data[2], data[3]);
1416 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1420 case Shader::SMO_light_source_i_attrib: {
1422 _target_rs->get_attrib_def(target_light);
1427 if (index >= 0 && (
size_t)index < num_lights) {
1429 nassertr(!light.
is_empty(), &LMatrix4::ident_mat());
1431 nassertr(light_obj !=
nullptr, &LMatrix4::ident_mat());
1435 }
else if (index == 0) {
1439 return &LMatrix4::ones_mat();
1443 case Shader::SMO_light_source_i_packed: {
1446 _target_rs->get_attrib_def(target_light);
1451 if (index >= 0 && (
size_t)index < num_lights) {
1453 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1456 nassertr(light !=
nullptr, &LMatrix4::zeros_mat());
1460 LMatrix4 mat = np.get_net_transform()->
get_mat() *
1461 _scene_setup->get_world_transform()->get_mat();
1463 if (node->
is_of_type(DirectionalLight::get_class_type())) {
1464 LVecBase3 d = mat.xform_vec(((
const DirectionalLight *)node)->get_direction());
1466 t.set_row(2, LVecBase4(d, 0));
1467 t.set_row(3, LVecBase4(-d, 0));
1469 }
else if (node->
is_of_type(LightLensNode::get_class_type())) {
1473 t.set_row(3, LVecBase4(p));
1477 if (node->
is_of_type(Spotlight::get_class_type())) {
1478 PN_stdfloat cutoff = ccos(deg_2_rad(lens->
get_hfov() * 0.5f));
1480 t.set_cell(1, 3, ((
const Spotlight *)node)->get_exponent());
1481 t.set_row(2, LVecBase4(d, cutoff));
1483 }
else if (node->
is_of_type(PointLight::get_class_type())) {
1484 t.set_cell(1, 3, lens->
get_far());
1485 t.set_cell(3, 3, lens->
get_near());
1487 if (node->
is_of_type(SphereLight::get_class_type())) {
1488 t.set_cell(2, 3, ((
const SphereLight *)node)->get_radius());
1492 }
else if (index == 0) {
1495 t.set_row(0, LVecBase4(1, 1, 1, 1));
1500 nassertr(
false , &LMatrix4::ident_mat());
1501 return &LMatrix4::ident_mat();
1523 static const CPT_InternalName IN_constantAttenuation(
"constantAttenuation");
1525 static const CPT_InternalName IN_quadraticAttenuation(
"quadraticAttenuation");
1533 if (attrib == IN_color) {
1534 if (node ==
nullptr) {
1535 return &LMatrix4::ident_mat();
1538 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1543 }
else if (attrib == IN_ambient) {
1544 if (node ==
nullptr) {
1545 return &LMatrix4::ident_mat();
1548 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1554 t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
1558 }
else if (attrib == IN_diffuse) {
1559 if (node ==
nullptr) {
1560 return &LMatrix4::ident_mat();
1563 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1566 t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
1573 }
else if (attrib == IN_specular) {
1574 if (node ==
nullptr) {
1575 return &LMatrix4::ident_mat();
1578 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1582 }
else if (attrib == IN_position) {
1584 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
1588 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1590 }
else if (node->
is_of_type(DirectionalLight::get_class_type())) {
1592 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1595 LVector3 dir = -(light->
get_direction() * transform->get_mat());
1596 dir *= _scene_setup->get_cs_world_transform()->
get_mat();
1597 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 0);
1601 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1603 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1606 _scene_setup->get_cs_world_transform()->compose(
1607 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1609 const LMatrix4 &light_mat = transform->get_mat();
1611 t = LMatrix4::translate_mat(pos);
1615 }
else if (attrib == IN_halfVector) {
1617 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
1621 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1623 }
else if (node->
is_of_type(DirectionalLight::get_class_type())) {
1625 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1628 LVector3 dir = -(light->
get_direction() * transform->get_mat());
1629 dir *= _scene_setup->get_cs_world_transform()->
get_mat();
1631 dir += LVector3(0, 0, 1);
1633 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 1);
1637 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1639 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1642 _scene_setup->get_cs_world_transform()->compose(
1643 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1645 const LMatrix4 &light_mat = transform->get_mat();
1648 pos += LVector3(0, 0, 1);
1650 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pos[0],pos[1],pos[2], 1);
1654 }
else if (attrib == IN_spotDirection) {
1655 if (node ==
nullptr) {
1656 t.set_row(3, LVector3(0.0f, 0.0f, -1.0f));
1660 t.set_row(3, LVector3(0.0f, 0.0f, 0.0f));
1664 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1666 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1669 _scene_setup->get_cs_world_transform()->compose(
1670 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1672 const LMatrix4 &light_mat = transform->get_mat();
1678 }
else if (attrib == IN_spotCutoff) {
1679 if (node !=
nullptr &&
1680 node->
is_of_type(Spotlight::get_class_type())) {
1682 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1684 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1686 float cutoff = lens->
get_hfov() * 0.5f;
1687 t.set_row(3, LVecBase4(cutoff));
1691 t.set_row(3, LVecBase4(180));
1695 }
else if (attrib == IN_spotCosCutoff) {
1696 if (node !=
nullptr &&
1697 node->
is_of_type(Spotlight::get_class_type())) {
1699 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1701 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1703 float cutoff = lens->
get_hfov() * 0.5f;
1704 t.set_row(3, LVecBase4(ccos(deg_2_rad(cutoff))));
1708 t.set_row(3, LVecBase4(-1));
1712 }
else if (attrib == IN_spotExponent) {
1713 if (node ==
nullptr) {
1714 return &LMatrix4::zeros_mat();
1717 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1722 }
else if (attrib == IN_attenuation) {
1723 if (node !=
nullptr) {
1725 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1729 t.set_row(3, LVecBase4(1, 0, 0, 0));
1733 }
else if (attrib == IN_constantAttenuation) {
1734 if (node ==
nullptr) {
1735 return &LMatrix4::ones_mat();
1738 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1743 }
else if (attrib == IN_linearAttenuation) {
1744 if (node ==
nullptr) {
1745 return &LMatrix4::zeros_mat();
1748 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1753 }
else if (attrib == IN_quadraticAttenuation) {
1754 if (node ==
nullptr) {
1755 return &LMatrix4::zeros_mat();
1758 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1763 }
else if (attrib == IN_shadowViewMatrix) {
1764 static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f,
1765 0.0f, 0.5f, 0.0f, 0.0f,
1766 0.0f, 0.0f, 0.5f, 0.0f,
1767 0.5f, 0.5f, 0.5f, 1.0f);
1769 if (node ==
nullptr) {
1774 DCAST_INTO_R(lnode, node, &LMatrix4::ident_mat());
1777 t = _inv_cs_transform->get_mat() *
1778 _scene_setup->get_camera_transform()->get_mat() *
1779 np.get_net_transform()->get_inverse()->
get_mat() *
1782 if (!node->
is_of_type(PointLight::get_class_type())) {
1789 <<
"Shader input requests invalid attribute " << *attrib
1790 <<
" from node " << np <<
"\n";
1791 return &LMatrix4::ident_mat();
1802 static PT(
Texture) default_add_tex;
1803 static PT(
Texture) default_normal_height_tex;
1805 switch (spec._part) {
1806 case Shader::STO_named_input:
1808 if (!_target_shader->has_shader_input(spec._name)) {
1811 if (parent != InternalName::get_root() &&
1812 _target_shader->has_shader_input(parent)) {
1815 const string &basename = spec._name->get_basename();
1816 NodePath np = _target_shader->get_shader_input_nodepath(parent);
1818 if (basename ==
"shadowMap") {
1819 PT(
Texture) tex = get_shadow_map(np);
1820 if (tex !=
nullptr) {
1821 sampler = tex->get_default_sampler();
1826 if (spec._stage == 0) {
1828 <<
"Shader input " << *parent
1829 <<
" has no member named " << basename <<
".\n";
1837 if (spec._stage == 0) {
1839 <<
"Shader input " << *spec._name <<
" is not present.\n";
1845 return _target_shader->get_shader_input_texture(spec._name, &sampler);
1849 case Shader::STO_stage_i:
1854 _target_rs->get_attrib_def(texattrib);
1865 case Shader::STO_light_i_shadow_map:
1868 _target_rs->get_attrib_def(target_light);
1873 if (spec._stage >= 0 && (
size_t)spec._stage < num_lights) {
1875 nassertr(!light.
is_empty(),
nullptr);
1877 nassertr(light_obj !=
nullptr,
nullptr);
1881 if (lln !=
nullptr && lln->_shadow_caster) {
1882 tex = get_shadow_map(light);
1884 tex = get_dummy_shadow_map((Texture::TextureType)spec._desired_type);
1887 if (tex !=
nullptr) {
1888 sampler = tex->get_default_sampler();
1893 PT(
Texture) tex = get_dummy_shadow_map((Texture::TextureType)spec._desired_type);
1894 if (tex !=
nullptr) {
1895 sampler = tex->get_default_sampler();
1902 case Shader::STO_ff_stage_i:
1907 _target_rs->get_attrib_def(texattrib);
1918 case Shader::STO_stage_modulate_i:
1921 if (_target_rs->get_attrib(texattrib)) {
1925 TextureStage::Mode mode = stage->
get_mode();
1927 if (mode == TextureStage::M_modulate ||
1928 mode == TextureStage::M_modulate_glow ||
1929 mode == TextureStage::M_modulate_gloss) {
1930 if (si++ == spec._stage) {
1941 case Shader::STO_stage_add_i:
1944 if (_target_rs->get_attrib(texattrib)) {
1948 TextureStage::Mode mode = stage->
get_mode();
1950 if (mode == TextureStage::M_add) {
1951 if (si++ == spec._stage) {
1960 if (default_add_tex ==
nullptr) {
1962 tex->setup_2d_texture(1, 1, Texture::T_unsigned_byte, Texture::F_luminance);
1963 tex->set_clear_color(LColor(0, 0, 0, 1));
1964 default_add_tex = std::move(tex);
1966 return default_add_tex;
1970 case Shader::STO_stage_normal_i:
1973 if (_target_rs->get_attrib(texattrib)) {
1977 TextureStage::Mode mode = stage->
get_mode();
1979 if (mode == TextureStage::M_normal ||
1980 mode == TextureStage::M_normal_height) {
1981 if (si++ == spec._stage) {
1990 if (default_normal_height_tex ==
nullptr) {
1992 tex->setup_2d_texture(1, 1, Texture::T_unsigned_byte, Texture::F_rgba);
1993 tex->set_clear_color(LColor(0.5, 0.5, 1, 0));
1994 default_normal_height_tex = std::move(tex);
1996 return default_normal_height_tex;
2000 case Shader::STO_stage_gloss_i:
2003 if (_target_rs->get_attrib(texattrib)) {
2007 TextureStage::Mode mode = stage->
get_mode();
2009 if (mode == TextureStage::M_gloss ||
2010 mode == TextureStage::M_modulate_gloss ||
2011 mode == TextureStage::M_normal_gloss) {
2012 if (si++ == spec._stage) {
2023 case Shader::STO_stage_height_i:
2026 if (_target_rs->get_attrib(texattrib)) {
2030 TextureStage::Mode mode = stage->
get_mode();
2032 if (mode == TextureStage::M_height ||
2033 mode == TextureStage::M_normal_height) {
2034 if (si++ == spec._stage) {
2043 if (default_normal_height_tex ==
nullptr) {
2045 tex->setup_2d_texture(1, 1, Texture::T_unsigned_byte, Texture::F_rgba);
2046 tex->set_clear_color(LColor(0.5, 0.5, 1, 0));
2047 default_normal_height_tex = std::move(tex);
2049 return default_normal_height_tex;
2053 case Shader::STO_stage_selector_i:
2056 if (_target_rs->get_attrib(texattrib)) {
2060 TextureStage::Mode mode = stage->
get_mode();
2062 if (mode == TextureStage::M_selector) {
2063 if (si++ == spec._stage) {
2074 case Shader::STO_stage_emission_i:
2077 if (_target_rs->get_attrib(texattrib)) {
2081 TextureStage::Mode mode = stage->
get_mode();
2083 if (mode == TextureStage::M_emission) {
2084 if (si++ == spec._stage) {
2096 nassertr(
false,
nullptr);
2108 return (_target_shader->get_shader_input_ptr(spec._arg));
2117 _current_display_region = dr->get_object();
2120 _effective_incomplete_render = _incomplete_render && _current_display_region->get_incomplete_render();
2122 _stereo_buffer_mask = ~0;
2127 switch (output_channel) {
2129 output_channel = Lens::SC_right;
2132 case Lens::SC_right:
2133 output_channel = Lens::SC_left;
2141 switch (output_channel) {
2144 if (_current_properties->is_stereo()) {
2149 case Lens::SC_right:
2151 if (_current_properties->is_stereo()) {
2157 case Lens::SC_stereo:
2158 _color_write_mask = ColorWriteAttrib::C_all;
2181 reissue_transforms();
2184 _state_rs = RenderState::make_empty();
2185 _state_mask.
clear();
2195 nassertv(_engine !=
nullptr);
2197 DCAST_INTO_V(win, window);
2220 calc_projection_mat(
const Lens *lens) {
2221 if (lens ==
nullptr) {
2229 return TransformState::make_identity();
2242 _prepared_objects->begin_frame(
this, current_thread);
2249 _state_rs = RenderState::make_empty();
2250 _state_mask.
clear();
2256 if (_last_query_frame < frame) {
2257 _last_query_frame = frame;
2258 _timer_queries_pcollector.clear_level();
2265 if (_timer_queries_active) {
2268 issue_timer_query(0x8000);
2269 issue_timer_query(0x0000);
2274 return !_needs_reset;
2305 _scene_setup = _scene_null;
2311 for (i = 0; i < _num_lights_enabled; ++i) {
2312 enable_light(i,
false);
2314 _num_lights_enabled = 0;
2317 for (i = 0; i < _num_clip_planes_enabled; ++i) {
2318 enable_clip_plane(i,
false);
2320 _num_clip_planes_enabled = 0;
2323 _state_rs = RenderState::make_empty();
2324 _state_mask.
clear();
2333 _prepared_objects->end_frame(current_thread);
2336 _data_transferred_pcollector.flush_level();
2338 _primitive_batches_pcollector.flush_level();
2339 _primitive_batches_tristrip_pcollector.flush_level();
2340 _primitive_batches_trifan_pcollector.flush_level();
2341 _primitive_batches_tri_pcollector.flush_level();
2342 _primitive_batches_patch_pcollector.flush_level();
2343 _primitive_batches_other_pcollector.flush_level();
2344 _vertices_tristrip_pcollector.flush_level();
2345 _vertices_trifan_pcollector.flush_level();
2346 _vertices_tri_pcollector.flush_level();
2347 _vertices_patch_pcollector.flush_level();
2348 _vertices_other_pcollector.flush_level();
2350 _state_pcollector.flush_level();
2351 _texture_state_pcollector.flush_level();
2352 _transform_state_pcollector.flush_level();
2353 _draw_primitive_pcollector.flush_level();
2356 _prepared_objects->_graphics_memory_lru.begin_epoch();
2370 PStatClient *client = PStatClient::get_global_pstats();
2372 if (!client->client_is_connected()) {
2373 _timer_queries_active =
false;
2377 if (!_timer_queries_active) {
2378 if (pstats_gpu_timing && _supports_timer_query) {
2380 _timer_queries_active =
true;
2388 if (_pstats_gpu_thread == -1) {
2391 PStatThread gpu_thread(client, _pstats_gpu_thread);
2395 if (!_pending_timer_queries.empty()) {
2396 int count = _pending_timer_queries.size();
2403 if (_last_num_queried > 0) {
2406 int i = std::min(_last_num_queried, count) - 1;
2408 if (_pending_timer_queries[i]->is_answer_ready()) {
2410 while (i < count - 1) {
2411 if (!_pending_timer_queries[++i]->is_answer_ready()) {
2419 if (_pending_timer_queries[--i]->is_answer_ready()) {
2430 int step = count / 2;
2431 int i = first + step;
2432 if (_pending_timer_queries[i]->is_answer_ready()) {
2445 _last_num_queried = first;
2447 for (
int i = 0; i < first; ++i) {
2450 double time_data = query->get_timestamp();
2452 if (query->_pstats_index == _command_latency_pcollector.get_index()) {
2455 cdef = client->get_collector_ptr(query->_pstats_index)->get_def(client, query->_pstats_index);
2456 _pstats_gpu_data.add_level(query->_pstats_index, time_data * cdef->_factor);
2458 }
else if (query->_pstats_index & 0x8000) {
2459 _pstats_gpu_data.add_stop(query->_pstats_index & 0x7fff, time_data);
2462 _pstats_gpu_data.add_start(query->_pstats_index & 0x7fff, time_data);
2468 if (query->_pstats_index == 0x8000) {
2470 _pstats_gpu_data.clear();
2477 _pending_timer_queries.erase(
2478 _pending_timer_queries.begin(),
2479 _pending_timer_queries.begin() + first
2481 _timer_queries_pcollector.add_level_now(first);
2504 begin_decal_base_first() {
2507 if (decal_base_first ==
nullptr) {
2508 decal_base_first = RenderState::make
2509 (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
2510 RenderState::get_max_priority());
2512 return decal_base_first;
2522 begin_decal_nested() {
2526 if (decal_nested ==
nullptr) {
2527 decal_nested = RenderState::make
2528 (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
2529 RenderState::get_max_priority());
2531 return decal_nested;
2545 begin_decal_base_second() {
2550 if (decal_base_second ==
nullptr) {
2551 decal_base_second = RenderState::make
2552 (ColorWriteAttrib::make(ColorWriteAttrib::C_off),
2556 RenderState::get_max_priority());
2558 return decal_base_second;
2578 _data_reader = data_reader;
2582 return _data_reader->has_vertex() || (_target_shader && _target_shader->has_shader());
2681 _data_reader =
nullptr;
2689 _needs_reset =
false;
2692 _state_rs = RenderState::make_empty();
2693 _target_rs =
nullptr;
2694 _state_mask.
clear();
2695 _internal_transform = _cs_transform;
2697 _scene_setup = _scene_null;
2699 _color_write_mask = ColorWriteAttrib::C_all;
2701 _has_scene_graph_color =
false;
2702 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2703 _transform_stale =
true;
2704 _color_blend_involves_color_scale =
false;
2705 _texture_involves_color_scale =
false;
2706 _vertex_colors_enabled =
true;
2707 _lighting_enabled =
false;
2708 _num_lights_enabled = 0;
2709 _num_clip_planes_enabled = 0;
2710 _clip_planes_enabled =
false;
2712 _color_scale_enabled =
false;
2713 _current_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
2714 _has_texture_alpha_scale =
false;
2716 _has_material_force_color =
false;
2717 _material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2718 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
2720 _tex_gen_modifies_mat =
false;
2721 _last_max_stage_index = 0;
2771 get_cs_transform_for(CoordinateSystem cs)
const {
2772 if (_coordinate_system == cs) {
2774 return _cs_transform;
2776 }
else if (_internal_coordinate_system == CS_default ||
2777 _internal_coordinate_system == cs) {
2778 return TransformState::make_identity();
2781 return TransformState::make_mat
2782 (LMatrix4::convert_mat(cs, _internal_coordinate_system));
2793 get_cs_transform()
const {
2794 return _cs_transform;
2801 void GraphicsStateGuardian::
2802 do_issue_clip_plane() {
2803 int num_enabled = 0;
2804 int num_on_planes = 0;
2807 _target_rs->get_attrib_def(ClipPlaneAttrib::get_class_slot());
2809 if (target_clip_plane !=
nullptr) {
2810 CPT(
ClipPlaneAttrib) new_plane = target_clip_plane->filter_to_max(_max_clip_planes);
2813 for (
int li = 0; li < num_on_planes; li++) {
2814 NodePath plane = new_plane->get_on_plane(li);
2817 DCAST_INTO_V(plane_node, plane.
node());
2820 if (!_clip_planes_enabled) {
2821 enable_clip_planes(
true);
2822 _clip_planes_enabled =
true;
2825 enable_clip_plane(num_enabled,
true);
2826 if (num_enabled == 0) {
2827 begin_bind_clip_planes();
2830 bind_clip_plane(plane, num_enabled);
2837 for (i = num_enabled; i < _num_clip_planes_enabled; ++i) {
2838 enable_clip_plane(i,
false);
2840 _num_clip_planes_enabled = num_enabled;
2843 if (num_enabled == 0) {
2844 if (_clip_planes_enabled) {
2845 enable_clip_planes(
false);
2846 _clip_planes_enabled =
false;
2849 end_bind_clip_planes();
2864 _target_rs->get_attrib_def(ColorAttrib::get_class_slot());
2867 case ColorAttrib::T_flat:
2870 _scene_graph_color = target_color->
get_color();
2871 _has_scene_graph_color =
true;
2872 _vertex_colors_enabled =
false;
2875 case ColorAttrib::T_off:
2878 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2879 _has_scene_graph_color =
false;
2880 _vertex_colors_enabled =
false;
2883 case ColorAttrib::T_vertex:
2886 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2887 _has_scene_graph_color =
false;
2888 _vertex_colors_enabled =
true;
2892 if (_color_scale_via_lighting) {
2893 _state_mask.
clear_bit(LightAttrib::get_class_slot());
2894 _state_mask.
clear_bit(MaterialAttrib::get_class_slot());
2896 determine_light_color_scale();
2903 void GraphicsStateGuardian::
2904 do_issue_color_scale() {
2907 if (_has_texture_alpha_scale) {
2908 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2912 _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot());
2914 _color_scale_enabled = target_color_scale->
has_scale();
2915 _current_color_scale = target_color_scale->
get_scale();
2916 _has_texture_alpha_scale =
false;
2918 if (_color_blend_involves_color_scale) {
2919 _state_mask.
clear_bit(TransparencyAttrib::get_class_slot());
2921 if (_texture_involves_color_scale) {
2922 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
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();
2931 if (_alpha_scale_via_texture && !_has_scene_graph_color &&
2935 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2936 _state_mask.
clear_bit(TexMatrixAttrib::get_class_slot());
2938 _has_texture_alpha_scale =
true;
2958 LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
2961 int num_enabled = 0;
2962 bool any_on_lights =
false;
2965 _target_rs->get_attrib_def(target_light);
2967 if (display_cat.is_spam()) {
2969 <<
"do_issue_light: " << target_light <<
"\n";
2971 if (target_light !=
nullptr) {
2976 for (
size_t li = 0; li < filtered_lights; ++li) {
2980 nassertv(light_obj !=
nullptr);
2983 if (!_lighting_enabled) {
2984 enable_lighting(
true);
2985 _lighting_enabled =
true;
2988 const LColor &color = light_obj->
get_color();
2990 if (color[0] != 0.0 || color[1] != 0.0 || color[2] != 0.0) {
2991 enable_light(num_enabled,
true);
2992 if (num_enabled == 0) {
2993 begin_bind_lights();
2996 light_obj->bind(
this, light, num_enabled);
3002 for (i = num_enabled; i < _num_lights_enabled; ++i) {
3003 enable_light(i,
false);
3005 _num_lights_enabled = num_enabled;
3008 if (!any_on_lights) {
3009 if (_color_scale_via_lighting && (_has_material_force_color || _light_color_scale != LVecBase4(1.0f, 1.0f, 1.0f, 1.0f))) {
3011 if (!_lighting_enabled) {
3012 enable_lighting(
true);
3013 _lighting_enabled =
true;
3015 set_ambient_light(LColor(1.0f, 1.0f, 1.0f, 1.0f));
3018 if (_lighting_enabled) {
3019 enable_lighting(
false);
3020 _lighting_enabled =
false;
3026 if (!_lighting_enabled) {
3027 enable_lighting(
true);
3028 _lighting_enabled =
true;
3031 set_ambient_light(target_light->get_ambient_contribution());
3034 if (num_enabled != 0) {
3096 void GraphicsStateGuardian::
3097 init_frame_pstats() {
3099 _data_transferred_pcollector.clear_level();
3100 _vertex_buffer_switch_pcollector.clear_level();
3101 _index_buffer_switch_pcollector.clear_level();
3103 _primitive_batches_pcollector.clear_level();
3104 _primitive_batches_tristrip_pcollector.clear_level();
3105 _primitive_batches_trifan_pcollector.clear_level();
3106 _primitive_batches_tri_pcollector.clear_level();
3107 _primitive_batches_patch_pcollector.clear_level();
3108 _primitive_batches_other_pcollector.clear_level();
3109 _vertices_tristrip_pcollector.clear_level();
3110 _vertices_trifan_pcollector.clear_level();
3111 _vertices_tri_pcollector.clear_level();
3112 _vertices_patch_pcollector.clear_level();
3113 _vertices_other_pcollector.clear_level();
3115 _state_pcollector.clear_level();
3116 _transform_state_pcollector.clear_level();
3117 _texture_state_pcollector.clear_level();
3127 create_gamma_table (PN_stdfloat gamma,
unsigned short *red_table,
unsigned short *green_table,
unsigned short *blue_table) {
3135 for (i = 0; i < 256; i++) {
3138 PN_stdfloat gamma_correction;
3140 x = ((double) i / 255.0);
3141 gamma_correction = 1.0 / gamma;
3142 x = pow (x, (
double) gamma_correction);
3148 red_table [i] = (int)g;
3149 green_table [i] = (int)g;
3150 blue_table [i] = (int)g;
3159 void GraphicsStateGuardian::
3160 reissue_transforms() {
3168 void GraphicsStateGuardian::
3169 enable_lighting(
bool enable) {
3177 void GraphicsStateGuardian::
3178 set_ambient_light(
const LColor &color) {
3186 void GraphicsStateGuardian::
3187 enable_light(
int light_id,
bool enable) {
3198 void GraphicsStateGuardian::
3199 begin_bind_lights() {
3208 void GraphicsStateGuardian::
3217 void GraphicsStateGuardian::
3218 enable_clip_planes(
bool enable) {
3226 void GraphicsStateGuardian::
3227 enable_clip_plane(
int plane_id,
bool enable) {
3238 void GraphicsStateGuardian::
3239 begin_bind_clip_planes() {
3247 void GraphicsStateGuardian::
3248 bind_clip_plane(
const NodePath &plane,
int plane_id) {
3257 void GraphicsStateGuardian::
3258 end_bind_clip_planes() {
3264 void GraphicsStateGuardian::
3265 determine_target_texture() {
3267 _target_rs->get_attrib_def(TextureAttrib::get_class_slot());
3269 _target_rs->get_attrib_def(TexGenAttrib::get_class_slot());
3271 nassertv(target_texture !=
nullptr &&
3272 target_tex_gen !=
nullptr);
3273 _target_texture = target_texture;
3274 _target_tex_gen = target_tex_gen;
3276 if (_has_texture_alpha_scale) {
3280 _target_texture = DCAST(
TextureAttrib, _target_texture->add_on_stage(stage, texture));
3281 _target_tex_gen = DCAST(
TexGenAttrib, _target_tex_gen->add_stage
3282 (stage, TexGenAttrib::M_constant, LTexCoord3(_current_color_scale[3], 0.0f, 0.0f)));
3286 _target_texture = _target_texture->filter_to_max(max_texture_stages);
3287 nassertv(_target_texture->get_num_on_stages() <= max_texture_stages);
3293 void GraphicsStateGuardian::
3294 determine_target_shader() {
3295 if (_target_rs->_generated_shader !=
nullptr) {
3296 _target_shader = (
const ShaderAttrib *)_target_rs->_generated_shader.p();
3299 _target_rs->get_attrib_def(ShaderAttrib::get_class_slot());
3306 void GraphicsStateGuardian::
3315 void GraphicsStateGuardian::
3322 _closing_gsg =
true;
3324 if (display_cat.is_debug()) {
3326 <<
this <<
" close_gsg " << get_type() <<
"\n";
3340 _prepared_objects.clear();
3342 _pending_timer_queries.clear();
3353 void GraphicsStateGuardian::
3354 panic_deactivate() {
3357 <<
"Deactivating " << get_type() <<
".\n";
3359 throw_event(
"panic-deactivate-gsg",
this);
3368 void GraphicsStateGuardian::
3369 determine_light_color_scale() {
3370 if (_has_scene_graph_color) {
3374 _has_material_force_color =
true;
3375 _material_force_color = _scene_graph_color;
3376 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3377 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3378 _material_force_color.set(_scene_graph_color[0] * _current_color_scale[0],
3379 _scene_graph_color[1] * _current_color_scale[1],
3380 _scene_graph_color[2] * _current_color_scale[2],
3381 _scene_graph_color[3] * _current_color_scale[3]);
3384 }
else if (!_vertex_colors_enabled) {
3388 _has_material_force_color =
true;
3389 _material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
3390 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3391 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3392 _material_force_color.componentwise_mult(_current_color_scale);
3398 _has_material_force_color =
false;
3399 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3400 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3401 _light_color_scale = _current_color_scale;
3412 if (state ==
nullptr) {
3413 state = RenderState::make(LightAttrib::make_all_off());
3422 get_unclipped_state() {
3424 if (state ==
nullptr) {
3425 state = RenderState::make(ClipPlaneAttrib::make_all_off());
3434 get_untextured_state() {
3436 if (state ==
nullptr) {
3437 state = RenderState::make(TextureAttrib::make_off());
3451 nassertr(_loader !=
nullptr,
nullptr);
3454 if (_current_display_region !=
nullptr) {
3455 priority = _current_display_region->get_texture_reload_priority();
3458 string task_name = string(
"reload:") + tc->
get_texture()->get_name();
3464 for (
size_t ti = 0; ti < num_tasks; ++ti) {
3466 if (task->
is_exact_type(TextureReloadRequest::get_class_type()) &&
3479 _supports_compressed_texture);
3480 request->set_priority(priority);
3481 _loader->load_async(request);
3493 bool is_point = node->
is_of_type(PointLight::get_class_type());
3494 nassertr(node->
is_of_type(DirectionalLight::get_class_type()) ||
3495 node->
is_of_type(Spotlight::get_class_type()) ||
3499 if (light ==
nullptr || !light->_shadow_caster) {
3502 if (node->
is_of_type(PointLight::get_class_type())) {
3503 return get_dummy_shadow_map(Texture::TT_cube_map);
3505 return get_dummy_shadow_map(Texture::TT_2d_texture);
3510 nassertr(light->_shadow_map !=
nullptr,
nullptr);
3513 if (light->_sbuffers.count(
this) != 0) {
3515 return light->_shadow_map;
3518 if (display_cat.is_debug()) {
3520 <<
"Constructing shadow buffer for light '" << light->get_name()
3521 <<
"', size=" << light->_sb_size[0] <<
"x" << light->_sb_size[1]
3522 <<
", sort=" << light->_sb_sort <<
"\n";
3525 if (host ==
nullptr) {
3526 nassertr(_current_display_region !=
nullptr,
nullptr);
3527 host = _current_display_region->get_window();
3529 nassertr(host !=
nullptr,
nullptr);
3532 GraphicsOutput *sbuffer = make_shadow_buffer(light, light->_shadow_map,
3537 for (
int i = 0; i < 6; ++i) {
3540 dr->set_target_tex_page(i);
3541 dr->set_camera(light_np);
3542 dr->set_clear_depth_active(
true);
3547 dr->set_clear_depth_active(
true);
3550 light->_sbuffers[
this] = sbuffer;
3551 return light->_shadow_map;
3559 get_dummy_shadow_map(Texture::TextureType texture_type)
const {
3560 if (texture_type != Texture::TT_cube_map) {
3562 if (dummy_2d ==
nullptr) {
3563 dummy_2d =
new Texture(
"dummy-shadow-2d");
3564 dummy_2d->setup_2d_texture(1, 1, Texture::T_unsigned_byte, Texture::F_depth_component);
3565 dummy_2d->set_clear_color(1);
3568 dummy_2d->set_minfilter(SamplerState::FT_shadow);
3569 dummy_2d->set_magfilter(SamplerState::FT_shadow);
3571 dummy_2d->set_minfilter(SamplerState::FT_linear);
3572 dummy_2d->set_magfilter(SamplerState::FT_linear);
3577 static PT(
Texture) dummy_cube;
3578 if (dummy_cube ==
nullptr) {
3579 dummy_cube =
new Texture(
"dummy-shadow-cube");
3580 dummy_cube->setup_cube_map(1, Texture::T_unsigned_byte, Texture::F_depth_component);
3581 dummy_cube->set_clear_color(1);
3583 dummy_cube->set_minfilter(SamplerState::FT_linear);
3584 dummy_cube->set_magfilter(SamplerState::FT_linear);
3596 bool is_point = light->
is_of_type(PointLight::get_class_type());
3600 fbp.set_depth_bits(shadow_depth_bits);
3603 int flags = GraphicsPipe::BF_refuse_window;
3605 flags |= GraphicsPipe::BF_size_square;
3612 light->get_name(), light->_sb_sort, fbp, props, flags,
this, host);
3614 if (sbuffer !=
nullptr) {
3615 sbuffer->
add_render_texture(tex, GraphicsOutput::RTM_bind_or_copy, GraphicsOutput::RTP_depth);
3628 state->get_attrib_def(shader_attrib);
3631 if (_shader_generator ==
nullptr) {
3632 if (!_supports_basic_shaders) {
3637 if (state->_generated_shader ==
nullptr ||
3638 state->_generated_shader_seq != _generated_shader_seq) {
3644 state->get_attrib_def(sattr);
3645 if (sattr->get_flag(ShaderAttrib::F_hardware_skinning)) {
3650 state->_generated_shader = _shader_generator->synthesize_shader(state, spec);
3651 state->_generated_shader_seq = _generated_shader_seq;
3728 operator << (std::ostream &out, GraphicsStateGuardian::ShaderModel sm) {
3729 static const char *sm_strings[] = {
"none",
"1.1",
"2.0",
"2.x",
"3.0",
"4.0",
"5.0",
"5.1"};
3730 nassertr(sm >= 0 && sm <= GraphicsStateGuardian::SM_51, out);
3731 out << sm_strings[sm];