18 #include "graphicsStateGuardian.h" 19 #include "graphicsEngine.h" 20 #include "config_display.h" 21 #include "textureContext.h" 22 #include "vertexBufferContext.h" 23 #include "indexBufferContext.h" 24 #include "renderBuffer.h" 26 #include "planeNode.h" 27 #include "ambientLight.h" 28 #include "throw_event.h" 29 #include "clockObject.h" 30 #include "pStatTimer.h" 31 #include "pStatGPUTimer.h" 32 #include "geomTristrips.h" 33 #include "geomTrifans.h" 34 #include "geomLinestrips.h" 35 #include "colorWriteAttrib.h" 38 #include "drawableRegion.h" 39 #include "displayRegion.h" 40 #include "graphicsOutput.h" 41 #include "texturePool.h" 42 #include "geomMunger.h" 43 #include "ambientLight.h" 44 #include "directionalLight.h" 45 #include "pointLight.h" 46 #include "spotlight.h" 47 #include "textureReloadRequest.h" 48 #include "shaderAttrib.h" 49 #include "materialAttrib.h" 50 #include "depthWriteAttrib.h" 51 #include "lightAttrib.h" 52 #include "texGenAttrib.h" 53 #include "shaderGenerator.h" 54 #include "lightLensNode.h" 55 #include "colorAttrib.h" 56 #include "colorScaleAttrib.h" 57 #include "clipPlaneAttrib.h" 58 #include "fogAttrib.h" 59 #include "config_pstats.h" 64 PStatCollector GraphicsStateGuardian::_vertex_buffer_switch_pcollector(
"Vertex buffer switch:Vertex");
65 PStatCollector GraphicsStateGuardian::_index_buffer_switch_pcollector(
"Vertex buffer switch:Index");
66 PStatCollector GraphicsStateGuardian::_load_vertex_buffer_pcollector(
"Draw:Transfer data:Vertex buffer");
67 PStatCollector GraphicsStateGuardian::_load_index_buffer_pcollector(
"Draw:Transfer data:Index buffer");
68 PStatCollector GraphicsStateGuardian::_create_vertex_buffer_pcollector(
"Draw:Transfer data:Create Vertex buffer");
69 PStatCollector GraphicsStateGuardian::_create_index_buffer_pcollector(
"Draw:Transfer data:Create Index buffer");
70 PStatCollector GraphicsStateGuardian::_load_texture_pcollector(
"Draw:Transfer data:Texture");
71 PStatCollector GraphicsStateGuardian::_data_transferred_pcollector(
"Data transferred");
72 PStatCollector GraphicsStateGuardian::_texmgrmem_total_pcollector(
"Texture manager");
73 PStatCollector GraphicsStateGuardian::_texmgrmem_resident_pcollector(
"Texture manager:Resident");
74 PStatCollector GraphicsStateGuardian::_primitive_batches_pcollector(
"Primitive batches");
75 PStatCollector GraphicsStateGuardian::_primitive_batches_tristrip_pcollector(
"Primitive batches:Triangle strips");
76 PStatCollector GraphicsStateGuardian::_primitive_batches_trifan_pcollector(
"Primitive batches:Triangle fans");
77 PStatCollector GraphicsStateGuardian::_primitive_batches_tri_pcollector(
"Primitive batches:Triangles");
78 PStatCollector GraphicsStateGuardian::_primitive_batches_patch_pcollector(
"Primitive batches:Patches");
79 PStatCollector GraphicsStateGuardian::_primitive_batches_other_pcollector(
"Primitive batches:Other");
80 PStatCollector GraphicsStateGuardian::_vertices_tristrip_pcollector(
"Vertices:Triangle strips");
81 PStatCollector GraphicsStateGuardian::_vertices_trifan_pcollector(
"Vertices:Triangle fans");
82 PStatCollector GraphicsStateGuardian::_vertices_tri_pcollector(
"Vertices:Triangles");
83 PStatCollector GraphicsStateGuardian::_vertices_patch_pcollector(
"Vertices:Patches");
84 PStatCollector GraphicsStateGuardian::_vertices_other_pcollector(
"Vertices:Other");
85 PStatCollector GraphicsStateGuardian::_state_pcollector(
"State changes");
86 PStatCollector GraphicsStateGuardian::_transform_state_pcollector(
"State changes:Transforms");
87 PStatCollector GraphicsStateGuardian::_texture_state_pcollector(
"State changes:Textures");
88 PStatCollector GraphicsStateGuardian::_draw_primitive_pcollector(
"Draw:Primitive:Draw");
89 PStatCollector GraphicsStateGuardian::_draw_set_state_pcollector(
"Draw:Set State");
90 PStatCollector GraphicsStateGuardian::_clear_pcollector(
"Draw:Clear");
91 PStatCollector GraphicsStateGuardian::_flush_pcollector(
"Draw:Flush");
92 PStatCollector GraphicsStateGuardian::_compute_dispatch_pcollector(
"Draw:Compute dispatch");
94 PStatCollector GraphicsStateGuardian::_wait_occlusion_pcollector(
"Wait:Occlusion");
95 PStatCollector GraphicsStateGuardian::_wait_timer_pcollector(
"Wait:Timer Queries");
96 PStatCollector GraphicsStateGuardian::_timer_queries_pcollector(
"Timer queries");
97 PStatCollector GraphicsStateGuardian::_command_latency_pcollector(
"Command latency");
99 PStatCollector GraphicsStateGuardian::_prepare_pcollector(
"Draw:Prepare");
100 PStatCollector GraphicsStateGuardian::_prepare_texture_pcollector(
"Draw:Prepare:Texture");
101 PStatCollector GraphicsStateGuardian::_prepare_sampler_pcollector(
"Draw:Prepare:Sampler");
102 PStatCollector GraphicsStateGuardian::_prepare_geom_pcollector(
"Draw:Prepare:Geom");
103 PStatCollector GraphicsStateGuardian::_prepare_shader_pcollector(
"Draw:Prepare:Shader");
104 PStatCollector GraphicsStateGuardian::_prepare_vertex_buffer_pcollector(
"Draw:Prepare:Vertex buffer");
105 PStatCollector GraphicsStateGuardian::_prepare_index_buffer_pcollector(
"Draw:Prepare:Index buffer");
107 PStatCollector GraphicsStateGuardian::_draw_set_state_transform_pcollector(
"Draw:Set State:Transform");
108 PStatCollector GraphicsStateGuardian::_draw_set_state_alpha_test_pcollector(
"Draw:Set State:Alpha test");
109 PStatCollector GraphicsStateGuardian::_draw_set_state_antialias_pcollector(
"Draw:Set State:Antialias");
110 PStatCollector GraphicsStateGuardian::_draw_set_state_clip_plane_pcollector(
"Draw:Set State:Clip plane");
111 PStatCollector GraphicsStateGuardian::_draw_set_state_color_pcollector(
"Draw:Set State:Color");
112 PStatCollector GraphicsStateGuardian::_draw_set_state_cull_face_pcollector(
"Draw:Set State:Cull face");
113 PStatCollector GraphicsStateGuardian::_draw_set_state_depth_offset_pcollector(
"Draw:Set State:Depth offset");
114 PStatCollector GraphicsStateGuardian::_draw_set_state_depth_test_pcollector(
"Draw:Set State:Depth test");
115 PStatCollector GraphicsStateGuardian::_draw_set_state_depth_write_pcollector(
"Draw:Set State:Depth write");
116 PStatCollector GraphicsStateGuardian::_draw_set_state_render_mode_pcollector(
"Draw:Set State:Render mode");
117 PStatCollector GraphicsStateGuardian::_draw_set_state_rescale_normal_pcollector(
"Draw:Set State:Rescale normal");
118 PStatCollector GraphicsStateGuardian::_draw_set_state_shade_model_pcollector(
"Draw:Set State:Shade model");
119 PStatCollector GraphicsStateGuardian::_draw_set_state_blending_pcollector(
"Draw:Set State:Blending");
120 PStatCollector GraphicsStateGuardian::_draw_set_state_shader_pcollector(
"Draw:Set State:Shader");
121 PStatCollector GraphicsStateGuardian::_draw_set_state_shader_parameters_pcollector(
"Draw:Set State:Shader Parameters");
122 PStatCollector GraphicsStateGuardian::_draw_set_state_texture_pcollector(
"Draw:Set State:Texture");
123 PStatCollector GraphicsStateGuardian::_draw_set_state_tex_matrix_pcollector(
"Draw:Set State:Tex matrix");
124 PStatCollector GraphicsStateGuardian::_draw_set_state_tex_gen_pcollector(
"Draw:Set State:Tex gen");
125 PStatCollector GraphicsStateGuardian::_draw_set_state_material_pcollector(
"Draw:Set State:Material");
126 PStatCollector GraphicsStateGuardian::_draw_set_state_light_pcollector(
"Draw:Set State:Light");
127 PStatCollector GraphicsStateGuardian::_draw_set_state_stencil_pcollector(
"Draw:Set State:Stencil");
128 PStatCollector GraphicsStateGuardian::_draw_set_state_fog_pcollector(
"Draw:Set State:Fog");
129 PStatCollector GraphicsStateGuardian::_draw_set_state_scissor_pcollector(
"Draw:Set State:Scissor");
131 PT(
TextureStage) GraphicsStateGuardian::_alpha_scale_texture_stage = NULL;
133 TypeHandle GraphicsStateGuardian::_type_handle;
141 GraphicsStateGuardian::
142 GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
144 _internal_coordinate_system(internal_coordinate_system),
148 _coordinate_system = CS_invalid;
149 _internal_transform = TransformState::make_identity();
151 if (internal_coordinate_system == CS_default) {
152 _internal_coordinate_system = get_default_coordinate_system();
159 _current_stereo_channel = Lens::SC_mono;
160 _current_tex_view_offset = 0;
161 _current_lens = (
Lens *)NULL;
162 _projection_mat = TransformState::make_identity();
163 _projection_mat_inv = TransformState::make_identity();
167 _current_properties = NULL;
168 _closing_gsg =
false;
171 _stereo_buffer_mask = ~0;
172 _incomplete_render = allow_incomplete_render;
173 _effective_incomplete_render =
false;
176 _is_hardware =
false;
177 _prefers_triangle_strips =
false;
178 _max_vertices_per_array = INT_MAX;
179 _max_vertices_per_primitive = INT_MAX;
184 _max_texture_stages = 1;
188 _max_texture_dimension = -1;
189 _max_3d_texture_dimension = 0;
190 _max_2d_texture_array_layers = 0;
191 _max_cube_map_dimension = 0;
195 _supports_texture_combine =
false;
196 _supports_texture_saved_result =
false;
197 _supports_texture_dot3 =
false;
199 _supports_3d_texture =
false;
200 _supports_2d_texture_array =
false;
201 _supports_cube_map =
false;
202 _supports_tex_non_pow2 =
false;
203 _supports_texture_srgb =
false;
204 _supports_compressed_texture =
false;
205 _compressed_texture_formats.
clear();
206 _compressed_texture_formats.
set_bit(Texture::CM_off);
210 _max_clip_planes = -1;
213 _max_vertex_transforms = 0;
214 _max_vertex_transform_indices = 0;
216 _supports_occlusion_query =
false;
217 _supports_timer_query =
false;
220 _timer_queries_active =
false;
221 _last_query_frame = 0;
222 _last_num_queried = 0;
225 _pstats_gpu_thread = -1;
230 _copy_texture_inverted =
false;
233 _supports_multisample =
false;
234 _supports_generate_mipmap =
false;
235 _supports_depth_texture =
false;
236 _supports_depth_stencil =
false;
237 _supports_shadow_filter =
false;
238 _supports_sampler_objects =
false;
239 _supports_basic_shaders =
false;
240 _supports_geometry_shaders =
false;
241 _supports_tessellation_shaders =
false;
242 _supports_compute_shaders =
false;
243 _supports_glsl =
false;
245 _supports_stencil =
false;
246 _supports_stencil_wrap =
false;
247 _supports_two_sided_stencil =
false;
248 _supports_geometry_instancing =
false;
251 _max_color_targets = 1;
253 _supported_geom_rendering = 0;
258 _color_scale_via_lighting = color_scale_via_lighting;
262 _alpha_scale_via_texture = alpha_scale_via_texture;
266 _runtime_color_scale =
false;
269 _auto_detect_shader_model = SM_00;
270 _shader_model = SM_00;
273 _texture_quality_override = Texture::QL_default;
281 GraphicsStateGuardian::
282 ~GraphicsStateGuardian() {
297 nassertr(_engine != (
GraphicsEngine *)NULL, GraphicsEngine::get_global_ptr());
316 return _supports_multisample;
333 return _supported_geom_rendering;
362 if (cs == CS_default) {
363 cs = get_default_coordinate_system();
365 if (_coordinate_system == cs) {
368 _coordinate_system = cs;
371 if (_internal_coordinate_system == CS_default ||
372 _internal_coordinate_system == _coordinate_system) {
373 _cs_transform = TransformState::make_identity();
374 _inv_cs_transform = TransformState::make_identity();
378 TransformState::make_mat
380 _internal_coordinate_system));
382 TransformState::make_mat
384 _coordinate_system));
403 return _internal_coordinate_system;
415 return _prepared_objects;
458 void *callback_arg) {
460 PreparedGraphicsObjects::Textures::const_iterator ti;
461 for (ti = _prepared_objects->_prepared_textures.begin();
462 ti != _prepared_objects->_prepared_textures.end();
464 bool result = (*func)(*ti, callback_arg);
497 _flash_texture = tex;
510 _flash_texture = NULL;
523 return _flash_texture;
538 _scene_setup = scene_setup;
539 _current_lens = scene_setup->
get_lens();
540 if (_current_lens == (
Lens *)NULL) {
546 _projection_mat = calc_projection_mat(_current_lens);
547 if (_projection_mat == 0) {
550 _projection_mat_inv = _projection_mat->get_inverse();
782 end_occlusion_query() {
785 _current_occlusion_query = NULL;
796 issue_timer_query(
int pstats_index) {
829 if (!nc_state->_mungers.empty()) {
830 RenderState::Mungers::const_iterator mi = nc_state->_last_mi;
831 if (!(*mi).first.was_deleted() && (*mi).first ==
this) {
832 if ((*mi).second->is_registered()) {
839 RenderState::Mungers::iterator mi = nc_state->_mungers.find(
this);
840 if (mi != nc_state->_mungers.end() && !(*mi).first.was_deleted()) {
841 if ((*mi).second->is_registered()) {
842 nc_state->_last_mi = mi;
847 nc_state->_mungers.erase(mi);
851 PT(
GeomMunger) munger = make_geom_munger(nc_state, current_thread);
852 nassertr(munger != (
GeomMunger *)NULL && munger->is_registered(), munger);
854 mi = nc_state->_mungers.insert(RenderState::Mungers::value_type(
this, munger)).first;
855 nc_state->_last_mi = mi;
885 switch (_internal_coordinate_system) {
900 <<
"Invalid coordinate system in compute_distance_to: " 901 << (int)_internal_coordinate_system <<
"\n";
943 if (altered & spec._dep[0]) {
945 if (t != &spec._cache[0]) {
949 if (altered & spec._dep[1]) {
951 if (t != &spec._cache[1]) {
957 case Shader::SMF_compose:
958 spec._value.multiply(spec._cache[0], spec._cache[1]);
960 case Shader::SMF_transform_dlight:
961 spec._value = spec._cache[0];
969 case Shader::SMF_transform_plight:
970 spec._value = spec._cache[0];
973 case Shader::SMF_transform_slight:
974 spec._value = spec._cache[0];
980 case Shader::SMF_first:
981 return &spec._cache[0];
998 case Shader::SMO_identity: {
1001 case Shader::SMO_window_size: {
1003 _current_display_region->get_pixel_height(),
1007 case Shader::SMO_pixel_size: {
1009 _current_display_region->get_pixel_height(),
1013 case Shader::SMO_frame_time: {
1015 t =
LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time);
1018 case Shader::SMO_frame_delta: {
1020 t =
LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt);
1023 case Shader::SMO_texpad_x: {
1024 Texture *tex = _target_shader->get_shader_input_texture(name);
1032 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,cx,cy,cz,0);
1035 case Shader::SMO_texpix_x: {
1036 Texture *tex = _target_shader->get_shader_input_texture(name);
1041 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,px,py,pz,0);
1044 case Shader::SMO_attr_material: {
1046 _target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
1048 if (target_material->
is_off()) {
1049 t =
LMatrix4(1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0);
1058 t =
LMatrix4(amb[0],amb[1],amb[2],amb[3],
1059 dif[0],dif[1],dif[2],dif[3],
1060 emm[0],emm[1],emm[2],emm[3],
1061 spc[0],spc[1],spc[2],spc[3]);
1064 case Shader::SMO_attr_color: {
1066 _target_rs->get_attrib_def(ColorAttrib::get_class_slot());
1071 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]);
1074 case Shader::SMO_attr_colorscale: {
1076 _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot());
1081 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,cs[0],cs[1],cs[2],cs[3]);
1084 case Shader::SMO_attr_fog: {
1086 _target_rs->get_attrib_def(FogAttrib::get_class_slot());
1088 if (fog == (
Fog*) NULL) {
1091 PN_stdfloat start, end;
1093 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,fog->
get_exp_density(),start,end,1.0f/(end-start));
1096 case Shader::SMO_attr_fogcolor: {
1098 _target_rs->get_attrib_def(FogAttrib::get_class_slot());
1100 if (fog == (
Fog*) NULL) {
1104 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]);
1107 case Shader::SMO_alight_x: {
1108 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1112 LColor const &c = lt->get_color();
1113 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]);
1116 case Shader::SMO_satten_x: {
1117 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1121 LVecBase3 const &a = lt->get_attenuation();
1122 PN_stdfloat x = lt->get_exponent();
1123 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,a[0],a[1],a[2],x);
1126 case Shader::SMO_dlight_x: {
1128 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1132 LColor const &c = lt->get_color();
1133 LColor const &s = lt->get_specular_color();
1134 t = np.get_net_transform()->
get_mat() *
1140 t =
LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],c[3],d[0],d[1],d[2],0,h[0],h[1],h[2],0);
1143 case Shader::SMO_plight_x: {
1145 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1149 LColor const &c = lt->get_color();
1150 LColor const &s = lt->get_specular_color();
1151 t = np.get_net_transform()->
get_mat() *
1155 t =
LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],s[3],p[0],p[1],p[2],0,a[0],a[1],a[2],0);
1158 case Shader::SMO_slight_x: {
1160 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1164 Lens *lens = lt->get_lens();
1166 LColor const &c = lt->get_color();
1167 LColor const &s = lt->get_specular_color();
1168 PN_stdfloat cutoff = ccos(deg_2_rad(lens->get_hfov() * 0.5f));
1169 t = np.get_net_transform()->
get_mat() *
1173 t =
LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],s[3],p[0],p[1],p[2],0,d[0],d[1],d[2],cutoff);
1176 case Shader::SMO_light_ambient: {
1177 LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
1179 _target_rs->get_attrib_def(LightAttrib::get_class_slot());
1182 if (num_on_lights == 0) {
1187 for (
int li = 0; li < num_on_lights; li++) {
1193 if (light_obj->get_type() == AmbientLight::get_class_type()) {
1194 cur_ambient_light += light_obj->get_color();
1197 t.
set_row(3, cur_ambient_light);
1201 case Shader::SMO_texmat_x: {
1204 int stagenr = atoi(name->get_name().c_str());
1205 if (stagenr >= ta->get_num_on_stages()) {
1208 return &tma->get_mat(ta->get_on_stage(stagenr));
1210 case Shader::SMO_plane_x: {
1211 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1215 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,p[0],p[1],p[2],p[3]);
1218 case Shader::SMO_clipplane_x: {
1220 int planenr = atoi(name->get_name().c_str());
1228 p.xform(np.get_net_transform()->
get_mat());
1229 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,p[0],p[1],p[2],p[3]);
1232 case Shader::SMO_apiview_clipplane_i: {
1243 CPT(TransformState) transform =
1245 plane.
get_transform(_scene_setup->get_scene_root().get_parent()));
1247 LPlane xformed_plane = plane_node->get_plane() * transform->get_mat();
1251 case Shader::SMO_mat_constant_x: {
1252 return &_target_shader->get_shader_input_matrix(name, t);
1254 case Shader::SMO_vec_constant_x: {
1255 const LVecBase4 &input = _target_shader->get_shader_input_vector(name);
1256 const PN_stdfloat *data = input.
get_data();
1257 t =
LMatrix4(data[0],data[1],data[2],data[3],
1258 data[0],data[1],data[2],data[3],
1259 data[0],data[1],data[2],data[3],
1260 data[0],data[1],data[2],data[3]);
1263 case Shader::SMO_world_to_view: {
1267 case Shader::SMO_view_to_world: {
1270 case Shader::SMO_model_to_view: {
1271 return &(get_external_transform()->get_mat());
1273 case Shader::SMO_model_to_apiview: {
1274 return &(get_internal_transform()->get_mat());
1276 case Shader::SMO_view_to_model: {
1277 t = get_external_transform()->get_inverse()->get_mat();
1280 case Shader::SMO_apiview_to_model: {
1281 t = get_internal_transform()->get_inverse()->get_mat();
1284 case Shader::SMO_apiview_to_view: {
1285 return &(_inv_cs_transform->get_mat());
1287 case Shader::SMO_view_to_apiview: {
1288 return &(_cs_transform->get_mat());
1290 case Shader::SMO_clip_to_view: {
1291 if (_current_lens->get_coordinate_system() == _coordinate_system) {
1292 return &(_current_lens->get_projection_mat_inv(_current_stereo_channel));
1294 t = _current_lens->get_projection_mat_inv(_current_stereo_channel) *
1299 case Shader::SMO_view_to_clip: {
1300 if (_current_lens->get_coordinate_system() == _coordinate_system) {
1301 return &(_current_lens->get_projection_mat(_current_stereo_channel));
1304 _current_lens->get_projection_mat(_current_stereo_channel);
1308 case Shader::SMO_apiclip_to_view: {
1309 t = _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat();
1312 case Shader::SMO_view_to_apiclip: {
1313 t = _cs_transform->get_mat() * _projection_mat->get_mat();
1316 case Shader::SMO_apiclip_to_apiview: {
1317 return &(_projection_mat_inv->get_mat());
1319 case Shader::SMO_apiview_to_apiclip: {
1320 return &(_projection_mat->get_mat());
1322 case Shader::SMO_view_x_to_view: {
1323 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1325 t = np.get_net_transform()->
get_mat() *
1329 case Shader::SMO_view_to_view_x: {
1330 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1333 np.get_net_transform()->get_inverse()->
get_mat();
1336 case Shader::SMO_apiview_x_to_view: {
1337 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1340 np.get_net_transform()->
get_mat() *
1344 case Shader::SMO_view_to_apiview_x: {
1345 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1348 np.get_net_transform()->get_inverse()->
get_mat() *
1352 case Shader::SMO_clip_x_to_view: {
1353 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1357 t = lens->get_projection_mat_inv(_current_stereo_channel) *
1359 np.get_net_transform()->
get_mat() *
1363 case Shader::SMO_view_to_clip_x: {
1364 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1369 np.get_net_transform()->get_inverse()->
get_mat() *
1371 lens->get_projection_mat(_current_stereo_channel);
1374 case Shader::SMO_apiclip_x_to_view: {
1375 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1379 t = calc_projection_mat(lens)->get_inverse()->get_mat() *
1380 get_cs_transform_for(lens->get_coordinate_system())->get_inverse()->get_mat() *
1381 np.get_net_transform()->
get_mat() *
1385 case Shader::SMO_view_to_apiclip_x: {
1386 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1391 np.get_net_transform()->get_inverse()->
get_mat() *
1392 get_cs_transform_for(lens->get_coordinate_system())->get_mat() *
1393 calc_projection_mat(lens)->get_mat();
1396 case Shader::SMO_vec_constant_x_attrib: {
1398 if (_target_shader->has_shader_input(name)) {
1401 const LVecBase4 &data = _target_shader->get_shader_input_vector(name);
1402 t =
LMatrix4(data[0],data[1],data[2],data[3],
1403 data[0],data[1],data[2],data[3],
1404 data[0],data[1],data[2],data[3],
1405 data[0],data[1],data[2],data[3]);
1409 const NodePath &np = _target_shader->get_shader_input_nodepath(name->get_parent());
1423 static const CPT_InternalName IN_constantAttenuation(
"constantAttenuation");
1425 static const CPT_InternalName IN_quadraticAttenuation(
"quadraticAttenuation");
1427 if (attrib == IN_ambient) {
1432 c.componentwise_mult(_light_color_scale);
1440 }
else if (attrib == IN_diffuse) {
1448 c.componentwise_mult(_light_color_scale);
1453 }
else if (attrib == IN_specular) {
1459 }
else if (attrib == IN_position) {
1462 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
1464 }
else if (np.
node()->
is_of_type(DirectionalLight::get_class_type())) {
1468 CPT(TransformState) transform = np.
get_transform(_scene_setup->get_scene_root().get_parent());
1471 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,dir[0],dir[1],dir[2],0);
1479 CPT(TransformState) transform =
1481 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1483 const LMatrix4 &light_mat = transform->get_mat();
1484 LPoint3 pos = lens->get_nodal_point() * light_mat;
1489 }
else if (attrib == IN_halfVector) {
1492 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
1494 }
else if (np.
node()->
is_of_type(DirectionalLight::get_class_type())) {
1498 CPT(TransformState) transform = np.
get_transform(_scene_setup->get_scene_root().get_parent());
1504 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,dir[0],dir[1],dir[2],1);
1512 CPT(TransformState) transform =
1514 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1516 const LMatrix4 &light_mat = transform->get_mat();
1517 LPoint3 pos = lens->get_nodal_point() * light_mat;
1521 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,pos[0],pos[1],pos[2],1);
1525 }
else if (attrib == IN_spotDirection) {
1536 CPT(TransformState) transform =
1538 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1540 const LMatrix4 &light_mat = transform->get_mat();
1541 LVector3 dir = lens->get_view_vector() * light_mat;
1546 }
else if (attrib == IN_spotCutoff) {
1553 float cutoff = lens->get_hfov() * 0.5f;
1562 }
else if (attrib == IN_spotCosCutoff) {
1569 float cutoff = lens->get_hfov() * 0.5f;
1577 }
else if (attrib == IN_spotExponent) {
1584 }
else if (attrib == IN_constantAttenuation) {
1591 }
else if (attrib == IN_linearAttenuation) {
1598 }
else if (attrib == IN_quadraticAttenuation) {
1607 <<
"Shader input requests invalid attribute " << *name
1608 <<
" from node " << np <<
"\n";
1625 return (_target_shader->get_shader_input_ptr(spec._arg));
1637 _current_display_region = dr->get_object();
1640 _effective_incomplete_render = _incomplete_render && _current_display_region->get_incomplete_render();
1642 _stereo_buffer_mask = ~0;
1647 switch (output_channel) {
1649 output_channel = Lens::SC_right;
1652 case Lens::SC_right:
1653 output_channel = Lens::SC_left;
1661 switch (output_channel) {
1664 if (_current_properties->is_stereo()) {
1669 case Lens::SC_right:
1671 if (_current_properties->is_stereo()) {
1677 case Lens::SC_stereo:
1678 _color_write_mask = ColorWriteAttrib::C_all;
1708 reissue_transforms();
1711 _state_rs = RenderState::make_empty();
1712 _state_mask.
clear();
1728 DCAST_INTO_V(win, window);
1756 CPT(TransformState) GraphicsStateGuardian::
1757 calc_projection_mat(
const Lens *lens) {
1758 if (lens == (
Lens *)NULL) {
1766 return TransformState::make_identity();
1784 _prepared_objects->begin_frame(
this, current_thread);
1792 _state_rs = RenderState::make_empty();
1793 _state_mask.
clear();
1799 if (_last_query_frame < frame) {
1800 _last_query_frame = frame;
1801 _timer_queries_pcollector.clear_level();
1809 if (_timer_queries_active) {
1812 issue_timer_query(0x8000);
1813 issue_timer_query(0x0000);
1818 return !_needs_reset;
1857 _scene_setup = _scene_null;
1863 for (i = 0; i < _num_lights_enabled; ++i) {
1864 enable_light(i,
false);
1866 _num_lights_enabled = 0;
1869 for (i = 0; i < _num_clip_planes_enabled; ++i) {
1870 enable_clip_plane(i,
false);
1872 _num_clip_planes_enabled = 0;
1875 _state_rs = RenderState::make_empty();
1876 _state_mask.
clear();
1888 _prepared_objects->end_frame(current_thread);
1891 _data_transferred_pcollector.flush_level();
1893 _primitive_batches_pcollector.flush_level();
1894 _primitive_batches_tristrip_pcollector.flush_level();
1895 _primitive_batches_trifan_pcollector.flush_level();
1896 _primitive_batches_tri_pcollector.flush_level();
1897 _primitive_batches_patch_pcollector.flush_level();
1898 _primitive_batches_other_pcollector.flush_level();
1899 _vertices_tristrip_pcollector.flush_level();
1900 _vertices_trifan_pcollector.flush_level();
1901 _vertices_tri_pcollector.flush_level();
1902 _vertices_patch_pcollector.flush_level();
1903 _vertices_other_pcollector.flush_level();
1905 _state_pcollector.flush_level();
1906 _texture_state_pcollector.flush_level();
1907 _transform_state_pcollector.flush_level();
1908 _draw_primitive_pcollector.flush_level();
1911 _prepared_objects->_graphics_memory_lru.begin_epoch();
1928 PStatClient *client = PStatClient::get_global_pstats();
1930 if (!client->client_is_connected()) {
1931 _timer_queries_active =
false;
1935 if (!_timer_queries_active) {
1936 if (pstats_gpu_timing && _supports_timer_query) {
1938 _timer_queries_active =
true;
1946 if (_pstats_gpu_thread == -1) {
1949 PStatThread gpu_thread(client, _pstats_gpu_thread);
1953 if (!_pending_timer_queries.empty()) {
1954 int count = _pending_timer_queries.size();
1961 if (_last_num_queried > 0) {
1964 int i = min(_last_num_queried, count) - 1;
1966 if (_pending_timer_queries[i]->is_answer_ready()) {
1968 while (i < count - 1) {
1969 if (!_pending_timer_queries[++i]->is_answer_ready()) {
1977 if (_pending_timer_queries[--i]->is_answer_ready()) {
1988 int step = count / 2;
1989 int i = first + step;
1990 if (_pending_timer_queries[i]->is_answer_ready()) {
2003 _last_num_queried = first;
2007 for (
int i = 0; i < first; ++i) {
2010 double time_data = query->get_timestamp();
2012 if (query->_pstats_index == _command_latency_pcollector.get_index()) {
2015 cdef = client->get_collector_ptr(query->_pstats_index)->get_def(client, query->_pstats_index);
2016 _pstats_gpu_data.add_level(query->_pstats_index, time_data * cdef->_factor);
2018 }
else if (query->_pstats_index & 0x8000) {
2019 _pstats_gpu_data.add_stop(query->_pstats_index & 0x7fff, time_data);
2022 _pstats_gpu_data.add_start(query->_pstats_index & 0x7fff, time_data);
2028 if (query->_pstats_index == 0x8000) {
2030 _pstats_gpu_data.clear();
2037 _pending_timer_queries.erase(
2038 _pending_timer_queries.begin(),
2039 _pending_timer_queries.begin() + first
2041 _timer_queries_pcollector.add_level_now(first);
2071 begin_decal_base_first() {
2074 if (decal_base_first == (
const RenderState *)NULL) {
2075 decal_base_first = RenderState::make
2076 (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
2077 RenderState::get_max_priority());
2079 return decal_base_first;
2093 begin_decal_nested() {
2098 decal_nested = RenderState::make
2099 (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
2100 RenderState::get_max_priority());
2102 return decal_nested;
2121 begin_decal_base_second() {
2126 if (decal_base_second == (
const RenderState *)NULL) {
2127 decal_base_second = RenderState::make
2128 (ColorWriteAttrib::make(ColorWriteAttrib::C_off),
2133 RenderState::get_max_priority());
2135 return decal_base_second;
2163 _data_reader = data_reader;
2164 return _data_reader->has_vertex();
2248 _data_reader = NULL;
2259 _needs_reset =
false;
2262 _state_rs = RenderState::make_empty();
2264 _state_mask.
clear();
2265 _internal_transform = _cs_transform;
2267 _scene_setup = _scene_null;
2269 _color_write_mask = ColorWriteAttrib::C_all;
2271 _has_scene_graph_color =
false;
2272 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2273 _transform_stale =
true;
2274 _color_blend_involves_color_scale =
false;
2275 _texture_involves_color_scale =
false;
2276 _vertex_colors_enabled =
true;
2277 _lighting_enabled =
false;
2278 _num_lights_enabled = 0;
2279 _num_clip_planes_enabled = 0;
2280 _clip_planes_enabled =
false;
2282 _color_scale_enabled =
false;
2283 _current_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
2284 _has_texture_alpha_scale =
false;
2286 _has_material_force_color =
false;
2287 _material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2288 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
2290 _tex_gen_modifies_mat =
false;
2291 _last_max_stage_index = 0;
2315 const TransformState *trans) {
2354 CPT(TransformState) GraphicsStateGuardian::
2355 get_cs_transform_for(CoordinateSystem cs)
const {
2356 if (_coordinate_system == cs) {
2358 return _cs_transform;
2360 }
else if (_internal_coordinate_system == CS_default ||
2361 _internal_coordinate_system == cs) {
2362 return TransformState::make_identity();
2365 return TransformState::make_mat
2380 CPT(TransformState) GraphicsStateGuardian::
2381 get_cs_transform()
const {
2382 return _cs_transform;
2392 void GraphicsStateGuardian::
2393 do_issue_clip_plane() {
2394 int num_enabled = 0;
2395 int num_on_planes = 0;
2398 _target_rs->get_attrib_def(ClipPlaneAttrib::get_class_slot());
2401 CPT(
ClipPlaneAttrib) new_plane = target_clip_plane->filter_to_max(_max_clip_planes);
2404 for (
int li = 0; li < num_on_planes; li++) {
2405 NodePath plane = new_plane->get_on_plane(li);
2408 DCAST_INTO_V(plane_node, plane.
node());
2409 if ((plane_node->get_clip_effect() & PlaneNode::CE_visible) != 0) {
2411 if (!_clip_planes_enabled) {
2412 enable_clip_planes(
true);
2413 _clip_planes_enabled =
true;
2416 enable_clip_plane(num_enabled,
true);
2417 if (num_enabled == 0) {
2418 begin_bind_clip_planes();
2421 bind_clip_plane(plane, num_enabled);
2428 for (i = num_enabled; i < _num_clip_planes_enabled; ++i) {
2429 enable_clip_plane(i,
false);
2431 _num_clip_planes_enabled = num_enabled;
2434 if (num_enabled == 0) {
2435 if (_clip_planes_enabled) {
2436 enable_clip_planes(
false);
2437 _clip_planes_enabled =
false;
2440 end_bind_clip_planes();
2460 _target_rs->get_attrib_def(ColorAttrib::get_class_slot());
2463 case ColorAttrib::T_flat:
2466 _scene_graph_color = target_color->
get_color();
2467 _has_scene_graph_color =
true;
2468 _vertex_colors_enabled =
false;
2471 case ColorAttrib::T_off:
2474 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2475 _has_scene_graph_color =
false;
2476 _vertex_colors_enabled =
false;
2479 case ColorAttrib::T_vertex:
2482 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2483 _has_scene_graph_color =
false;
2484 _vertex_colors_enabled =
true;
2488 if (_color_scale_via_lighting) {
2489 _state_mask.
clear_bit(LightAttrib::get_class_slot());
2490 _state_mask.
clear_bit(MaterialAttrib::get_class_slot());
2492 determine_light_color_scale();
2501 void GraphicsStateGuardian::
2502 do_issue_color_scale() {
2505 if (_has_texture_alpha_scale) {
2506 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2510 _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot());
2512 _color_scale_enabled = target_color_scale->
has_scale();
2513 _current_color_scale = target_color_scale->
get_scale();
2514 _has_texture_alpha_scale =
false;
2516 if (_color_blend_involves_color_scale) {
2517 _state_mask.
clear_bit(TransparencyAttrib::get_class_slot());
2519 if (_texture_involves_color_scale) {
2520 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2522 if (_color_scale_via_lighting) {
2523 _state_mask.
clear_bit(LightAttrib::get_class_slot());
2524 _state_mask.
clear_bit(MaterialAttrib::get_class_slot());
2526 determine_light_color_scale();
2529 if (_alpha_scale_via_texture && !_has_scene_graph_color &&
2533 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2534 _state_mask.
clear_bit(TexMatrixAttrib::get_class_slot());
2536 _has_texture_alpha_scale =
true;
2564 LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
2567 int num_enabled = 0;
2568 int num_on_lights = 0;
2571 _target_rs->get_attrib_def(LightAttrib::get_class_slot());
2573 if (display_cat.is_spam()) {
2575 <<
"do_issue_light: " << target_light <<
"\n";
2578 CPT(
LightAttrib) new_light = target_light->filter_to_max(_max_lights);
2579 if (display_cat.is_spam()) {
2580 new_light->write(display_cat.spam(
false), 2);
2583 num_on_lights = new_light->get_num_on_lights();
2584 for (
int li = 0; li < num_on_lights; li++) {
2585 NodePath light = new_light->get_on_light(li);
2588 nassertv(light_obj != (
Light *)NULL);
2591 if (!_lighting_enabled) {
2592 enable_lighting(
true);
2593 _lighting_enabled =
true;
2596 if (light_obj->get_type() == AmbientLight::get_class_type()) {
2599 cur_ambient_light += light_obj->get_color();
2602 const LColor &color = light_obj->get_color();
2604 if (color[0] != 0.0 || color[1] != 0.0 || color[2] != 0.0) {
2605 enable_light(num_enabled,
true);
2606 if (num_enabled == 0) {
2607 begin_bind_lights();
2610 light_obj->bind(
this, light, num_enabled);
2617 for (i = num_enabled; i < _num_lights_enabled; ++i) {
2618 enable_light(i,
false);
2620 _num_lights_enabled = num_enabled;
2623 if (num_on_lights == 0) {
2624 if (_color_scale_via_lighting && (_has_material_force_color || _light_color_scale !=
LVecBase4(1.0f, 1.0f, 1.0f, 1.0f))) {
2627 if (!_lighting_enabled) {
2628 enable_lighting(
true);
2629 _lighting_enabled =
true;
2631 set_ambient_light(
LColor(1.0f, 1.0f, 1.0f, 1.0f));
2634 if (_lighting_enabled) {
2635 enable_lighting(
false);
2636 _lighting_enabled =
false;
2641 set_ambient_light(cur_ambient_light);
2644 if (num_enabled != 0) {
2724 void GraphicsStateGuardian::
2725 init_frame_pstats() {
2727 _data_transferred_pcollector.clear_level();
2728 _vertex_buffer_switch_pcollector.clear_level();
2729 _index_buffer_switch_pcollector.clear_level();
2731 _primitive_batches_pcollector.clear_level();
2732 _primitive_batches_tristrip_pcollector.clear_level();
2733 _primitive_batches_trifan_pcollector.clear_level();
2734 _primitive_batches_tri_pcollector.clear_level();
2735 _primitive_batches_patch_pcollector.clear_level();
2736 _primitive_batches_other_pcollector.clear_level();
2737 _vertices_tristrip_pcollector.clear_level();
2738 _vertices_trifan_pcollector.clear_level();
2739 _vertices_tri_pcollector.clear_level();
2740 _vertices_patch_pcollector.clear_level();
2741 _vertices_other_pcollector.clear_level();
2743 _state_pcollector.clear_level();
2744 _transform_state_pcollector.clear_level();
2745 _texture_state_pcollector.clear_level();
2757 create_gamma_table (PN_stdfloat gamma,
unsigned short *red_table,
unsigned short *green_table,
unsigned short *blue_table) {
2765 for (i = 0; i < 256; i++) {
2768 PN_stdfloat gamma_correction;
2770 x = ((double) i / 255.0);
2771 gamma_correction = 1.0 / gamma;
2772 x = pow (x, (
double) gamma_correction);
2778 red_table [i] = (int)g;
2779 green_table [i] = (int)g;
2780 blue_table [i] = (int)g;
2792 void GraphicsStateGuardian::
2793 reissue_transforms() {
2804 void GraphicsStateGuardian::
2805 enable_lighting(
bool enable) {
2816 void GraphicsStateGuardian::
2817 set_ambient_light(
const LColor &color) {
2827 void GraphicsStateGuardian::
2828 enable_light(
int light_id,
bool enable) {
2843 void GraphicsStateGuardian::
2844 begin_bind_lights() {
2856 void GraphicsStateGuardian::
2868 void GraphicsStateGuardian::
2869 enable_clip_planes(
bool enable) {
2880 void GraphicsStateGuardian::
2881 enable_clip_plane(
int plane_id,
bool enable) {
2896 void GraphicsStateGuardian::
2897 begin_bind_clip_planes() {
2908 void GraphicsStateGuardian::
2909 bind_clip_plane(
const NodePath &plane,
int plane_id) {
2921 void GraphicsStateGuardian::
2922 end_bind_clip_planes() {
2931 void GraphicsStateGuardian::
2932 determine_target_texture() {
2934 _target_rs->get_attrib_def(TextureAttrib::get_class_slot());
2936 _target_rs->get_attrib_def(TexGenAttrib::get_class_slot());
2940 _target_texture = target_texture;
2941 _target_tex_gen = target_tex_gen;
2943 if (_has_texture_alpha_scale) {
2947 _target_texture = DCAST(
TextureAttrib, _target_texture->add_on_stage(stage, texture));
2948 _target_tex_gen = DCAST(
TexGenAttrib, _target_tex_gen->add_stage
2949 (stage, TexGenAttrib::M_constant,
LTexCoord3(_current_color_scale[3], 0.0f, 0.0f)));
2953 _target_texture = _target_texture->filter_to_max(max_texture_stages);
2954 nassertv(_target_texture->get_num_on_stages() <= max_texture_stages);
2963 void GraphicsStateGuardian::
2975 void GraphicsStateGuardian::
2982 _closing_gsg =
true;
2984 if (display_cat.is_debug()) {
2986 <<
this <<
" close_gsg " << get_type() <<
"\n";
3003 _prepared_objects->begin_frame(
this, current_thread);
3004 _prepared_objects->end_frame(current_thread);
3010 _pending_timer_queries.clear();
3025 void GraphicsStateGuardian::
3026 panic_deactivate() {
3029 <<
"Deactivating " << get_type() <<
".\n";
3031 throw_event(
"panic-deactivate-gsg",
this);
3043 void GraphicsStateGuardian::
3044 determine_light_color_scale() {
3045 if (_has_scene_graph_color) {
3049 _has_material_force_color =
true;
3050 _material_force_color = _scene_graph_color;
3051 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3052 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3053 _material_force_color.set(_scene_graph_color[0] * _current_color_scale[0],
3054 _scene_graph_color[1] * _current_color_scale[1],
3055 _scene_graph_color[2] * _current_color_scale[2],
3056 _scene_graph_color[3] * _current_color_scale[3]);
3062 _has_material_force_color =
false;
3063 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3064 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3065 _light_color_scale = _current_color_scale;
3079 state = RenderState::make(LightAttrib::make_all_off());
3090 get_unclipped_state() {
3093 state = RenderState::make(ClipPlaneAttrib::make_all_off());
3104 get_untextured_state() {
3107 state = RenderState::make(TextureAttrib::make_off());
3123 void GraphicsStateGuardian::
3125 nassertv(_loader != (
Loader *)NULL);
3129 priority = _current_display_region->get_texture_reload_priority();
3132 string task_name = string(
"reload:") + tc->
get_texture()->get_name();
3138 for (
int ti = 0; ti < num_tasks; ++ti) {
3140 if (task->
is_exact_type(TextureReloadRequest::get_class_type()) &&
3154 _supports_compressed_texture);
3156 _loader->load_async(request);
3168 PT(
Texture) GraphicsStateGuardian::
3171 nassertr(light_np.
node()->
is_of_type(DirectionalLight::get_class_type()) ||
3176 if (light == NULL || !light->_shadow_caster) {
3180 bool is_point = light->is_of_type(PointLight::get_class_type());
3182 nassertr(light->_sbuffers.count(
this) == 0, NULL);
3184 if (display_cat.is_debug()) {
3186 <<
"Constructing shadow buffer for light '" << light->get_name()
3187 <<
"', size=" << light->_sb_xsize <<
"x" << light->_sb_ysize
3188 <<
", sort=" << light->_sb_sort <<
"\n";
3193 fbp.set_depth_bits(shadow_depth_bits);
3196 int flags = GraphicsPipe::BF_refuse_window;
3198 flags |= GraphicsPipe::BF_size_square;
3203 light->_sb_sort, fbp, props, flags,
this, DCAST(
GraphicsOutput, host));
3204 nassertr(sbuffer != NULL, NULL);
3209 if (light->_sb_xsize != light->_sb_ysize) {
3211 <<
"PointLight shadow buffers must have an equal width and height!\n";
3213 tex->
setup_cube_map(light->_sb_xsize, Texture::T_unsigned_byte, Texture::F_depth_component);
3215 tex->setup_2d_texture(light->_sb_xsize, light->_sb_ysize, Texture::T_unsigned_byte, Texture::F_depth_component);
3217 tex->make_ram_image();
3218 sbuffer->add_render_texture(tex, GraphicsOutput::RTM_bind_or_copy, GraphicsOutput::RTP_depth);
3222 tex->set_wrap_u(SamplerState::WM_clamp);
3223 tex->set_wrap_v(SamplerState::WM_clamp);
3225 tex->set_wrap_u(SamplerState::WM_border_color);
3226 tex->set_wrap_v(SamplerState::WM_border_color);
3227 tex->set_border_color(
LVecBase4(1, 1, 1, 1));
3232 tex->set_minfilter(SamplerState::FT_shadow);
3233 tex->set_magfilter(SamplerState::FT_shadow);
3236 tex->set_minfilter(SamplerState::FT_linear);
3237 tex->set_magfilter(SamplerState::FT_linear);
3242 for (
int i = 0; i < 6; ++i) {
3243 PT(
DisplayRegion) dr = sbuffer->make_mono_display_region(0, 1, 0, 1);
3244 dr->set_lens_index(i);
3245 dr->set_target_tex_page(i);
3246 dr->set_camera(light_np);
3247 dr->set_clear_depth_active(
true);
3250 PT(
DisplayRegion) dr = sbuffer->make_mono_display_region(0, 1, 0, 1);
3251 dr->set_camera(light_np);
3252 dr->set_clear_depth_active(
true);
3254 light->_sbuffers[
this] = sbuffer;
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.
virtual bool is_linear() const
Returns true if the lens represents a linear projection (e.g.
bool has_scale() const
Returns true if the ColorScaleAttrib has a non-identity scale, false otherwise (in which case it migh...
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.
Fog * get_fog() const
If the FogAttrib is not an 'off' FogAttrib, returns the fog that is associated.
virtual int get_driver_version_major()
Returns major version of the video driver.
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.
static const LMatrix4f & ident_mat()
Returns an identity matrix.
virtual Light * as_light()
Cross-casts the node to a Light pointer, if it is one of the four kinds of Light nodes, or returns NULL if it is not.
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...
This is the base class for all three-component vectors and points.
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.
const float * get_data() const
Returns the address of the first of the four data elements in the vector.
int get_z_size() const
Returns the depth of the texture image in texels.
virtual void release_shader(ShaderContext *sc)
Releases the resources allocated by prepare_shader.
virtual TextureContext * prepare_texture(Texture *tex)
Creates whatever structures the GSG requires to represent the texture internally, and returns a newly...
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, both of which are conceptually rectangular regions into which drawing commands may be issued.
virtual void clear_before_callback()
Resets any non-standard graphics state that might give a callback apoplexy.
Material * get_material() const
If the MaterialAttrib is not an 'off' MaterialAttrib, returns the material that is associated...
virtual void release_index_buffer(IndexBufferContext *ibc)
Frees the resources previously allocated via a call to prepare_data(), including deleting the IndexBu...
virtual void release_geom(GeomContext *gc)
Frees the resources previously allocated via a call to prepare_geom(), including deleting the GeomCon...
static WindowProperties size(int x_size, int y_size)
Returns a WindowProperties structure with only the size specified.
const LColor & get_color() const
If the type is T_flat or T_off, this returns the color that will be applied to geometry.
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.
GraphicsPipe * get_pipe() const
Returns the graphics pipe on which this GSG was created.
virtual const LColor & get_specular_color() const
Returns the color of specular highlights generated by the light.
bool get_supports_shadow_filter() const
Returns true if this particular GSG supports the filter mode FT_shadow for depth textures.
This loader request will call Texture::get_ram_image() in a sub-thread, to force the texture's image ...
static LMatrix4f translate_mat(const LVecBase3f &trans)
Returns a matrix that applies the indicated translation.
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.
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...
LVecBase3f xform_vec(const LVecBase3f &v) const
The matrix transforms a 3-component vector (without translation component) and returns the result...
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...
const LVecBase4 & get_scale() const
Returns the scale to be applied to colors.
NodePath get_on_plane(int n) const
Returns the nth plane enabled by the attribute, sorted in render order.
static void remove_gsg(GraphicsStateGuardianBase *gsg)
Called by a GSG destructor to remove a GSG from the available list.
virtual void prepare_display_region(DisplayRegionPipelineReader *dr)
Makes the specified DisplayRegion current.
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.
PN_stdfloat get_shininess() const
Returns the shininess exponent of the material.
A node that contains a Lens.
virtual bool has_extension(const string &extension) const
Returns true if the GSG implements the extension identified by the given string.
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...
virtual bool set_gamma(PN_stdfloat gamma)
Set gamma.
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-...
A list of tasks, for instance as returned by some of the AsyncTaskManager query functions.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
void traverse_prepared_textures(TextureCallback *func, void *callback_arg)
Calls the indicated function on all currently-prepared textures, or until the callback function retur...
A convenient class for loading models from disk, in bam or egg format (or any of a number of other fo...
This is a special class object that holds all the information returned by a particular GSG to indicat...
virtual void remove_window(GraphicsOutputBase *window)
This is simply a transparent call to GraphicsEngine::remove_window().
const Lens * get_lens() const
Returns the particular Lens used for rendering.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
A light source that seems to illuminate all points in space at once.
void set_active(bool active)
Sets the active flag associated with the GraphicsStateGuardian.
virtual void restore_gamma()
Restore original gamma setting.
This functions similarly to a LightAttrib.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
double get_frame_time(Thread *current_thread=Thread::get_current_thread()) const
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
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.
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...
AsyncTask * get_task(int index) const
Returns the nth AsyncTask in the collection.
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...
Type get_color_type() const
Returns the type of color specified by this ColorAttrib.
static const LMatrix4f & convert_mat(CoordinateSystem from, CoordinateSystem to)
Returns a matrix that transforms from the indicated coordinate system to the indicated coordinate sys...
int get_priority() const
Returns the task's current priority value.
void setup_cube_map()
Sets the texture as an empty cube map texture with no dimensions.
const TransformState * get_camera_transform() const
Returns the position of the camera relative to the starting node.
const TransformState * get_cs_world_transform() const
Returns the position from the starting node relative to the camera, in the GSG's internal coordinate ...
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
int get_pad_x_size() const
Returns size of the pad region.
int get_buffer_mask() const
Converts the non-aux bitplanes of the framebuffer into a RenderBuffer::Type.
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...
const LColor & get_diffuse() const
Returns the diffuse color setting, if it has been set.
bool is_identity() const
Returns true if the ColorScaleAttrib is an identity attrib, false if it is either an off attrib or it...
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.
const LColor & get_ambient() const
Returns the ambient color setting, if it has been set.
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.
int get_max_texture_stages() const
Returns the maximum number of simultaneous textures that may be applied to geometry with multitexturi...
static Loader * get_global_ptr()
Returns a pointer to the global Loader.
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().
int get_num_on_planes() const
Returns the number of planes that are enabled by the attribute.
void clear_flash_texture()
Resets the "flash texture", so that no textures will flash.
virtual PN_stdfloat compute_distance_to(const LPoint3 &point) const
This function will compute the distance to the indicated point, assumed to be in eye coordinates...
virtual void clear_state_and_transform()
Forgets the current graphics state and current transform, so that the next call to set_state_and_tran...
LVecBase3f xform_point(const LVecBase3f &v) const
The matrix transforms a 3-component point (including translation component) and returns the result...
int get_frame_count(Thread *current_thread=Thread::get_current_thread()) const
Returns the number of times tick() has been called since the ClockObject was created, or since it was last reset.
This is a 4-by-4 transform matrix.
virtual string get_driver_vendor()
Returns the vendor of the video card driver.
const Shader::ShaderPtrData * fetch_ptr_parameter(const Shader::ShaderPtrSpec &spec)
Return a pointer to struct ShaderPtrData.
Specifies how atmospheric fog effects are applied to geometry.
virtual PreparedGraphicsObjects * get_prepared_objects()
Returns the set of texture and geom objects that have been prepared with this GSG (and possibly other...
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.
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...
virtual bool draw_lines(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of disconnected line segments.
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, with a cone-shaped falloff.
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.
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.
virtual ShaderContext * prepare_shader(Shader *shader)
Compile a vertex/fragment shader body.
void set_bit(int index)
Sets the nth bit on.
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.
virtual int get_driver_shader_version_minor()
Returns the minor version of the shader model.
GraphicsOutput * make_output(GraphicsPipe *pipe, const string &name, int sort, const FrameBufferProperties &fb_prop, const WindowProperties &win_prop, int flags, GraphicsStateGuardian *gsg=NULL, GraphicsOutput *host=NULL)
Creates a new window (or buffer) and returns it.
int get_num_tasks() const
Returns the number of AsyncTasks in the collection.
virtual SamplerContext * prepare_sampler(const SamplerState &sampler)
Creates whatever structures the GSG requires to represent the sampler internally, and returns a newly...
Applies a scale to colors in the scene graph and on vertices.
virtual int get_driver_shader_version_major()
Returns the major version of the shader model.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
int get_num_on_lights() const
Returns the number of lights that are turned on by the attribute.
PN_stdfloat get_exp_density() const
Returns the density of the fog for exponential calculations.
Represents a set of settings that indicate how a texture is sampled.
virtual int get_driver_version_minor()
Returns the minor version of the video driver.
This is the base class for all three-component vectors and points.
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomMunger *munger, const GeomVertexDataPipelineReader *data_reader, bool force)
Called before a sequence of draw_primitive() functions are called, this should prepare the vertex dat...
This is a special class object that holds a handle to the sampler state object given by the graphics ...
static const LMatrix4f & zeros_mat()
Returns an matrix filled with zeros.
Applies a transform matrix to UV's before they are rendered.
virtual SceneSetup * get_scene() const
Returns the current SceneSetup object.
const TransformState * get_world_transform() const
Returns the position of the starting node relative to the camera.
This class represents a concrete task performed by an AsyncManager.
const LVector3 & get_direction() const
Returns the direction in which the light is aimed.
PandaNode * node() const
Returns the referenced node of the path.
void set_priority(int priority)
Specifies a priority value for this task.
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...
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...
A derivative of Light and of Camera.
int get_y_size() const
Returns the height of the texture image in texels.
This is a special class object that holds all the information returned by a particular GSG to indicat...
bool is_off() const
Returns true if the MaterialAttrib is an 'off' MaterialAttrib, indicating that it should disable the ...
const LColor & get_color() const
Returns the color of the fog.
virtual void end_scene()
Called between begin_frame() and end_frame() to mark the end of drawing commands for a "scene" (usual...
Texture * get_flash_texture() const
Returns the current "flash texture", if any, or NULL if none.
virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of line strips.
static bool is_connected()
Returns true if the client believes it is connected to a working PStatServer, false otherwise...
virtual bool get_supports_multisample() const
Returns true if this particular GSG supports using the multisample bits to provide antialiasing...
virtual string get_driver_version()
Returns driver version This has an implementation-defined meaning, and may be "" if the particular gr...
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.
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.
void set_row(int row, const LVecBase4f &v)
Replaces the indicated row of the matrix.
An abstract base class for GraphicsOutput, for all the usual reasons.
const LColor & get_color() const
Returns the basic color of the light.
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...
This class is the main interface to controlling the render process.
const LColor & get_emission() const
Returns the emission color setting, if it has been set.
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.
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
bool get_swap_eyes() const
Returns the current setting of the "swap eyes" flag.
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...
bool set_scene(SceneSetup *scene_setup)
Sets the SceneSetup object that indicates the initial camera position, etc.
virtual IndexBufferContext * prepare_index_buffer(GeomPrimitive *data)
Prepares the indicated buffer for retained-mode rendering.
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...
bool normalize()
Normalizes the vector in place.
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.
void set_flash_texture(Texture *tex)
Sets the "flash texture".
LVecBase3f get_row3(int row) const
Retrieves the row column of the matrix as a 3-component vector, ignoring the last column...
A RenderBuffer is an arbitrary subset of the various layers (depth buffer, color buffer, etc.) of a drawing region.
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...
static const LMatrix4f & ones_mat()
Returns an matrix filled with ones.
void set_coordinate_system(CoordinateSystem cs)
Changes the coordinate system in effect on this particular gsg.
const LColor & get_specular() const
Returns the specular color setting, if it has been set.
A light originating from a single point in space, and shining in all directions.
double get_dt(Thread *current_thread=Thread::get_current_thread()) const
Returns the elapsed time for the previous frame: the number of seconds elapsed between the last two c...
A node that contains a plane.
PN_stdfloat get_gamma(PN_stdfloat gamma)
Get the current gamma setting.
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...
int get_x_size() const
Returns the width of the texture image in texels.
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" ...
NodePath get_on_light(int n) const
Returns the nth light turned on by the attribute, sorted in render order.
virtual string get_driver_renderer()
Returns GL_Renderer.
virtual bool get_supports_cg_profile(const string &name) const
Returns true if this particular GSG supports the specified Cg Shader Profile.
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, this should set up the associated hardware light with the light's properties.