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 return &LMatrix4::ones_mat();
1022 PN_stdfloat start, end;
1024 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1028 case Shader::SMO_attr_fogcolor: {
1030 _target_rs->get_attrib_def(FogAttrib::get_class_slot());
1032 if (fog ==
nullptr) {
1033 return &LMatrix4::ones_mat();
1036 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
1039 case Shader::SMO_alight_x: {
1040 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1041 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1043 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1045 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
1048 case Shader::SMO_satten_x: {
1049 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1050 nassertr(!np.
is_empty(), &LMatrix4::ones_mat());
1052 DCAST_INTO_R(lt, np.
node(), &LMatrix4::ones_mat());
1055 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a[0], a[1], a[2], x);
1058 case Shader::SMO_dlight_x: {
1060 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1061 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1063 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1066 t = np.get_net_transform()->
get_mat() *
1067 _scene_setup->get_world_transform()->get_mat();
1070 LVecBase3 h = d + LVecBase3(0,-1,0);
1072 t.set(c[0], c[1], c[2], c[3],
1073 s[0], s[1], s[2], c[3],
1074 d[0], d[1], d[2], 0,
1075 h[0], h[1], h[2], 0);
1078 case Shader::SMO_plight_x: {
1080 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1081 nassertr(!np.
is_empty(), &LMatrix4::ones_mat());
1083 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1086 t = np.get_net_transform()->
get_mat() *
1087 _scene_setup->get_world_transform()->get_mat();
1088 LVecBase3 p = (t.xform_point(lt->
get_point()));
1091 PN_stdfloat lnear = lens->
get_near();
1092 PN_stdfloat lfar = lens->
get_far();
1093 t.set(c[0], c[1], c[2], c[3],
1094 s[0], s[1], s[2], s[3],
1095 p[0], p[1], p[2], lnear,
1096 a[0], a[1], a[2], lfar);
1099 case Shader::SMO_slight_x: {
1101 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1102 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1104 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1106 nassertr(lens !=
nullptr, &LMatrix4::zeros_mat());
1109 PN_stdfloat cutoff = ccos(deg_2_rad(lens->
get_hfov() * 0.5f));
1110 t = np.get_net_transform()->
get_mat() *
1111 _scene_setup->get_world_transform()->get_mat();
1114 t.set(c[0], c[1], c[2], c[3],
1115 s[0], s[1], s[2], s[3],
1116 p[0], p[1], p[2], 0,
1117 d[0], d[1], d[2], cutoff);
1120 case Shader::SMO_light_ambient: {
1121 LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
1123 _target_rs->get_attrib_def(LightAttrib::get_class_slot());
1128 t.set_row(3, LVecBase4(1, 1, 1, 1));
1130 t.set_row(3, target_light->get_ambient_contribution());
1134 case Shader::SMO_texmat_i: {
1137 if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
1141 return &LMatrix4::ident_mat();
1144 case Shader::SMO_inv_texmat_i: {
1147 if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
1148 index < ta->get_num_on_stages()) {
1149 t = tma->get_transform(ta->
get_on_stage(index))->get_inverse()->get_mat();
1152 return &LMatrix4::ident_mat();
1155 case Shader::SMO_texscale_i: {
1158 if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
1159 index < ta->get_num_on_stages()) {
1160 LVecBase3 scale = tma->get_transform(ta->
get_on_stage(index))->get_scale();
1161 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, scale[0], scale[1], scale[2], 0);
1164 return &LMatrix4::ident_mat();
1167 case Shader::SMO_texcolor_i: {
1169 if (_target_rs->get_attrib(ta) && index < ta->get_num_on_stages()) {
1174 return &LMatrix4::zeros_mat();
1177 case Shader::SMO_tex_is_alpha_i: {
1181 if (_target_rs->get_attrib(ta) &&
1182 index < ta->get_num_on_stages()) {
1184 PN_stdfloat v = (ta->
get_on_texture(ts)->get_format() == Texture::F_alpha);
1185 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v, v, v, 0);
1188 return &LMatrix4::zeros_mat();
1191 case Shader::SMO_plane_x: {
1192 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1193 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1195 DCAST_INTO_R(plane_node, np.
node(), &LMatrix4::zeros_mat());
1197 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, p[0], p[1], p[2], p[3]);
1200 case Shader::SMO_clipplane_x: {
1202 _target_rs->get_attrib_def(cpa);
1203 int planenr = atoi(name->
get_name().c_str());
1205 return &LMatrix4::zeros_mat();
1208 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1210 DCAST_INTO_R(plane_node, np.
node(), &LMatrix4::zeros_mat());
1215 if (!transform->is_identity()) {
1216 plane.xform(transform->get_mat());
1218 t.set_row(3, plane);
1221 case Shader::SMO_apiview_clipplane_i: {
1223 _target_rs->get_attrib_def(cpa);
1225 return &LMatrix4::zeros_mat();
1229 nassertr(!plane.
is_empty(), &LMatrix4::zeros_mat());
1231 DCAST_INTO_R(plane_node, plane.
node(), &LMatrix4::zeros_mat());
1234 _scene_setup->get_cs_world_transform()->compose(
1235 plane.
get_transform(_scene_setup->get_scene_root().get_parent()));
1237 LPlane xformed_plane = plane_node->
get_plane() * transform->get_mat();
1238 t.set_row(3, xformed_plane);
1241 case Shader::SMO_mat_constant_x: {
1242 return &_target_shader->get_shader_input_matrix(name, t);
1244 case Shader::SMO_vec_constant_x: {
1245 const LVecBase4 &input = _target_shader->get_shader_input_vector(name);
1246 const PN_stdfloat *data = input.get_data();
1247 t.set(data[0], data[1], data[2], data[3],
1248 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]);
1253 case Shader::SMO_world_to_view: {
1254 return &(_scene_setup->get_world_transform()->get_mat());
1256 case Shader::SMO_view_to_world: {
1257 return &(_scene_setup->get_camera_transform()->get_mat());
1259 case Shader::SMO_model_to_view: {
1260 t = _inv_cs_transform->compose(_internal_transform)->get_mat();
1263 case Shader::SMO_model_to_apiview: {
1264 return &(_internal_transform->get_mat());
1266 case Shader::SMO_view_to_model: {
1267 t = _internal_transform->invert_compose(_cs_transform)->get_mat();
1270 case Shader::SMO_apiview_to_model: {
1271 t = _internal_transform->get_inverse()->get_mat();
1274 case Shader::SMO_apiview_to_view: {
1275 return &(_inv_cs_transform->get_mat());
1277 case Shader::SMO_view_to_apiview: {
1278 return &(_cs_transform->get_mat());
1280 case Shader::SMO_clip_to_view: {
1281 if (_current_lens->get_coordinate_system() == _coordinate_system) {
1282 return &(_current_lens->get_projection_mat_inv(_current_stereo_channel));
1284 t = _current_lens->get_projection_mat_inv(_current_stereo_channel) *
1285 LMatrix4::convert_mat(_current_lens->get_coordinate_system(), _coordinate_system);
1289 case Shader::SMO_view_to_clip: {
1290 if (_current_lens->get_coordinate_system() == _coordinate_system) {
1291 return &(_current_lens->get_projection_mat(_current_stereo_channel));
1293 t = LMatrix4::convert_mat(_coordinate_system, _current_lens->get_coordinate_system()) *
1294 _current_lens->get_projection_mat(_current_stereo_channel);
1298 case Shader::SMO_apiclip_to_view: {
1299 t = _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat();
1302 case Shader::SMO_view_to_apiclip: {
1303 t = _cs_transform->get_mat() * _projection_mat->get_mat();
1306 case Shader::SMO_apiclip_to_apiview: {
1307 return &(_projection_mat_inv->get_mat());
1309 case Shader::SMO_apiview_to_apiclip: {
1310 return &(_projection_mat->get_mat());
1312 case Shader::SMO_view_x_to_view: {
1313 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1314 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1315 t = np.get_net_transform()->
get_mat() *
1316 _scene_setup->get_world_transform()->get_mat();
1319 case Shader::SMO_view_to_view_x: {
1320 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1321 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1322 t = _scene_setup->get_camera_transform()->get_mat() *
1323 np.get_net_transform()->get_inverse()->
get_mat();
1326 case Shader::SMO_apiview_x_to_view: {
1327 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1328 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1329 t = LMatrix4::convert_mat(_internal_coordinate_system, _coordinate_system) *
1330 np.get_net_transform()->
get_mat() *
1331 _scene_setup->get_world_transform()->get_mat();
1334 case Shader::SMO_view_to_apiview_x: {
1335 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1336 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1337 t = (_scene_setup->get_camera_transform()->get_mat() *
1338 np.get_net_transform()->get_inverse()->
get_mat() *
1339 LMatrix4::convert_mat(_coordinate_system, _internal_coordinate_system));
1342 case Shader::SMO_clip_x_to_view: {
1343 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1344 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1346 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1350 np.get_net_transform()->
get_mat() *
1351 _scene_setup->get_world_transform()->get_mat();
1354 case Shader::SMO_view_to_clip_x: {
1355 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1356 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1358 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1360 t = _scene_setup->get_camera_transform()->get_mat() *
1361 np.get_net_transform()->get_inverse()->
get_mat() *
1366 case Shader::SMO_apiclip_x_to_view: {
1367 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1368 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1370 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1372 t = calc_projection_mat(lens)->get_inverse()->get_mat() *
1374 np.get_net_transform()->
get_mat() *
1375 _scene_setup->get_world_transform()->get_mat();
1378 case Shader::SMO_view_to_apiclip_x: {
1379 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1380 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1382 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1384 t = _scene_setup->get_camera_transform()->get_mat() *
1385 np.get_net_transform()->get_inverse()->
get_mat() *
1387 calc_projection_mat(lens)->get_mat();
1390 case Shader::SMO_mat_constant_x_attrib: {
1391 if (_target_shader->has_shader_input(name)) {
1394 return &_target_shader->get_shader_input_matrix(name, t);
1398 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1402 case Shader::SMO_vec_constant_x_attrib: {
1403 if (_target_shader->has_shader_input(name)) {
1406 const LVecBase4 &data = _target_shader->get_shader_input_vector(name);
1407 t.set(data[0], data[1], data[2], data[3],
1408 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]);
1415 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1419 case Shader::SMO_light_source_i_attrib: {
1421 _target_rs->get_attrib_def(target_light);
1426 if (index >= 0 && (
size_t)index < num_lights) {
1428 nassertr(!light.
is_empty(), &LMatrix4::ident_mat());
1430 nassertr(light_obj !=
nullptr, &LMatrix4::ident_mat());
1434 }
else if (index == 0) {
1438 return &LMatrix4::ones_mat();
1442 case Shader::SMO_light_source_i_packed: {
1445 _target_rs->get_attrib_def(target_light);
1450 if (index >= 0 && (
size_t)index < num_lights) {
1452 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1455 nassertr(light !=
nullptr, &LMatrix4::zeros_mat());
1459 LMatrix4 mat = np.get_net_transform()->
get_mat() *
1460 _scene_setup->get_world_transform()->get_mat();
1462 if (node->
is_of_type(DirectionalLight::get_class_type())) {
1463 LVecBase3 d = mat.xform_vec(((
const DirectionalLight *)node)->get_direction());
1465 t.set_row(2, LVecBase4(d, 0));
1466 t.set_row(3, LVecBase4(-d, 0));
1468 }
else if (node->
is_of_type(LightLensNode::get_class_type())) {
1472 t.set_row(3, LVecBase4(p));
1476 if (node->
is_of_type(Spotlight::get_class_type())) {
1477 PN_stdfloat cutoff = ccos(deg_2_rad(lens->
get_hfov() * 0.5f));
1479 t.set_cell(1, 3, ((
const Spotlight *)node)->get_exponent());
1480 t.set_row(2, LVecBase4(d, cutoff));
1482 }
else if (node->
is_of_type(PointLight::get_class_type())) {
1483 t.set_cell(1, 3, lens->
get_far());
1484 t.set_cell(3, 3, lens->
get_near());
1486 if (node->
is_of_type(SphereLight::get_class_type())) {
1487 t.set_cell(2, 3, ((
const SphereLight *)node)->get_radius());
1491 }
else if (index == 0) {
1494 t.set_row(0, LVecBase4(1, 1, 1, 1));
1499 nassertr(
false , &LMatrix4::ident_mat());
1500 return &LMatrix4::ident_mat();
1522 static const CPT_InternalName IN_constantAttenuation(
"constantAttenuation");
1524 static const CPT_InternalName IN_quadraticAttenuation(
"quadraticAttenuation");
1532 if (attrib == IN_color) {
1533 if (node ==
nullptr) {
1534 return &LMatrix4::ident_mat();
1537 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1542 }
else if (attrib == IN_ambient) {
1543 if (node ==
nullptr) {
1544 return &LMatrix4::ident_mat();
1547 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1553 t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
1557 }
else if (attrib == IN_diffuse) {
1558 if (node ==
nullptr) {
1559 return &LMatrix4::ident_mat();
1562 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1565 t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
1572 }
else if (attrib == IN_specular) {
1573 if (node ==
nullptr) {
1574 return &LMatrix4::ident_mat();
1577 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1581 }
else if (attrib == IN_position) {
1583 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
1587 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1589 }
else if (node->
is_of_type(DirectionalLight::get_class_type())) {
1591 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1594 LVector3 dir = -(light->
get_direction() * transform->get_mat());
1595 dir *= _scene_setup->get_cs_world_transform()->
get_mat();
1596 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 0);
1600 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1602 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1605 _scene_setup->get_cs_world_transform()->compose(
1606 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1608 const LMatrix4 &light_mat = transform->get_mat();
1610 t = LMatrix4::translate_mat(pos);
1614 }
else if (attrib == IN_halfVector) {
1616 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
1620 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1622 }
else if (node->
is_of_type(DirectionalLight::get_class_type())) {
1624 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1627 LVector3 dir = -(light->
get_direction() * transform->get_mat());
1628 dir *= _scene_setup->get_cs_world_transform()->
get_mat();
1630 dir += LVector3(0, 0, 1);
1632 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 1);
1636 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1638 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1641 _scene_setup->get_cs_world_transform()->compose(
1642 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1644 const LMatrix4 &light_mat = transform->get_mat();
1647 pos += LVector3(0, 0, 1);
1649 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pos[0],pos[1],pos[2], 1);
1653 }
else if (attrib == IN_spotDirection) {
1654 if (node ==
nullptr) {
1655 t.set_row(3, LVector3(0.0f, 0.0f, -1.0f));
1659 t.set_row(3, LVector3(0.0f, 0.0f, 0.0f));
1663 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1665 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1668 _scene_setup->get_cs_world_transform()->compose(
1669 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1671 const LMatrix4 &light_mat = transform->get_mat();
1677 }
else if (attrib == IN_spotCutoff) {
1678 if (node !=
nullptr &&
1679 node->
is_of_type(Spotlight::get_class_type())) {
1681 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1683 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1685 float cutoff = lens->
get_hfov() * 0.5f;
1686 t.set_row(3, LVecBase4(cutoff));
1690 t.set_row(3, LVecBase4(180));
1694 }
else if (attrib == IN_spotCosCutoff) {
1695 if (node !=
nullptr &&
1696 node->
is_of_type(Spotlight::get_class_type())) {
1698 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1700 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1702 float cutoff = lens->
get_hfov() * 0.5f;
1703 t.set_row(3, LVecBase4(ccos(deg_2_rad(cutoff))));
1707 t.set_row(3, LVecBase4(-1));
1711 }
else if (attrib == IN_spotExponent) {
1712 if (node ==
nullptr) {
1713 return &LMatrix4::zeros_mat();
1716 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1721 }
else if (attrib == IN_attenuation) {
1722 if (node !=
nullptr) {
1724 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1728 t.set_row(3, LVecBase4(1, 0, 0, 0));
1732 }
else if (attrib == IN_constantAttenuation) {
1733 if (node ==
nullptr) {
1734 return &LMatrix4::ones_mat();
1737 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1742 }
else if (attrib == IN_linearAttenuation) {
1743 if (node ==
nullptr) {
1744 return &LMatrix4::zeros_mat();
1747 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1752 }
else if (attrib == IN_quadraticAttenuation) {
1753 if (node ==
nullptr) {
1754 return &LMatrix4::zeros_mat();
1757 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1762 }
else if (attrib == IN_shadowViewMatrix) {
1763 static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f,
1764 0.0f, 0.5f, 0.0f, 0.0f,
1765 0.0f, 0.0f, 0.5f, 0.0f,
1766 0.5f, 0.5f, 0.5f, 1.0f);
1768 if (node ==
nullptr) {
1773 DCAST_INTO_R(lnode, node, &LMatrix4::ident_mat());
1776 t = _inv_cs_transform->get_mat() *
1777 _scene_setup->get_camera_transform()->get_mat() *
1778 np.get_net_transform()->get_inverse()->
get_mat() *
1781 if (!node->
is_of_type(PointLight::get_class_type())) {
1788 <<
"Shader input requests invalid attribute " << *attrib
1789 <<
" from node " << np <<
"\n";
1790 return &LMatrix4::ident_mat();
1800 switch (spec._part) {
1801 case Shader::STO_named_input:
1803 if (!_target_shader->has_shader_input(spec._name)) {
1806 if (parent != InternalName::get_root() &&
1807 _target_shader->has_shader_input(parent)) {
1810 const string &basename = spec._name->get_basename();
1811 NodePath np = _target_shader->get_shader_input_nodepath(parent);
1813 if (basename ==
"shadowMap") {
1814 PT(
Texture) tex = get_shadow_map(np);
1815 if (tex !=
nullptr) {
1816 sampler = tex->get_default_sampler();
1821 if (spec._stage == 0) {
1823 <<
"Shader input " << *parent
1824 <<
" has no member named " << basename <<
".\n";
1832 if (spec._stage == 0) {
1834 <<
"Shader input " << *spec._name <<
" is not present.\n";
1840 return _target_shader->get_shader_input_texture(spec._name, &sampler);
1844 case Shader::STO_stage_i:
1849 _target_rs->get_attrib_def(texattrib);
1860 case Shader::STO_light_i_shadow_map:
1863 _target_rs->get_attrib_def(target_light);
1868 if (spec._stage >= 0 && (
size_t)spec._stage < num_lights) {
1870 nassertr(!light.
is_empty(),
nullptr);
1872 nassertr(light_obj !=
nullptr,
nullptr);
1874 PT(
Texture) tex = get_shadow_map(light);
1875 if (tex !=
nullptr) {
1876 sampler = tex->get_default_sampler();
1881 PT(
Texture) tex = get_dummy_shadow_map((Texture::TextureType)spec._desired_type);
1882 if (tex !=
nullptr) {
1883 sampler = tex->get_default_sampler();
1891 nassertr(
false,
nullptr);
1903 return (_target_shader->get_shader_input_ptr(spec._arg));
1912 _current_display_region = dr->get_object();
1915 _effective_incomplete_render = _incomplete_render && _current_display_region->get_incomplete_render();
1917 _stereo_buffer_mask = ~0;
1922 switch (output_channel) {
1924 output_channel = Lens::SC_right;
1927 case Lens::SC_right:
1928 output_channel = Lens::SC_left;
1936 switch (output_channel) {
1939 if (_current_properties->is_stereo()) {
1944 case Lens::SC_right:
1946 if (_current_properties->is_stereo()) {
1952 case Lens::SC_stereo:
1953 _color_write_mask = ColorWriteAttrib::C_all;
1976 reissue_transforms();
1979 _state_rs = RenderState::make_empty();
1980 _state_mask.
clear();
1990 nassertv(_engine !=
nullptr);
1992 DCAST_INTO_V(win, window);
2015 calc_projection_mat(
const Lens *lens) {
2016 if (lens ==
nullptr) {
2024 return TransformState::make_identity();
2037 _prepared_objects->begin_frame(
this, current_thread);
2044 _state_rs = RenderState::make_empty();
2045 _state_mask.
clear();
2051 if (_last_query_frame < frame) {
2052 _last_query_frame = frame;
2053 _timer_queries_pcollector.clear_level();
2060 if (_timer_queries_active) {
2063 issue_timer_query(0x8000);
2064 issue_timer_query(0x0000);
2069 return !_needs_reset;
2100 _scene_setup = _scene_null;
2106 for (i = 0; i < _num_lights_enabled; ++i) {
2107 enable_light(i,
false);
2109 _num_lights_enabled = 0;
2112 for (i = 0; i < _num_clip_planes_enabled; ++i) {
2113 enable_clip_plane(i,
false);
2115 _num_clip_planes_enabled = 0;
2118 _state_rs = RenderState::make_empty();
2119 _state_mask.
clear();
2128 _prepared_objects->end_frame(current_thread);
2131 _data_transferred_pcollector.flush_level();
2133 _primitive_batches_pcollector.flush_level();
2134 _primitive_batches_tristrip_pcollector.flush_level();
2135 _primitive_batches_trifan_pcollector.flush_level();
2136 _primitive_batches_tri_pcollector.flush_level();
2137 _primitive_batches_patch_pcollector.flush_level();
2138 _primitive_batches_other_pcollector.flush_level();
2139 _vertices_tristrip_pcollector.flush_level();
2140 _vertices_trifan_pcollector.flush_level();
2141 _vertices_tri_pcollector.flush_level();
2142 _vertices_patch_pcollector.flush_level();
2143 _vertices_other_pcollector.flush_level();
2145 _state_pcollector.flush_level();
2146 _texture_state_pcollector.flush_level();
2147 _transform_state_pcollector.flush_level();
2148 _draw_primitive_pcollector.flush_level();
2151 _prepared_objects->_graphics_memory_lru.begin_epoch();
2165 PStatClient *client = PStatClient::get_global_pstats();
2167 if (!client->client_is_connected()) {
2168 _timer_queries_active =
false;
2172 if (!_timer_queries_active) {
2173 if (pstats_gpu_timing && _supports_timer_query) {
2175 _timer_queries_active =
true;
2183 if (_pstats_gpu_thread == -1) {
2186 PStatThread gpu_thread(client, _pstats_gpu_thread);
2190 if (!_pending_timer_queries.empty()) {
2191 int count = _pending_timer_queries.size();
2198 if (_last_num_queried > 0) {
2201 int i = std::min(_last_num_queried, count) - 1;
2203 if (_pending_timer_queries[i]->is_answer_ready()) {
2205 while (i < count - 1) {
2206 if (!_pending_timer_queries[++i]->is_answer_ready()) {
2214 if (_pending_timer_queries[--i]->is_answer_ready()) {
2225 int step = count / 2;
2226 int i = first + step;
2227 if (_pending_timer_queries[i]->is_answer_ready()) {
2240 _last_num_queried = first;
2242 for (
int i = 0; i < first; ++i) {
2245 double time_data = query->get_timestamp();
2247 if (query->_pstats_index == _command_latency_pcollector.get_index()) {
2250 cdef = client->get_collector_ptr(query->_pstats_index)->get_def(client, query->_pstats_index);
2251 _pstats_gpu_data.add_level(query->_pstats_index, time_data * cdef->_factor);
2253 }
else if (query->_pstats_index & 0x8000) {
2254 _pstats_gpu_data.add_stop(query->_pstats_index & 0x7fff, time_data);
2257 _pstats_gpu_data.add_start(query->_pstats_index & 0x7fff, time_data);
2263 if (query->_pstats_index == 0x8000) {
2265 _pstats_gpu_data.clear();
2272 _pending_timer_queries.erase(
2273 _pending_timer_queries.begin(),
2274 _pending_timer_queries.begin() + first
2276 _timer_queries_pcollector.add_level_now(first);
2299 begin_decal_base_first() {
2302 if (decal_base_first ==
nullptr) {
2303 decal_base_first = RenderState::make
2304 (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
2305 RenderState::get_max_priority());
2307 return decal_base_first;
2317 begin_decal_nested() {
2321 if (decal_nested ==
nullptr) {
2322 decal_nested = RenderState::make
2323 (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
2324 RenderState::get_max_priority());
2326 return decal_nested;
2340 begin_decal_base_second() {
2345 if (decal_base_second ==
nullptr) {
2346 decal_base_second = RenderState::make
2347 (ColorWriteAttrib::make(ColorWriteAttrib::C_off),
2351 RenderState::get_max_priority());
2353 return decal_base_second;
2373 _data_reader = data_reader;
2377 return _data_reader->has_vertex() || (_target_shader && _target_shader->has_shader());
2476 _data_reader =
nullptr;
2484 _needs_reset =
false;
2487 _state_rs = RenderState::make_empty();
2488 _target_rs =
nullptr;
2489 _state_mask.
clear();
2490 _internal_transform = _cs_transform;
2492 _scene_setup = _scene_null;
2494 _color_write_mask = ColorWriteAttrib::C_all;
2496 _has_scene_graph_color =
false;
2497 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2498 _transform_stale =
true;
2499 _color_blend_involves_color_scale =
false;
2500 _texture_involves_color_scale =
false;
2501 _vertex_colors_enabled =
true;
2502 _lighting_enabled =
false;
2503 _num_lights_enabled = 0;
2504 _num_clip_planes_enabled = 0;
2505 _clip_planes_enabled =
false;
2507 _color_scale_enabled =
false;
2508 _current_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
2509 _has_texture_alpha_scale =
false;
2511 _has_material_force_color =
false;
2512 _material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2513 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
2515 _tex_gen_modifies_mat =
false;
2516 _last_max_stage_index = 0;
2566 get_cs_transform_for(CoordinateSystem cs)
const {
2567 if (_coordinate_system == cs) {
2569 return _cs_transform;
2571 }
else if (_internal_coordinate_system == CS_default ||
2572 _internal_coordinate_system == cs) {
2573 return TransformState::make_identity();
2576 return TransformState::make_mat
2577 (LMatrix4::convert_mat(cs, _internal_coordinate_system));
2588 get_cs_transform()
const {
2589 return _cs_transform;
2596 void GraphicsStateGuardian::
2597 do_issue_clip_plane() {
2598 int num_enabled = 0;
2599 int num_on_planes = 0;
2602 _target_rs->get_attrib_def(ClipPlaneAttrib::get_class_slot());
2604 if (target_clip_plane !=
nullptr) {
2605 CPT(
ClipPlaneAttrib) new_plane = target_clip_plane->filter_to_max(_max_clip_planes);
2608 for (
int li = 0; li < num_on_planes; li++) {
2609 NodePath plane = new_plane->get_on_plane(li);
2612 DCAST_INTO_V(plane_node, plane.
node());
2615 if (!_clip_planes_enabled) {
2616 enable_clip_planes(
true);
2617 _clip_planes_enabled =
true;
2620 enable_clip_plane(num_enabled,
true);
2621 if (num_enabled == 0) {
2622 begin_bind_clip_planes();
2625 bind_clip_plane(plane, num_enabled);
2632 for (i = num_enabled; i < _num_clip_planes_enabled; ++i) {
2633 enable_clip_plane(i,
false);
2635 _num_clip_planes_enabled = num_enabled;
2638 if (num_enabled == 0) {
2639 if (_clip_planes_enabled) {
2640 enable_clip_planes(
false);
2641 _clip_planes_enabled =
false;
2644 end_bind_clip_planes();
2659 _target_rs->get_attrib_def(ColorAttrib::get_class_slot());
2662 case ColorAttrib::T_flat:
2665 _scene_graph_color = target_color->
get_color();
2666 _has_scene_graph_color =
true;
2667 _vertex_colors_enabled =
false;
2670 case ColorAttrib::T_off:
2673 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2674 _has_scene_graph_color =
false;
2675 _vertex_colors_enabled =
false;
2678 case ColorAttrib::T_vertex:
2681 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2682 _has_scene_graph_color =
false;
2683 _vertex_colors_enabled =
true;
2687 if (_color_scale_via_lighting) {
2688 _state_mask.
clear_bit(LightAttrib::get_class_slot());
2689 _state_mask.
clear_bit(MaterialAttrib::get_class_slot());
2691 determine_light_color_scale();
2698 void GraphicsStateGuardian::
2699 do_issue_color_scale() {
2702 if (_has_texture_alpha_scale) {
2703 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2707 _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot());
2709 _color_scale_enabled = target_color_scale->
has_scale();
2710 _current_color_scale = target_color_scale->
get_scale();
2711 _has_texture_alpha_scale =
false;
2713 if (_color_blend_involves_color_scale) {
2714 _state_mask.
clear_bit(TransparencyAttrib::get_class_slot());
2716 if (_texture_involves_color_scale) {
2717 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2719 if (_color_scale_via_lighting) {
2720 _state_mask.
clear_bit(LightAttrib::get_class_slot());
2721 _state_mask.
clear_bit(MaterialAttrib::get_class_slot());
2723 determine_light_color_scale();
2726 if (_alpha_scale_via_texture && !_has_scene_graph_color &&
2730 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2731 _state_mask.
clear_bit(TexMatrixAttrib::get_class_slot());
2733 _has_texture_alpha_scale =
true;
2753 LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
2756 int num_enabled = 0;
2757 bool any_on_lights =
false;
2760 _target_rs->get_attrib_def(target_light);
2762 if (display_cat.is_spam()) {
2764 <<
"do_issue_light: " << target_light <<
"\n";
2766 if (target_light !=
nullptr) {
2771 for (
size_t li = 0; li < filtered_lights; ++li) {
2775 nassertv(light_obj !=
nullptr);
2778 if (!_lighting_enabled) {
2779 enable_lighting(
true);
2780 _lighting_enabled =
true;
2783 const LColor &color = light_obj->
get_color();
2785 if (color[0] != 0.0 || color[1] != 0.0 || color[2] != 0.0) {
2786 enable_light(num_enabled,
true);
2787 if (num_enabled == 0) {
2788 begin_bind_lights();
2791 light_obj->bind(
this, light, num_enabled);
2797 for (i = num_enabled; i < _num_lights_enabled; ++i) {
2798 enable_light(i,
false);
2800 _num_lights_enabled = num_enabled;
2803 if (!any_on_lights) {
2804 if (_color_scale_via_lighting && (_has_material_force_color || _light_color_scale != LVecBase4(1.0f, 1.0f, 1.0f, 1.0f))) {
2806 if (!_lighting_enabled) {
2807 enable_lighting(
true);
2808 _lighting_enabled =
true;
2810 set_ambient_light(LColor(1.0f, 1.0f, 1.0f, 1.0f));
2813 if (_lighting_enabled) {
2814 enable_lighting(
false);
2815 _lighting_enabled =
false;
2821 if (!_lighting_enabled) {
2822 enable_lighting(
true);
2823 _lighting_enabled =
true;
2826 set_ambient_light(target_light->get_ambient_contribution());
2829 if (num_enabled != 0) {
2891 void GraphicsStateGuardian::
2892 init_frame_pstats() {
2894 _data_transferred_pcollector.clear_level();
2895 _vertex_buffer_switch_pcollector.clear_level();
2896 _index_buffer_switch_pcollector.clear_level();
2898 _primitive_batches_pcollector.clear_level();
2899 _primitive_batches_tristrip_pcollector.clear_level();
2900 _primitive_batches_trifan_pcollector.clear_level();
2901 _primitive_batches_tri_pcollector.clear_level();
2902 _primitive_batches_patch_pcollector.clear_level();
2903 _primitive_batches_other_pcollector.clear_level();
2904 _vertices_tristrip_pcollector.clear_level();
2905 _vertices_trifan_pcollector.clear_level();
2906 _vertices_tri_pcollector.clear_level();
2907 _vertices_patch_pcollector.clear_level();
2908 _vertices_other_pcollector.clear_level();
2910 _state_pcollector.clear_level();
2911 _transform_state_pcollector.clear_level();
2912 _texture_state_pcollector.clear_level();
2922 create_gamma_table (PN_stdfloat gamma,
unsigned short *red_table,
unsigned short *green_table,
unsigned short *blue_table) {
2930 for (i = 0; i < 256; i++) {
2933 PN_stdfloat gamma_correction;
2935 x = ((double) i / 255.0);
2936 gamma_correction = 1.0 / gamma;
2937 x = pow (x, (
double) gamma_correction);
2943 red_table [i] = (int)g;
2944 green_table [i] = (int)g;
2945 blue_table [i] = (int)g;
2954 void GraphicsStateGuardian::
2955 reissue_transforms() {
2963 void GraphicsStateGuardian::
2964 enable_lighting(
bool enable) {
2972 void GraphicsStateGuardian::
2973 set_ambient_light(
const LColor &color) {
2981 void GraphicsStateGuardian::
2982 enable_light(
int light_id,
bool enable) {
2993 void GraphicsStateGuardian::
2994 begin_bind_lights() {
3003 void GraphicsStateGuardian::
3012 void GraphicsStateGuardian::
3013 enable_clip_planes(
bool enable) {
3021 void GraphicsStateGuardian::
3022 enable_clip_plane(
int plane_id,
bool enable) {
3033 void GraphicsStateGuardian::
3034 begin_bind_clip_planes() {
3042 void GraphicsStateGuardian::
3043 bind_clip_plane(
const NodePath &plane,
int plane_id) {
3052 void GraphicsStateGuardian::
3053 end_bind_clip_planes() {
3059 void GraphicsStateGuardian::
3060 determine_target_texture() {
3062 _target_rs->get_attrib_def(TextureAttrib::get_class_slot());
3064 _target_rs->get_attrib_def(TexGenAttrib::get_class_slot());
3066 nassertv(target_texture !=
nullptr &&
3067 target_tex_gen !=
nullptr);
3068 _target_texture = target_texture;
3069 _target_tex_gen = target_tex_gen;
3071 if (_has_texture_alpha_scale) {
3075 _target_texture = DCAST(
TextureAttrib, _target_texture->add_on_stage(stage, texture));
3076 _target_tex_gen = DCAST(
TexGenAttrib, _target_tex_gen->add_stage
3077 (stage, TexGenAttrib::M_constant, LTexCoord3(_current_color_scale[3], 0.0f, 0.0f)));
3081 _target_texture = _target_texture->filter_to_max(max_texture_stages);
3082 nassertv(_target_texture->get_num_on_stages() <= max_texture_stages);
3088 void GraphicsStateGuardian::
3089 determine_target_shader() {
3090 if (_target_rs->_generated_shader !=
nullptr) {
3091 _target_shader = (
const ShaderAttrib *)_target_rs->_generated_shader.p();
3094 _target_rs->get_attrib_def(ShaderAttrib::get_class_slot());
3101 void GraphicsStateGuardian::
3110 void GraphicsStateGuardian::
3117 _closing_gsg =
true;
3119 if (display_cat.is_debug()) {
3121 <<
this <<
" close_gsg " << get_type() <<
"\n";
3135 _prepared_objects.clear();
3137 _pending_timer_queries.clear();
3148 void GraphicsStateGuardian::
3149 panic_deactivate() {
3152 <<
"Deactivating " << get_type() <<
".\n";
3154 throw_event(
"panic-deactivate-gsg",
this);
3163 void GraphicsStateGuardian::
3164 determine_light_color_scale() {
3165 if (_has_scene_graph_color) {
3169 _has_material_force_color =
true;
3170 _material_force_color = _scene_graph_color;
3171 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3172 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3173 _material_force_color.set(_scene_graph_color[0] * _current_color_scale[0],
3174 _scene_graph_color[1] * _current_color_scale[1],
3175 _scene_graph_color[2] * _current_color_scale[2],
3176 _scene_graph_color[3] * _current_color_scale[3]);
3179 }
else if (!_vertex_colors_enabled) {
3183 _has_material_force_color =
true;
3184 _material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
3185 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3186 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3187 _material_force_color.componentwise_mult(_current_color_scale);
3193 _has_material_force_color =
false;
3194 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3195 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3196 _light_color_scale = _current_color_scale;
3207 if (state ==
nullptr) {
3208 state = RenderState::make(LightAttrib::make_all_off());
3217 get_unclipped_state() {
3219 if (state ==
nullptr) {
3220 state = RenderState::make(ClipPlaneAttrib::make_all_off());
3229 get_untextured_state() {
3231 if (state ==
nullptr) {
3232 state = RenderState::make(TextureAttrib::make_off());
3246 nassertr(_loader !=
nullptr,
nullptr);
3249 if (_current_display_region !=
nullptr) {
3250 priority = _current_display_region->get_texture_reload_priority();
3253 string task_name = string(
"reload:") + tc->
get_texture()->get_name();
3259 for (
size_t ti = 0; ti < num_tasks; ++ti) {
3261 if (task->
is_exact_type(TextureReloadRequest::get_class_type()) &&
3274 _supports_compressed_texture);
3275 request->set_priority(priority);
3276 _loader->load_async(request);
3288 bool is_point = node->
is_of_type(PointLight::get_class_type());
3289 nassertr(node->
is_of_type(DirectionalLight::get_class_type()) ||
3290 node->
is_of_type(Spotlight::get_class_type()) ||
3294 if (light ==
nullptr || !light->_shadow_caster) {
3297 if (node->
is_of_type(PointLight::get_class_type())) {
3298 return get_dummy_shadow_map(Texture::TT_cube_map);
3300 return get_dummy_shadow_map(Texture::TT_2d_texture);
3305 nassertr(light->_shadow_map !=
nullptr,
nullptr);
3308 if (light->_sbuffers.count(
this) != 0) {
3310 return light->_shadow_map;
3313 if (display_cat.is_debug()) {
3315 <<
"Constructing shadow buffer for light '" << light->get_name()
3316 <<
"', size=" << light->_sb_size[0] <<
"x" << light->_sb_size[1]
3317 <<
", sort=" << light->_sb_sort <<
"\n";
3320 if (host ==
nullptr) {
3321 nassertr(_current_display_region !=
nullptr,
nullptr);
3322 host = _current_display_region->get_window();
3324 nassertr(host !=
nullptr,
nullptr);
3327 GraphicsOutput *sbuffer = make_shadow_buffer(light, light->_shadow_map,
3332 for (
int i = 0; i < 6; ++i) {
3335 dr->set_target_tex_page(i);
3336 dr->set_camera(light_np);
3337 dr->set_clear_depth_active(
true);
3342 dr->set_clear_depth_active(
true);
3345 light->_sbuffers[
this] = sbuffer;
3346 return light->_shadow_map;
3354 get_dummy_shadow_map(Texture::TextureType texture_type)
const {
3355 if (texture_type != Texture::TT_cube_map) {
3357 if (dummy_2d ==
nullptr) {
3358 dummy_2d =
new Texture(
"dummy-shadow-2d");
3359 dummy_2d->setup_2d_texture(1, 1, Texture::T_unsigned_byte, Texture::F_depth_component);
3360 dummy_2d->set_clear_color(1);
3363 dummy_2d->set_minfilter(SamplerState::FT_shadow);
3364 dummy_2d->set_magfilter(SamplerState::FT_shadow);
3366 dummy_2d->set_minfilter(SamplerState::FT_linear);
3367 dummy_2d->set_magfilter(SamplerState::FT_linear);
3372 static PT(
Texture) dummy_cube;
3373 if (dummy_cube ==
nullptr) {
3374 dummy_cube =
new Texture(
"dummy-shadow-cube");
3375 dummy_cube->setup_cube_map(1, Texture::T_unsigned_byte, Texture::F_depth_component);
3376 dummy_cube->set_clear_color(1);
3378 dummy_cube->set_minfilter(SamplerState::FT_linear);
3379 dummy_cube->set_magfilter(SamplerState::FT_linear);
3391 bool is_point = light->
is_of_type(PointLight::get_class_type());
3395 fbp.set_depth_bits(shadow_depth_bits);
3398 int flags = GraphicsPipe::BF_refuse_window;
3400 flags |= GraphicsPipe::BF_size_square;
3407 light->get_name(), light->_sb_sort, fbp, props, flags,
this, host);
3409 if (sbuffer !=
nullptr) {
3410 sbuffer->
add_render_texture(tex, GraphicsOutput::RTM_bind_or_copy, GraphicsOutput::RTP_depth);
3423 state->get_attrib_def(shader_attrib);
3426 if (_shader_generator ==
nullptr) {
3427 if (!_supports_basic_shaders) {
3432 if (state->_generated_shader ==
nullptr ||
3433 state->_generated_shader_seq != _generated_shader_seq) {
3439 state->get_attrib_def(sattr);
3440 if (sattr->get_flag(ShaderAttrib::F_hardware_skinning)) {
3445 state->_generated_shader = _shader_generator->synthesize_shader(state, spec);
3446 state->_generated_shader_seq = _generated_shader_seq;
3523 operator << (std::ostream &out, GraphicsStateGuardian::ShaderModel sm) {
3524 static const char *sm_strings[] = {
"none",
"1.1",
"2.0",
"2.x",
"3.0",
"4.0",
"5.0",
"5.1"};
3525 nassertr(sm >= 0 && sm <= GraphicsStateGuardian::SM_51, out);
3526 out << sm_strings[sm];