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());
332 bool GraphicsStateGuardian::
333 get_supports_multisample()
const {
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;
416 get_prepared_objects() {
417 return _prepared_objects;
433 PN_stdfloat GraphicsStateGuardian::
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;
504 Texture *GraphicsStateGuardian::
505 get_flash_texture()
const {
506 return _flash_texture;
518 _scene_setup = scene_setup;
519 _current_lens = scene_setup->
get_lens();
520 if (_current_lens ==
nullptr) {
526 _projection_mat = calc_projection_mat(_current_lens);
527 if (_projection_mat ==
nullptr) {
530 _projection_mat_inv = _projection_mat->get_inverse();
714 nassertv(_current_occlusion_query ==
nullptr);
724 end_occlusion_query() {
725 nassertr(_current_occlusion_query !=
nullptr,
nullptr);
727 _current_occlusion_query =
nullptr;
736 issue_timer_query(
int pstats_index) {
746 nassert_raise(
"Compute shaders not supported by GSG");
762 int mi = state->_last_mi;
765 if (munger->is_registered()) {
771 mi = mungers.
find(_id);
774 if (munger->is_registered()) {
775 state->_last_mi = mi;
785 PT(
GeomMunger) munger = make_geom_munger(state, current_thread);
786 nassertr(munger !=
nullptr && munger->is_registered(), munger);
787 nassertr(munger->is_of_type(StateMunger::get_class_type()), munger);
789 state->_last_mi = mungers.
store(_id, munger);
812 switch (_internal_coordinate_system) {
827 <<
"Invalid coordinate system in compute_distance_to: " 828 << (int)_internal_coordinate_system <<
"\n";
862 if (altered & spec._dep[0]) {
863 const LMatrix4 *t =
fetch_specified_part(spec._part[0], spec._arg[0], spec._cache[0], spec._index);
864 if (t != &spec._cache[0]) {
868 if (altered & spec._dep[1]) {
869 const LMatrix4 *t =
fetch_specified_part(spec._part[1], spec._arg[1], spec._cache[1], spec._index);
870 if (t != &spec._cache[1]) {
876 case Shader::SMF_compose:
877 spec._value.multiply(spec._cache[0], spec._cache[1]);
879 case Shader::SMF_transform_dlight:
880 spec._value = spec._cache[0];
881 v = spec._cache[1].xform_vec(spec._cache[0].get_row3(2));
883 spec._value.set_row(2, v);
884 v = spec._cache[1].xform_vec(spec._cache[0].get_row3(3));
886 spec._value.set_row(3, v);
888 case Shader::SMF_transform_plight:
891 spec._value = spec._cache[0];
892 LPoint3 point = spec._cache[1].xform_point(spec._cache[0].get_row3(2));
893 spec._value(2, 0) = point[0];
894 spec._value(2, 1) = point[1];
895 spec._value(2, 2) = point[2];
898 case Shader::SMF_transform_slight:
899 spec._value = spec._cache[0];
900 spec._value.set_row(2, spec._cache[1].xform_point(spec._cache[0].get_row3(2)));
901 v = spec._cache[1].xform_vec(spec._cache[0].get_row3(3));
903 spec._value.set_row(3, v);
905 case Shader::SMF_first:
906 return &spec._cache[0];
909 spec._value = LMatrix4::ident_mat();
919 LMatrix4 &t,
int index) {
921 case Shader::SMO_identity: {
922 return &LMatrix4::ident_mat();
924 case Shader::SMO_window_size:
925 case Shader::SMO_pixel_size: {
926 LVecBase2i pixel_size = _current_display_region->get_pixel_size();
927 t = LMatrix4::translate_mat(pixel_size[0], pixel_size[1], 0);
930 case Shader::SMO_frame_time: {
932 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time);
935 case Shader::SMO_frame_delta: {
937 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt);
940 case Shader::SMO_texpad_x: {
941 Texture *tex = _target_shader->get_shader_input_texture(name);
942 nassertr(tex !=
nullptr, &LMatrix4::zeros_mat());
949 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cx, cy, cz, 0);
952 case Shader::SMO_texpix_x: {
953 Texture *tex = _target_shader->get_shader_input_texture(name);
954 nassertr(tex !=
nullptr, &LMatrix4::zeros_mat());
958 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, px, py, pz, 0);
961 case Shader::SMO_attr_material: {
963 _target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
965 if (target_material->
is_off()) {
966 t.set(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0);
975 t.set(amb[0], amb[1], amb[2], amb[3],
976 dif[0], dif[1], dif[2], dif[3],
977 emm[0], emm[1], emm[2], emm[3],
978 spc[0], spc[1], spc[2], spc[3]);
981 case Shader::SMO_attr_material2: {
983 _target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
984 if (target_material->
is_off()) {
985 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
993 case Shader::SMO_attr_color: {
995 _target_rs->get_attrib_def(ColorAttrib::get_class_slot());
997 return &LMatrix4::ones_mat();
1000 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
1003 case Shader::SMO_attr_colorscale: {
1005 _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot());
1007 return &LMatrix4::ones_mat();
1009 LVecBase4 cs = target_color->
get_scale();
1010 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cs[0], cs[1], cs[2], cs[3]);
1013 case Shader::SMO_attr_fog: {
1015 _target_rs->get_attrib_def(FogAttrib::get_class_slot());
1017 if (fog ==
nullptr) {
1018 return &LMatrix4::ones_mat();
1020 PN_stdfloat start, end;
1022 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1026 case Shader::SMO_attr_fogcolor: {
1028 _target_rs->get_attrib_def(FogAttrib::get_class_slot());
1030 if (fog ==
nullptr) {
1031 return &LMatrix4::ones_mat();
1034 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
1037 case Shader::SMO_alight_x: {
1038 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1039 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1041 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1042 LColor
const &c = lt->get_color();
1043 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
1046 case Shader::SMO_satten_x: {
1047 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1048 nassertr(!np.
is_empty(), &LMatrix4::ones_mat());
1050 DCAST_INTO_R(lt, np.
node(), &LMatrix4::ones_mat());
1051 LVecBase3
const &a = lt->get_attenuation();
1052 PN_stdfloat x = lt->get_exponent();
1053 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a[0], a[1], a[2], x);
1056 case Shader::SMO_dlight_x: {
1058 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1059 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1061 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1062 LColor
const &c = lt->get_color();
1063 LColor
const &s = lt->get_specular_color();
1064 t = np.get_net_transform()->
get_mat() *
1065 _scene_setup->get_world_transform()->get_mat();
1066 LVecBase3 d = -(t.xform_vec(lt->get_direction()));
1068 LVecBase3 h = d + LVecBase3(0,-1,0);
1070 t.set(c[0], c[1], c[2], c[3],
1071 s[0], s[1], s[2], c[3],
1072 d[0], d[1], d[2], 0,
1073 h[0], h[1], h[2], 0);
1076 case Shader::SMO_plight_x: {
1078 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1079 nassertr(!np.
is_empty(), &LMatrix4::ones_mat());
1081 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1082 LColor
const &c = lt->get_color();
1083 LColor
const &s = lt->get_specular_color();
1084 t = np.get_net_transform()->
get_mat() *
1085 _scene_setup->get_world_transform()->get_mat();
1086 LVecBase3 p = (t.xform_point(lt->get_point()));
1087 LVecBase3 a = lt->get_attenuation();
1088 Lens *lens = lt->get_lens(0);
1089 PN_stdfloat lnear = lens->
get_near();
1090 PN_stdfloat lfar = lens->
get_far();
1091 t.set(c[0], c[1], c[2], c[3],
1092 s[0], s[1], s[2], s[3],
1093 p[0], p[1], p[2], lnear,
1094 a[0], a[1], a[2], lfar);
1097 case Shader::SMO_slight_x: {
1099 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1100 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1102 DCAST_INTO_R(lt, np.
node(), &LMatrix4::zeros_mat());
1103 Lens *lens = lt->get_lens();
1104 nassertr(lens !=
nullptr, &LMatrix4::zeros_mat());
1105 LColor
const &c = lt->get_color();
1106 LColor
const &s = lt->get_specular_color();
1107 PN_stdfloat cutoff = ccos(deg_2_rad(lens->get_hfov() * 0.5f));
1108 t = np.get_net_transform()->
get_mat() *
1109 _scene_setup->get_world_transform()->get_mat();
1110 LVecBase3 p = t.xform_point(lens->get_nodal_point());
1111 LVecBase3 d = -(t.xform_vec(lens->get_view_vector()));
1112 t.set(c[0], c[1], c[2], c[3],
1113 s[0], s[1], s[2], s[3],
1114 p[0], p[1], p[2], 0,
1115 d[0], d[1], d[2], cutoff);
1118 case Shader::SMO_light_ambient: {
1119 LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
1121 _target_rs->get_attrib_def(LightAttrib::get_class_slot());
1126 t.set_row(3, LVecBase4(1, 1, 1, 1));
1128 t.set_row(3, target_light->get_ambient_contribution());
1132 case Shader::SMO_texmat_i: {
1135 if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
1139 return &LMatrix4::ident_mat();
1142 case Shader::SMO_inv_texmat_i: {
1145 if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
1147 t = tma->get_transform(ta->
get_on_stage(index))->get_inverse()->get_mat();
1150 return &LMatrix4::ident_mat();
1153 case Shader::SMO_texscale_i: {
1156 if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
1158 LVecBase3 scale = tma->get_transform(ta->
get_on_stage(index))->get_scale();
1159 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, scale[0], scale[1], scale[2], 0);
1162 return &LMatrix4::ident_mat();
1165 case Shader::SMO_texcolor_i: {
1172 return &LMatrix4::zeros_mat();
1175 case Shader::SMO_tex_is_alpha_i: {
1179 if (_target_rs->get_attrib(ta) &&
1182 PN_stdfloat v = (ta->
get_on_texture(ts)->get_format() == Texture::F_alpha);
1183 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v, v, v, 0);
1186 return &LMatrix4::zeros_mat();
1189 case Shader::SMO_plane_x: {
1190 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1191 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1193 DCAST_INTO_R(plane_node, np.
node(), &LMatrix4::zeros_mat());
1194 LPlane p = plane_node->get_plane();
1195 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, p[0], p[1], p[2], p[3]);
1198 case Shader::SMO_clipplane_x: {
1200 _target_rs->get_attrib_def(cpa);
1201 int planenr = atoi(name->
get_name().c_str());
1203 return &LMatrix4::zeros_mat();
1206 nassertr(!np.
is_empty(), &LMatrix4::zeros_mat());
1208 DCAST_INTO_R(plane_node, np.
node(), &LMatrix4::zeros_mat());
1212 LPlane plane = plane_node->get_plane();
1213 if (!transform->is_identity()) {
1214 plane.xform(transform->get_mat());
1216 t.set_row(3, plane);
1219 case Shader::SMO_apiview_clipplane_i: {
1221 _target_rs->get_attrib_def(cpa);
1223 return &LMatrix4::zeros_mat();
1227 nassertr(!plane.
is_empty(), &LMatrix4::zeros_mat());
1229 DCAST_INTO_R(plane_node, plane.
node(), &LMatrix4::zeros_mat());
1232 _scene_setup->get_cs_world_transform()->compose(
1233 plane.
get_transform(_scene_setup->get_scene_root().get_parent()));
1235 LPlane xformed_plane = plane_node->get_plane() * transform->get_mat();
1236 t.set_row(3, xformed_plane);
1239 case Shader::SMO_mat_constant_x: {
1240 return &_target_shader->get_shader_input_matrix(name, t);
1242 case Shader::SMO_vec_constant_x: {
1243 const LVecBase4 &input = _target_shader->get_shader_input_vector(name);
1244 const PN_stdfloat *data = input.get_data();
1245 t.set(data[0], data[1], data[2], data[3],
1246 data[0], data[1], data[2], data[3],
1247 data[0], data[1], data[2], data[3],
1248 data[0], data[1], data[2], data[3]);
1251 case Shader::SMO_world_to_view: {
1252 return &(_scene_setup->get_world_transform()->get_mat());
1254 case Shader::SMO_view_to_world: {
1255 return &(_scene_setup->get_camera_transform()->get_mat());
1257 case Shader::SMO_model_to_view: {
1258 t = _inv_cs_transform->compose(_internal_transform)->get_mat();
1261 case Shader::SMO_model_to_apiview: {
1262 return &(_internal_transform->get_mat());
1264 case Shader::SMO_view_to_model: {
1265 t = _internal_transform->invert_compose(_cs_transform)->get_mat();
1268 case Shader::SMO_apiview_to_model: {
1269 t = _internal_transform->get_inverse()->get_mat();
1272 case Shader::SMO_apiview_to_view: {
1273 return &(_inv_cs_transform->get_mat());
1275 case Shader::SMO_view_to_apiview: {
1276 return &(_cs_transform->get_mat());
1278 case Shader::SMO_clip_to_view: {
1279 if (_current_lens->get_coordinate_system() == _coordinate_system) {
1280 return &(_current_lens->get_projection_mat_inv(_current_stereo_channel));
1282 t = _current_lens->get_projection_mat_inv(_current_stereo_channel) *
1283 LMatrix4::convert_mat(_current_lens->get_coordinate_system(), _coordinate_system);
1287 case Shader::SMO_view_to_clip: {
1288 if (_current_lens->get_coordinate_system() == _coordinate_system) {
1289 return &(_current_lens->get_projection_mat(_current_stereo_channel));
1291 t = LMatrix4::convert_mat(_coordinate_system, _current_lens->get_coordinate_system()) *
1292 _current_lens->get_projection_mat(_current_stereo_channel);
1296 case Shader::SMO_apiclip_to_view: {
1297 t = _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat();
1300 case Shader::SMO_view_to_apiclip: {
1301 t = _cs_transform->get_mat() * _projection_mat->get_mat();
1304 case Shader::SMO_apiclip_to_apiview: {
1305 return &(_projection_mat_inv->get_mat());
1307 case Shader::SMO_apiview_to_apiclip: {
1308 return &(_projection_mat->get_mat());
1310 case Shader::SMO_view_x_to_view: {
1311 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1312 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1313 t = np.get_net_transform()->
get_mat() *
1314 _scene_setup->get_world_transform()->get_mat();
1317 case Shader::SMO_view_to_view_x: {
1318 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1319 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1320 t = _scene_setup->get_camera_transform()->get_mat() *
1321 np.get_net_transform()->get_inverse()->
get_mat();
1324 case Shader::SMO_apiview_x_to_view: {
1325 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1326 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1327 t = LMatrix4::convert_mat(_internal_coordinate_system, _coordinate_system) *
1328 np.get_net_transform()->
get_mat() *
1329 _scene_setup->get_world_transform()->get_mat();
1332 case Shader::SMO_view_to_apiview_x: {
1333 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1334 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1335 t = (_scene_setup->get_camera_transform()->get_mat() *
1336 np.get_net_transform()->get_inverse()->
get_mat() *
1337 LMatrix4::convert_mat(_coordinate_system, _internal_coordinate_system));
1340 case Shader::SMO_clip_x_to_view: {
1341 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1342 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1344 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1345 const Lens *lens = node->get_lens();
1347 LMatrix4::convert_mat(lens->get_coordinate_system(), _coordinate_system) *
1348 np.get_net_transform()->
get_mat() *
1349 _scene_setup->get_world_transform()->get_mat();
1352 case Shader::SMO_view_to_clip_x: {
1353 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1354 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1356 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1357 const Lens *lens = node->get_lens();
1358 t = _scene_setup->get_camera_transform()->get_mat() *
1359 np.get_net_transform()->get_inverse()->
get_mat() *
1360 LMatrix4::convert_mat(_coordinate_system, lens->get_coordinate_system()) *
1361 lens->get_projection_mat(_current_stereo_channel);
1364 case Shader::SMO_apiclip_x_to_view: {
1365 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1366 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1368 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1369 const Lens *lens = node->get_lens();
1370 t = calc_projection_mat(lens)->get_inverse()->get_mat() *
1371 get_cs_transform_for(lens->get_coordinate_system())->get_inverse()->get_mat() *
1372 np.get_net_transform()->
get_mat() *
1373 _scene_setup->get_world_transform()->get_mat();
1376 case Shader::SMO_view_to_apiclip_x: {
1377 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1378 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1380 DCAST_INTO_R(node, np.
node(), &LMatrix4::ident_mat());
1381 const Lens *lens = node->get_lens();
1382 t = _scene_setup->get_camera_transform()->get_mat() *
1383 np.get_net_transform()->get_inverse()->
get_mat() *
1384 get_cs_transform_for(lens->get_coordinate_system())->get_mat() *
1385 calc_projection_mat(lens)->get_mat();
1388 case Shader::SMO_mat_constant_x_attrib: {
1389 if (_target_shader->has_shader_input(name)) {
1392 return &_target_shader->get_shader_input_matrix(name, t);
1396 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1400 case Shader::SMO_vec_constant_x_attrib: {
1401 if (_target_shader->has_shader_input(name)) {
1404 const LVecBase4 &data = _target_shader->get_shader_input_vector(name);
1405 t.set(data[0], data[1], data[2], data[3],
1406 data[0], data[1], data[2], data[3],
1407 data[0], data[1], data[2], data[3],
1408 data[0], data[1], data[2], data[3]);
1413 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1417 case Shader::SMO_light_source_i_attrib: {
1419 _target_rs->get_attrib_def(target_light);
1424 if (index >= 0 && (
size_t)index < num_lights) {
1426 nassertr(!light.
is_empty(), &LMatrix4::ident_mat());
1428 nassertr(light_obj !=
nullptr, &LMatrix4::ident_mat());
1432 }
else if (index == 0) {
1436 if (basename ==
"color" || basename ==
"diffuse") {
1437 t.set_row(3, _light_color_scale);
1439 }
else if (basename ==
"specular") {
1440 return &LMatrix4::ones_mat();
1445 case Shader::SMO_light_source_i_packed: {
1448 _target_rs->get_attrib_def(target_light);
1453 if (index >= 0 && (
size_t)index < num_lights) {
1455 nassertr(!np.
is_empty(), &LMatrix4::ident_mat());
1457 Light *light = node->as_light();
1458 nassertr(light !=
nullptr, &LMatrix4::zeros_mat());
1462 LMatrix4 mat = np.get_net_transform()->
get_mat() *
1463 _scene_setup->get_world_transform()->get_mat();
1465 if (node->is_of_type(DirectionalLight::get_class_type())) {
1466 LVecBase3 d = mat.xform_vec(((
const DirectionalLight *)node)->get_direction());
1468 t.set_row(2, LVecBase4(d, 0));
1469 t.set_row(3, LVecBase4(-d, 0));
1471 }
else if (node->is_of_type(LightLensNode::get_class_type())) {
1475 t.set_row(3, LVecBase4(p));
1479 if (node->is_of_type(Spotlight::get_class_type())) {
1480 PN_stdfloat cutoff = ccos(deg_2_rad(lens->
get_hfov() * 0.5f));
1482 t.set_cell(1, 3, ((
const Spotlight *)node)->get_exponent());
1483 t.set_row(2, LVecBase4(d, cutoff));
1485 }
else if (node->is_of_type(PointLight::get_class_type())) {
1486 t.set_cell(1, 3, lens->
get_far());
1487 t.set_cell(3, 3, lens->
get_near());
1489 if (node->is_of_type(SphereLight::get_class_type())) {
1490 t.set_cell(2, 3, ((
const SphereLight *)node)->get_radius());
1494 }
else if (index == 0) {
1497 t.set_row(0, _light_color_scale);
1502 nassertr(
false , &LMatrix4::ident_mat());
1503 return &LMatrix4::ident_mat();
1525 static const CPT_InternalName IN_constantAttenuation(
"constantAttenuation");
1527 static const CPT_InternalName IN_quadraticAttenuation(
"quadraticAttenuation");
1535 if (attrib == IN_color) {
1536 if (node ==
nullptr) {
1537 return &LMatrix4::ident_mat();
1540 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1542 c.componentwise_mult(_light_color_scale);
1546 }
else if (attrib == IN_ambient) {
1547 if (node ==
nullptr) {
1548 return &LMatrix4::ident_mat();
1551 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1554 c.componentwise_mult(_light_color_scale);
1558 t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
1562 }
else if (attrib == IN_diffuse) {
1563 if (node ==
nullptr) {
1564 return &LMatrix4::ident_mat();
1567 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1570 t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
1573 c.componentwise_mult(_light_color_scale);
1578 }
else if (attrib == IN_specular) {
1579 if (node ==
nullptr) {
1580 return &LMatrix4::ident_mat();
1583 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1587 }
else if (attrib == IN_position) {
1589 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
1593 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1595 }
else if (node->
is_of_type(DirectionalLight::get_class_type())) {
1597 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1600 LVector3 dir = -(light->
get_direction() * transform->get_mat());
1601 dir *= _scene_setup->get_cs_world_transform()->
get_mat();
1602 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 0);
1606 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1608 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1611 _scene_setup->get_cs_world_transform()->compose(
1612 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1614 const LMatrix4 &light_mat = transform->get_mat();
1616 t = LMatrix4::translate_mat(pos);
1620 }
else if (attrib == IN_halfVector) {
1622 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
1626 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1628 }
else if (node->
is_of_type(DirectionalLight::get_class_type())) {
1630 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1633 LVector3 dir = -(light->
get_direction() * transform->get_mat());
1634 dir *= _scene_setup->get_cs_world_transform()->
get_mat();
1636 dir += LVector3(0, 0, 1);
1638 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 1);
1642 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1644 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1647 _scene_setup->get_cs_world_transform()->compose(
1648 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1650 const LMatrix4 &light_mat = transform->get_mat();
1653 pos += LVector3(0, 0, 1);
1655 t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pos[0],pos[1],pos[2], 1);
1659 }
else if (attrib == IN_spotDirection) {
1660 if (node ==
nullptr) {
1661 t.set_row(3, LVector3(0.0f, 0.0f, -1.0f));
1665 t.set_row(3, LVector3(0.0f, 0.0f, 0.0f));
1669 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1671 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1674 _scene_setup->get_cs_world_transform()->compose(
1675 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1677 const LMatrix4 &light_mat = transform->get_mat();
1683 }
else if (attrib == IN_spotCutoff) {
1684 if (node !=
nullptr &&
1685 node->
is_of_type(Spotlight::get_class_type())) {
1687 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1689 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1691 float cutoff = lens->
get_hfov() * 0.5f;
1692 t.set_row(3, LVecBase4(cutoff));
1696 t.set_row(3, LVecBase4(180));
1700 }
else if (attrib == IN_spotCosCutoff) {
1701 if (node !=
nullptr &&
1702 node->
is_of_type(Spotlight::get_class_type())) {
1704 DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
1706 nassertr(lens !=
nullptr, &LMatrix4::ident_mat());
1708 float cutoff = lens->
get_hfov() * 0.5f;
1709 t.set_row(3, LVecBase4(ccos(deg_2_rad(cutoff))));
1713 t.set_row(3, LVecBase4(-1));
1717 }
else if (attrib == IN_spotExponent) {
1718 if (node ==
nullptr) {
1719 return &LMatrix4::zeros_mat();
1722 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1727 }
else if (attrib == IN_attenuation) {
1728 if (node !=
nullptr) {
1730 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1734 t.set_row(3, LVecBase4(1, 0, 0, 0));
1738 }
else if (attrib == IN_constantAttenuation) {
1739 if (node ==
nullptr) {
1740 return &LMatrix4::ones_mat();
1743 nassertr(light !=
nullptr, &LMatrix4::ones_mat());
1748 }
else if (attrib == IN_linearAttenuation) {
1749 if (node ==
nullptr) {
1750 return &LMatrix4::zeros_mat();
1753 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1758 }
else if (attrib == IN_quadraticAttenuation) {
1759 if (node ==
nullptr) {
1760 return &LMatrix4::zeros_mat();
1763 nassertr(light !=
nullptr, &LMatrix4::ident_mat());
1768 }
else if (attrib == IN_shadowViewMatrix) {
1769 static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f,
1770 0.0f, 0.5f, 0.0f, 0.0f,
1771 0.0f, 0.0f, 0.5f, 0.0f,
1772 0.5f, 0.5f, 0.5f, 1.0f);
1774 if (node ==
nullptr) {
1779 DCAST_INTO_R(lnode, node, &LMatrix4::ident_mat());
1782 t = _inv_cs_transform->get_mat() *
1783 _scene_setup->get_camera_transform()->get_mat() *
1784 np.get_net_transform()->get_inverse()->
get_mat() *
1787 if (!node->
is_of_type(PointLight::get_class_type())) {
1794 <<
"Shader input requests invalid attribute " << *attrib
1795 <<
" from node " << np <<
"\n";
1796 return &LMatrix4::ident_mat();
1806 switch (spec._part) {
1807 case Shader::STO_named_input:
1809 if (!_target_shader->has_shader_input(spec._name)) {
1812 if (parent != InternalName::get_root() &&
1813 _target_shader->has_shader_input(parent)) {
1816 const string &basename = spec._name->get_basename();
1817 NodePath np = _target_shader->get_shader_input_nodepath(parent);
1819 if (basename ==
"shadowMap") {
1820 PT(
Texture) tex = get_shadow_map(np);
1821 if (tex !=
nullptr) {
1822 sampler = tex->get_default_sampler();
1827 if (spec._stage == 0) {
1829 <<
"Shader input " << *parent
1830 <<
" has no member named " << basename <<
".\n";
1838 if (spec._stage == 0) {
1840 <<
"Shader input " << *spec._name <<
" is not present.\n";
1846 return _target_shader->get_shader_input_texture(spec._name, &sampler);
1850 case Shader::STO_stage_i:
1855 _target_rs->get_attrib_def(texattrib);
1866 case Shader::STO_light_i_shadow_map:
1869 _target_rs->get_attrib_def(target_light);
1874 if (spec._stage >= 0 && (
size_t)spec._stage < num_lights) {
1876 nassertr(!light.
is_empty(),
nullptr);
1878 nassertr(light_obj !=
nullptr,
nullptr);
1880 PT(
Texture) tex = get_shadow_map(light);
1881 if (tex !=
nullptr) {
1882 sampler = tex->get_default_sampler();
1887 PT(
Texture) tex = get_dummy_shadow_map((Texture::TextureType)spec._desired_type);
1888 if (tex !=
nullptr) {
1889 sampler = tex->get_default_sampler();
1897 nassertr(
false,
nullptr);
1909 return (_target_shader->get_shader_input_ptr(spec._arg));
1918 _current_display_region = dr->get_object();
1921 _effective_incomplete_render = _incomplete_render && _current_display_region->get_incomplete_render();
1923 _stereo_buffer_mask = ~0;
1928 switch (output_channel) {
1930 output_channel = Lens::SC_right;
1933 case Lens::SC_right:
1934 output_channel = Lens::SC_left;
1942 switch (output_channel) {
1945 if (_current_properties->is_stereo()) {
1950 case Lens::SC_right:
1952 if (_current_properties->is_stereo()) {
1958 case Lens::SC_stereo:
1959 _color_write_mask = ColorWriteAttrib::C_all;
1982 reissue_transforms();
1985 _state_rs = RenderState::make_empty();
1986 _state_mask.
clear();
1996 nassertv(_engine !=
nullptr);
1998 DCAST_INTO_V(win, window);
2021 calc_projection_mat(
const Lens *lens) {
2022 if (lens ==
nullptr) {
2030 return TransformState::make_identity();
2043 _prepared_objects->begin_frame(
this, current_thread);
2050 _state_rs = RenderState::make_empty();
2051 _state_mask.
clear();
2057 if (_last_query_frame < frame) {
2058 _last_query_frame = frame;
2059 _timer_queries_pcollector.clear_level();
2066 if (_timer_queries_active) {
2069 issue_timer_query(0x8000);
2070 issue_timer_query(0x0000);
2075 return !_needs_reset;
2106 _scene_setup = _scene_null;
2112 for (i = 0; i < _num_lights_enabled; ++i) {
2113 enable_light(i,
false);
2115 _num_lights_enabled = 0;
2118 for (i = 0; i < _num_clip_planes_enabled; ++i) {
2119 enable_clip_plane(i,
false);
2121 _num_clip_planes_enabled = 0;
2124 _state_rs = RenderState::make_empty();
2125 _state_mask.
clear();
2134 _prepared_objects->end_frame(current_thread);
2137 _data_transferred_pcollector.flush_level();
2139 _primitive_batches_pcollector.flush_level();
2140 _primitive_batches_tristrip_pcollector.flush_level();
2141 _primitive_batches_trifan_pcollector.flush_level();
2142 _primitive_batches_tri_pcollector.flush_level();
2143 _primitive_batches_patch_pcollector.flush_level();
2144 _primitive_batches_other_pcollector.flush_level();
2145 _vertices_tristrip_pcollector.flush_level();
2146 _vertices_trifan_pcollector.flush_level();
2147 _vertices_tri_pcollector.flush_level();
2148 _vertices_patch_pcollector.flush_level();
2149 _vertices_other_pcollector.flush_level();
2151 _state_pcollector.flush_level();
2152 _texture_state_pcollector.flush_level();
2153 _transform_state_pcollector.flush_level();
2154 _draw_primitive_pcollector.flush_level();
2157 _prepared_objects->_graphics_memory_lru.begin_epoch();
2171 PStatClient *client = PStatClient::get_global_pstats();
2173 if (!client->client_is_connected()) {
2174 _timer_queries_active =
false;
2178 if (!_timer_queries_active) {
2179 if (pstats_gpu_timing && _supports_timer_query) {
2181 _timer_queries_active =
true;
2189 if (_pstats_gpu_thread == -1) {
2192 PStatThread gpu_thread(client, _pstats_gpu_thread);
2196 if (!_pending_timer_queries.empty()) {
2197 int count = _pending_timer_queries.size();
2204 if (_last_num_queried > 0) {
2207 int i = std::min(_last_num_queried, count) - 1;
2209 if (_pending_timer_queries[i]->is_answer_ready()) {
2211 while (i < count - 1) {
2212 if (!_pending_timer_queries[++i]->is_answer_ready()) {
2220 if (_pending_timer_queries[--i]->is_answer_ready()) {
2231 int step = count / 2;
2232 int i = first + step;
2233 if (_pending_timer_queries[i]->is_answer_ready()) {
2246 _last_num_queried = first;
2248 for (
int i = 0; i < first; ++i) {
2251 double time_data = query->get_timestamp();
2253 if (query->_pstats_index == _command_latency_pcollector.get_index()) {
2256 cdef = client->get_collector_ptr(query->_pstats_index)->get_def(client, query->_pstats_index);
2257 _pstats_gpu_data.add_level(query->_pstats_index, time_data * cdef->_factor);
2259 }
else if (query->_pstats_index & 0x8000) {
2260 _pstats_gpu_data.add_stop(query->_pstats_index & 0x7fff, time_data);
2263 _pstats_gpu_data.add_start(query->_pstats_index & 0x7fff, time_data);
2269 if (query->_pstats_index == 0x8000) {
2271 _pstats_gpu_data.clear();
2278 _pending_timer_queries.erase(
2279 _pending_timer_queries.begin(),
2280 _pending_timer_queries.begin() + first
2282 _timer_queries_pcollector.add_level_now(first);
2305 begin_decal_base_first() {
2308 if (decal_base_first ==
nullptr) {
2309 decal_base_first = RenderState::make
2310 (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
2311 RenderState::get_max_priority());
2313 return decal_base_first;
2323 begin_decal_nested() {
2327 if (decal_nested ==
nullptr) {
2328 decal_nested = RenderState::make
2329 (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
2330 RenderState::get_max_priority());
2332 return decal_nested;
2346 begin_decal_base_second() {
2351 if (decal_base_second ==
nullptr) {
2352 decal_base_second = RenderState::make
2353 (ColorWriteAttrib::make(ColorWriteAttrib::C_off),
2357 RenderState::get_max_priority());
2359 return decal_base_second;
2379 _data_reader = data_reader;
2383 return _data_reader->has_vertex() || (_target_shader && _target_shader->has_shader());
2482 _data_reader =
nullptr;
2490 _needs_reset =
false;
2493 _state_rs = RenderState::make_empty();
2494 _target_rs =
nullptr;
2495 _state_mask.
clear();
2496 _internal_transform = _cs_transform;
2498 _scene_setup = _scene_null;
2500 _color_write_mask = ColorWriteAttrib::C_all;
2502 _has_scene_graph_color =
false;
2503 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2504 _transform_stale =
true;
2505 _color_blend_involves_color_scale =
false;
2506 _texture_involves_color_scale =
false;
2507 _vertex_colors_enabled =
true;
2508 _lighting_enabled =
false;
2509 _num_lights_enabled = 0;
2510 _num_clip_planes_enabled = 0;
2511 _clip_planes_enabled =
false;
2513 _color_scale_enabled =
false;
2514 _current_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
2515 _has_texture_alpha_scale =
false;
2517 _has_material_force_color =
false;
2518 _material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2519 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
2521 _tex_gen_modifies_mat =
false;
2522 _last_max_stage_index = 0;
2572 get_cs_transform_for(CoordinateSystem cs)
const {
2573 if (_coordinate_system == cs) {
2575 return _cs_transform;
2577 }
else if (_internal_coordinate_system == CS_default ||
2578 _internal_coordinate_system == cs) {
2579 return TransformState::make_identity();
2582 return TransformState::make_mat
2583 (LMatrix4::convert_mat(cs, _internal_coordinate_system));
2594 get_cs_transform()
const {
2595 return _cs_transform;
2602 void GraphicsStateGuardian::
2603 do_issue_clip_plane() {
2604 int num_enabled = 0;
2605 int num_on_planes = 0;
2608 _target_rs->get_attrib_def(ClipPlaneAttrib::get_class_slot());
2610 if (target_clip_plane !=
nullptr) {
2611 CPT(
ClipPlaneAttrib) new_plane = target_clip_plane->filter_to_max(_max_clip_planes);
2614 for (
int li = 0; li < num_on_planes; li++) {
2615 NodePath plane = new_plane->get_on_plane(li);
2618 DCAST_INTO_V(plane_node, plane.
node());
2619 if ((plane_node->get_clip_effect() & PlaneNode::CE_visible) != 0) {
2621 if (!_clip_planes_enabled) {
2622 enable_clip_planes(
true);
2623 _clip_planes_enabled =
true;
2626 enable_clip_plane(num_enabled,
true);
2627 if (num_enabled == 0) {
2628 begin_bind_clip_planes();
2631 bind_clip_plane(plane, num_enabled);
2638 for (i = num_enabled; i < _num_clip_planes_enabled; ++i) {
2639 enable_clip_plane(i,
false);
2641 _num_clip_planes_enabled = num_enabled;
2644 if (num_enabled == 0) {
2645 if (_clip_planes_enabled) {
2646 enable_clip_planes(
false);
2647 _clip_planes_enabled =
false;
2650 end_bind_clip_planes();
2665 _target_rs->get_attrib_def(ColorAttrib::get_class_slot());
2668 case ColorAttrib::T_flat:
2671 _scene_graph_color = target_color->
get_color();
2672 _has_scene_graph_color =
true;
2673 _vertex_colors_enabled =
false;
2676 case ColorAttrib::T_off:
2679 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2680 _has_scene_graph_color =
false;
2681 _vertex_colors_enabled =
false;
2684 case ColorAttrib::T_vertex:
2687 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2688 _has_scene_graph_color =
false;
2689 _vertex_colors_enabled =
true;
2693 if (_color_scale_via_lighting) {
2694 _state_mask.
clear_bit(LightAttrib::get_class_slot());
2695 _state_mask.
clear_bit(MaterialAttrib::get_class_slot());
2697 determine_light_color_scale();
2704 void GraphicsStateGuardian::
2705 do_issue_color_scale() {
2708 if (_has_texture_alpha_scale) {
2709 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2713 _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot());
2715 _color_scale_enabled = target_color_scale->
has_scale();
2716 _current_color_scale = target_color_scale->
get_scale();
2717 _has_texture_alpha_scale =
false;
2719 if (_color_blend_involves_color_scale) {
2720 _state_mask.
clear_bit(TransparencyAttrib::get_class_slot());
2722 if (_texture_involves_color_scale) {
2723 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2725 if (_color_scale_via_lighting) {
2726 _state_mask.
clear_bit(LightAttrib::get_class_slot());
2727 _state_mask.
clear_bit(MaterialAttrib::get_class_slot());
2729 determine_light_color_scale();
2732 if (_alpha_scale_via_texture && !_has_scene_graph_color &&
2736 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2737 _state_mask.
clear_bit(TexMatrixAttrib::get_class_slot());
2739 _has_texture_alpha_scale =
true;
2759 LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
2762 int num_enabled = 0;
2763 bool any_on_lights =
false;
2766 _target_rs->get_attrib_def(target_light);
2768 if (display_cat.is_spam()) {
2770 <<
"do_issue_light: " << target_light <<
"\n";
2772 if (target_light !=
nullptr) {
2777 for (
size_t li = 0; li < filtered_lights; ++li) {
2781 nassertv(light_obj !=
nullptr);
2784 if (!_lighting_enabled) {
2785 enable_lighting(
true);
2786 _lighting_enabled =
true;
2789 const LColor &color = light_obj->get_color();
2791 if (color[0] != 0.0 || color[1] != 0.0 || color[2] != 0.0) {
2792 enable_light(num_enabled,
true);
2793 if (num_enabled == 0) {
2794 begin_bind_lights();
2797 light_obj->bind(
this, light, num_enabled);
2803 for (i = num_enabled; i < _num_lights_enabled; ++i) {
2804 enable_light(i,
false);
2806 _num_lights_enabled = num_enabled;
2809 if (!any_on_lights) {
2810 if (_color_scale_via_lighting && (_has_material_force_color || _light_color_scale != LVecBase4(1.0f, 1.0f, 1.0f, 1.0f))) {
2812 if (!_lighting_enabled) {
2813 enable_lighting(
true);
2814 _lighting_enabled =
true;
2816 set_ambient_light(LColor(1.0f, 1.0f, 1.0f, 1.0f));
2819 if (_lighting_enabled) {
2820 enable_lighting(
false);
2821 _lighting_enabled =
false;
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);
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;
3464 string GraphicsStateGuardian::
3465 get_driver_vendor() {
3481 string GraphicsStateGuardian::
3482 get_driver_version() {
3491 int GraphicsStateGuardian::
3492 get_driver_version_major() {
3501 int GraphicsStateGuardian::
3502 get_driver_version_minor() {
3509 int GraphicsStateGuardian::
3510 get_driver_shader_version_major() {
3517 int GraphicsStateGuardian::
3518 get_driver_shader_version_minor() {
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];
void get_linear_range(PN_stdfloat &onset, PN_stdfloat &opaque)
Retrieves the current onset and offset ranges.
void clear_bit(int index)
Sets the nth bit off.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool is_linear() const
Returns true if the lens represents a linear projection (e.g.
set_scene
Sets the SceneSetup object that indicates the initial camera position, etc.
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
A light shining from infinitely far away in a particular direction, like sunlight.
get_y_size
Returns the height of the texture image in texels.
Texture * get_texture() const
Returns the pointer to the associated Texture object.
Lens::StereoChannel get_stereo_channel() const
Returns whether the DisplayRegion is specified as the left or right channel of a stereo pair,...
RenderBuffer get_render_buffer(int buffer_type, const FrameBufferProperties &prop)
Returns a RenderBuffer object suitable for operating on the requested set of buffers.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual Light * as_light()
Cross-casts the node to a Light pointer, if it is one of the four kinds of Light nodes,...
A basic node of the scene graph or data graph.
The abstract interface to all kinds of lights.
virtual bool draw_points(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected points.
virtual bool framebuffer_copy_to_ram(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb)
Copy the pixels within the indicated display region from the framebuffer into system memory,...
virtual void end_frame(Thread *current_thread)
Called after each frame is rendered, to allow the GSG a chance to do any internal cleanup after rende...
Encapsulates the data from a DisplayRegion, pre-fetched for one stage of the pipeline.
virtual bool depth_offset_decals()
Returns true if this GSG can implement decals using a DepthOffsetAttrib, or false if that is unreliab...
set_coordinate_system
Changes the coordinate system in effect on this particular gsg.
This is a const pointer to an InternalName, and should be used in lieu of a CPT(InternalName) in func...
This is a special class object that holds all the information returned by a particular GSG to indicat...
int get_pad_y_size() const
Returns size of the pad region.
bool is_exact_type(TypeHandle handle) const
Returns true if the current object is the indicated type exactly.
bool auto_shader() const
If true, then this ShaderAttrib does not contain an explicit shader - instead, it requests the automa...
virtual void release_shader(ShaderContext *sc)
Releases the resources allocated by prepare_shader.
has_scale
Returns true if the ColorScaleAttrib has a non-identity scale, false otherwise (in which case it migh...
This class represents a thread-safe handle to a promised future result of an asynchronous operation,...
get_pipe
Returns the graphics pipe on which this GSG was created.
get_tex_view_offset
Returns the current setting of the tex_view_offset.
bool has_alpha_scale() const
Returns true if the ColorScaleAttrib has a non-identity scale in the alpha component (ignoring RGB),...
This is a base class for GraphicsWindow (actually, GraphicsOutput) and DisplayRegion,...
virtual void clear_before_callback()
Resets any non-standard graphics state that might give a callback apoplexy.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
set_active
Sets the active flag associated with the GraphicsStateGuardian.
virtual void release_index_buffer(IndexBufferContext *ibc)
Frees the resources previously allocated via a call to prepare_data(), including deleting the IndexBu...
This is a generic buffer object that lives in graphics memory.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void release_geom(GeomContext *gc)
Frees the resources previously allocated via a call to prepare_geom(), including deleting the GeomCon...
virtual void clear(DrawableRegion *clearable)
Clears the framebuffer within the current DisplayRegion, according to the flags indicated by the give...
A base class for any number of different kinds of lenses, linear and otherwise.
virtual const LColor & get_specular_color() const
Returns the color of specular highlights generated by the light.
This loader request will call Texture::get_ram_image() in a sub-thread, to force the texture's image ...
get_z_size
Returns the depth of the texture image in texels.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool draw_patches(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of "patches", which can only be processed by a tessellation shader.
virtual bool update_texture(TextureContext *tc, bool force)
Ensures that the current Texture data is refreshed onto the GSG.
get_task
Returns the nth AsyncTask in the collection.
bool is_empty() const
Returns true if the NodePath contains no nodes.
GraphicsOutput * get_window() const
Returns the GraphicsOutput that this DisplayRegion is ultimately associated with, or NULL if no windo...
Indicates which, if any, material should be applied to geometry.
A class to manage a loose queue of isolated tasks, which can be performed either synchronously (in th...
This object describes how the vertex animation, if any, represented in a GeomVertexData is encoded.
virtual void ensure_generated_shader(const RenderState *state)
Ensures that an appropriate shader has been generated for the given state.
static void remove_gsg(GraphicsStateGuardianBase *gsg)
Called by a GSG destructor to remove a GSG from the available list.
get_num_on_stages
Returns the number of stages that are turned on by the attribute.
virtual void prepare_display_region(DisplayRegionPipelineReader *dr)
Makes the specified DisplayRegion current.
get_on_stage
Returns the nth stage turned on by the attribute, sorted in render order.
virtual void end_draw_primitives()
Called after a sequence of draw_primitive() functions are called, this should do whatever cleanup is ...
void clear()
Sets all the bits in the BitMask off.
virtual CoordinateSystem get_internal_coordinate_system() const
Returns the coordinate system used internally by the GSG.
A node that contains a Lens.
virtual bool draw_lines_adj(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected line segments with adjacency information.
get_near
Returns the position of the near plane (or cylinder, sphere, whatever).
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
This is a special class object that holds all the information returned by a particular GSG to indicat...
get_fog
If the FogAttrib is not an 'off' FogAttrib, returns the fog that is associated.
This is a base class for those kinds of SavedContexts that occupy an easily-measured (and substantial...
virtual void dispatch_compute(int size_x, int size_y, int size_z)
Dispatches a currently bound compute shader using the given work group counts.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
get_on_sampler
Returns the sampler associated with the indicated stage, or the one associated with its texture if no...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A list of tasks, for instance as returned by some of the AsyncTaskManager query functions.
get_color
If the type is T_flat or T_off, this returns the color that will be applied to geometry.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void traverse_prepared_textures(TextureCallback *func, void *callback_arg)
Calls the indicated function on all currently-prepared textures, or until the callback function retur...
set_priority
Specifies a priority value for this task.
This is a special class object that holds all the information returned by a particular GSG to indicat...
get_roughness
Returns the roughness previously specified by set_roughness.
const Value & get_data(size_t n) const
Returns the data in the nth entry of the table.
int store(const Key &key, const Value &data)
Records the indicated key/data pair in the map.
get_max_texture_stages
Returns the maximum number of simultaneous textures that may be applied to geometry with multitexturi...
virtual void remove_window(GraphicsOutputBase *window)
This is simply a transparent call to GraphicsEngine::remove_window().
void set_hardware(int num_transforms, bool indexed_transforms)
Specifies that vertex animation is to be performed by the graphics hardware (or at least by the graph...
const Lens * get_lens() const
Returns the particular Lens used for rendering.
A light source that seems to illuminate all points in space at once.
virtual void restore_gamma()
Restore original gamma setting.
This functions similarly to a LightAttrib.
get_supports_shadow_filter
Returns true if this particular GSG supports the filter mode FT_shadow for depth textures.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PN_stdfloat get_hfov() const
Returns the horizontal component of fov only.
virtual void release_vertex_buffer(VertexBufferContext *vbc)
Frees the resources previously allocated via a call to prepare_data(), including deleting the VertexB...
static void unregister_mungers_for_gsg(GraphicsStateGuardianBase *gsg)
Removes all the mungers from the registry that are associated with the indicated GSG.
Encapsulates the data from a Geom, pre-fetched for one stage of the pipeline.
virtual BufferContext * prepare_shader_buffer(ShaderBuffer *data)
Prepares the indicated buffer for retained-mode rendering.
bool remove_window(GraphicsOutput *window)
Removes the indicated window or offscreen buffer from the set of windows that will be processed when ...
void do_issue_color()
This method is defined in the base class because it is likely that this functionality will be used fo...
virtual void release_sampler(SamplerContext *sc)
Frees the resources previously allocated via a call to prepare_sampler(), including deleting the Samp...
A table of objects that are saved within the graphics context for reference by handle later.
virtual GeomContext * prepare_geom(Geom *geom)
Prepares the indicated Geom for retained-mode rendering, by creating whatever structures are necessar...
set_flash_texture
Sets the "flash texture".
get_name
Returns the complete name represented by the InternalName and all of its parents.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static WindowProperties size(const LVecBase2i &size)
Returns a WindowProperties structure with only the size specified.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PT(OcclusionQueryContext) GraphicsStateGuardian
Ends a previous call to begin_occlusion_query().
int get_pad_x_size() const
Returns size of the pad region.
GraphicsOutput * make_output(GraphicsPipe *pipe, const std::string &name, int sort, const FrameBufferProperties &fb_prop, const WindowProperties &win_prop, int flags, GraphicsStateGuardian *gsg=nullptr, GraphicsOutput *host=nullptr)
Creates a new window (or buffer) and returns it.
int get_buffer_mask() const
Converts the non-aux bitplanes of the framebuffer into a RenderBuffer::Type.
get_diffuse
Returns the diffuse color setting, if it has been set.
get_emission
Returns the emission color setting, if it has been set.
This is a special type of PStatTimer that also uses a timer query on the GSG to measure how long a ta...
The ShaderContext is meant to contain the compiled version of a shader string.
Indicates the set of TextureStages and their associated Textures that should be applied to (or remove...
GraphicsEngine * get_engine() const
Returns the graphics engine that created this GSG.
Lens * get_lens(int index=0) const
Returns a pointer to the particular Lens associated with this LensNode, or NULL if there is not yet a...
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomVertexDataPipelineReader *data_reader, bool force)
Called before a sequence of draw_primitive() functions are called, this should prepare the vertex dat...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_identity() const
Returns true if the ColorScaleAttrib is an identity attrib, false if it is either an off attrib or it...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Applies a Fog to the geometry at and below this node.
virtual bool draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of triangle strips.
get_scale
Returns the scale to be applied to colors.
size_t get_num_entries() const
Returns the number of active entries in the table.
A lightweight class that represents a single element that may be timed and/or counted via stats.
virtual void set_state_and_transform(const RenderState *state, const TransformState *transform)
Simultaneously resets the render state and the transform state.
get_exp_density
Returns the density of the fog for exponential calculations.
static Loader * get_global_ptr()
Returns a pointer to the global Loader.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for the various kinds of properties we might ask to have on a graphics window before we o...
static Texture * get_alpha_scale_map()
Returns a standard Texture object that has been created with Texture::generate_alpha_scale_map().
virtual bool draw_triangles_adj(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected triangles with adjacency information.
const LMatrix4 & get_projection_mat_inv(StereoChannel channel=SC_mono) const
Returns the matrix that transforms from a 2-d point on the film to a 3-d vector in space,...
DisplayRegion * make_mono_display_region()
Creates a new DisplayRegion that covers the entire window.
get_metallic
Returns the metallic setting, if it has been set.
get_parent
Return the parent of this InternalName.
get_base_color
Returns the base_color color setting, if it has been set.
void clear_flash_texture()
Resets the "flash texture", so that no textures will flash.
get_swap_eyes
Returns the current setting of the "swap eyes" flag.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_on_light
Returns the nth light turned on by the attribute, sorted in render order.
get_frame_time
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
PN_stdfloat compute_distance_to(const LPoint3 &point) const
This function will compute the distance to the indicated point, assumed to be in eye coordinates,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_frame_count
Returns the number of times tick() has been called since the ClockObject was created,...
virtual void clear_state_and_transform()
Forgets the current graphics state and current transform, so that the next call to set_state_and_tran...
get_shininess
Returns the shininess exponent of the material.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_num_on_planes
Returns the number of planes that are enabled by the attribute.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Specifies how atmospheric fog effects are applied to geometry.
An object to create GraphicsOutputs that share a particular 3-D API.
virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected triangles.
A container for geometry primitives.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void begin_occlusion_query()
Begins a new occlusion query.
virtual void release_texture(TextureContext *tc)
Frees the resources previously allocated via a call to prepare_texture(), including deleting the Text...
const Key & get_key(size_t n) const
Returns the key in the nth entry of the table.
virtual bool draw_lines(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected line segments.
get_refractive_index
Returns the index of refraction, or 1 if none has been set for this material.
int get_pad_z_size() const
Returns size of the pad region.
A light originating from a single point in space, and shining in a particular direction,...
get_ambient
Returns the ambient color setting, if it has been set.
virtual void do_issue_light()
This implementation of do_issue_light() assumes we have a limited number of hardware lights available...
virtual const LVecBase3 & get_attenuation() const
Returns the terms of the attenuation equation for the light.
get_coordinate_system
Returns the coordinate system that all 3-d computations are performed within for this Lens.
virtual bool has_extension(const std::string &extension) const
Returns true if the GSG implements the extension identified by the given string.
A lightweight class that represents a single thread of execution to PStats.
int get_tex_view_offset()
Returns the current texture view offset for this DisplayRegion.
unsigned int get_left_eye_color_mask() const
Returns the color mask in effect when rendering a left-eye view in red_blue stereo mode.
Similar to MutexHolder, but for a reentrant mutex.
size_t get_num_non_ambient_lights() const
Returns the number of non-ambient lights that are turned on by this attribute.
virtual ShaderContext * prepare_shader(Shader *shader)
Compile a vertex/fragment shader body.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_color
return the color for this stage
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a base class for the various different classes that represent the result of a frame of render...
Defines the way an object appears in the presence of lighting.
Similar to MutexHolder, but for a light reentrant mutex.
void remove_element(size_t n)
Removes the nth entry from the table.
Encodes a string name in a hash table, mapping it to a pointer.
get_color
Returns the color of the fog.
virtual SamplerContext * prepare_sampler(const SamplerState &sampler)
Creates whatever structures the GSG requires to represent the sampler internally, and returns a newly...
get_nodal_point
Returns the center point of the lens: the point from which the lens is viewing.
Applies a scale to colors in the scene graph and on vertices.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Represents a set of settings that indicate how a texture is sampled.
set_camera
Sets the camera that is associated with this DisplayRegion.
This is a special class object that holds a handle to the sampler state object given by the graphics ...
Applies a transform matrix to UV's before they are rendered.
virtual bool is_ambient_light() const
Returns true if this is an AmbientLight, false if it is not a light, or it is some other kind of ligh...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_material
If the MaterialAttrib is not an 'off' MaterialAttrib, returns the material that is associated.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class represents a concrete task performed by an AsyncManager.
const LMatrix4 & get_projection_mat(StereoChannel channel=SC_mono) const
Returns the complete transformation matrix from a 3-d point in space to a point on the film,...
virtual bool draw_linestrips_adj(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of line strips with adjacency information.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PandaNode * node() const
Returns the referenced node of the path.
virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of triangle fans.
unsigned int get_right_eye_color_mask() const
Returns the color mask in effect when rendering a right-eye view in red_blue stereo mode.
get_on_plane
Returns the nth plane enabled by the attribute, sorted in render order.
A thread; that is, a lightweight process.
virtual PN_stdfloat get_exponent() const
For spotlights, returns the exponent that controls the amount of light falloff from the center of the...
get_direction
Returns the direction in which the light is aimed.
A derivative of Light and of Camera.
bool is_empty() const
Returns true if the table is empty; i.e.
This is a special class object that holds all the information returned by a particular GSG to indicat...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_off() const
Returns true if the MaterialAttrib is an 'off' MaterialAttrib, indicating that it should disable the ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void end_scene()
Called between begin_frame() and end_frame() to mark the end of drawing commands for a "scene" (usual...
virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of line strips.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_color
Returns the basic color of the light.
set_lens_index
Sets the lens index, allows for multiple lenses to be attached to a camera.
static bool is_connected()
Returns true if the client believes it is connected to a working PStatServer, false otherwise.
virtual void release_shader_buffer(BufferContext *ibc)
Frees the resources previously allocated via a call to prepare_data(), including deleting the BufferC...
virtual VertexBufferContext * prepare_vertex_buffer(GeomVertexArrayData *data)
Prepares the indicated buffer for retained-mode rendering.
A rectangular subregion within a window for rendering into.
Indicates what color should be applied to renderable geometry.
static void create_gamma_table(PN_stdfloat gamma, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table)
Create a gamma table.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const LMatrix4 & get_mat() const
Returns the transform matrix that has been applied to the referenced node, or the identity matrix if ...
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
virtual bool get_supports_cg_profile(const std::string &name) const
Returns true if this particular GSG supports the specified Cg Shader Profile.
An abstract base class for GraphicsOutput, for all the usual reasons.
Returned from a GSG in response to begin_occlusion_query() .
virtual int get_supported_geom_rendering() const
Returns the union of Geom::GeomRendering values that this particular GSG can support directly.
CPT(TransformState) GraphicsStateGuardian
Given a lens, this function calculates the appropriate projection matrix for this gsg.
This class is the main interface to controlling the render process.
get_basename
Return the name represented by just this particular InternalName object, ignoring its parents names.
virtual void reset()
Resets all internal state as if the gsg were newly created.
const LMatrix4 * fetch_specified_part(Shader::ShaderMatInput input, InternalName *name, LMatrix4 &t, int index)
See fetch_specified_value.
virtual bool framebuffer_copy_to_texture(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb)
Copy the pixels within the indicated display region from the framebuffer into texture memory.
virtual bool begin_frame(Thread *current_thread)
Called before each frame is rendered, to allow the GSG a chance to do any internal cleanup before beg...
TypeHandle is the identifier used to differentiate C++ class types.
Defines the details about the Collectors: the name, the suggested color, etc.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_render_texture(Texture *tex, RenderTextureMode mode, RenderTexturePlane bitplane=RTP_COUNT)
Creates a new Texture object, suitable for rendering the contents of this buffer into,...
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
get_specular
Returns the specular color setting, if it has been set.
This object holds the camera position, etc., and other general setup information for rendering a part...
const LMatrix4 * fetch_specified_value(Shader::ShaderMatSpec &spec, int altered)
The gsg contains a large number of useful matrices:
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
virtual IndexBufferContext * prepare_index_buffer(GeomPrimitive *data)
Prepares the indicated buffer for retained-mode rendering.
virtual TextureContext * prepare_texture(Texture *tex, int view)
Creates whatever structures the GSG requires to represent the texture internally, and returns a newly...
void flush_timer_queries()
Called by the graphics engine on the draw thread to check the status of the running timer queries and...
Manages the communications to report statistics via a network connection to a remote PStatServer.
Encapsulates the data from a GeomPrimitive, pre-fetched for one stage of the pipeline.
virtual bool prepare_lens()
Makes the current lens (whichever lens was most recently specified with set_scene()) active,...
Defines the properties of a named stage of the multitexture pipeline.
Computes texture coordinates for geometry automatically based on vertex position and/or normal.
virtual void finish_decal()
Called during draw to clean up after decals are finished.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_color_type
Returns the type of color specified by this ColorAttrib.
get_dt
Returns the elapsed time for the previous frame: the number of seconds elapsed between the last two c...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_num_tasks
Returns the number of AsyncTasks in the collection.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A RenderBuffer is an arbitrary subset of the various layers (depth buffer, color buffer,...
bool remove(const Key &key)
Removes the indicated key and its associated data from the table.
static TextureStage * get_alpha_scale_texture_stage()
Returns the TextureStage that will be used to apply an alpha scale, if get_alpha_scale_via_texture() ...
virtual bool extract_texture_data(Texture *tex)
This method should only be called by the GraphicsEngine.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
bool has_any_on_light() const
Returns true if any light is turned on by the attrib, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const LVector3 & get_view_vector() const
Returns the axis along which the lens is facing.
A light originating from a single point in space, and shining in all directions.
get_far
Returns the position of the far plane (or cylinder, sphere, whatever).
get_x_size
Returns the width of the texture image in texels.
A sphere light is like a point light, except that it represents a sphere with a radius,...
A node that contains a plane.
get_driver_renderer
Returns GL_Renderer.
get_priority
Returns the task's current priority value.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_frame(const PStatFrameData &frame_data)
This is a slightly lower-level version of new_frame that also specifies the data to send for this fra...
virtual bool draw_tristrips_adj(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of triangle strips with adjacency information.
This is the data for one array of a GeomVertexData structure.
Indicates which set of lights should be considered "on" to illuminate geometry at this level and belo...
virtual bool begin_scene()
Called between begin_frame() and end_frame() to mark the beginning of drawing commands for a "scene" ...
get_on_texture
Returns the texture associated with the indicated stage, or NULL if no texture is associated.
int find(const Key &key) const
Searches for the indicated key in the table.
const LMatrix4 * fetch_specified_member(const NodePath &np, CPT_InternalName member, LMatrix4 &t)
Given a NodePath passed into a shader input that is a structure, fetches the value for the given memb...
virtual void bind_light(PointLight *light_obj, const NodePath &light, int light_id)
Called the first time a particular light has been bound to a given id within a frame,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.