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");
144 _internal_coordinate_system(internal_coordinate_system),
148 _coordinate_system = CS_invalid;
149 _internal_transform = TransformState::make_identity();
151 set_coordinate_system(get_default_coordinate_system());
155 _current_stereo_channel = Lens::SC_mono;
156 _current_tex_view_offset = 0;
157 _current_lens = (
Lens *)NULL;
158 _projection_mat = TransformState::make_identity();
159 _projection_mat_inv = TransformState::make_identity();
163 _current_properties = NULL;
164 _closing_gsg =
false;
167 _stereo_buffer_mask = ~0;
168 _incomplete_render = allow_incomplete_render;
169 _effective_incomplete_render =
false;
172 _is_hardware =
false;
173 _prefers_triangle_strips =
false;
174 _max_vertices_per_array = INT_MAX;
175 _max_vertices_per_primitive = INT_MAX;
180 _max_texture_stages = 1;
184 _max_texture_dimension = -1;
185 _max_3d_texture_dimension = 0;
186 _max_2d_texture_array_layers = 0;
187 _max_cube_map_dimension = 0;
191 _supports_texture_combine =
false;
192 _supports_texture_saved_result =
false;
193 _supports_texture_dot3 =
false;
195 _supports_3d_texture =
false;
196 _supports_2d_texture_array =
false;
197 _supports_cube_map =
false;
198 _supports_tex_non_pow2 =
false;
199 _supports_texture_srgb =
false;
200 _supports_compressed_texture =
false;
201 _compressed_texture_formats.clear();
202 _compressed_texture_formats.set_bit(Texture::CM_off);
206 _max_clip_planes = -1;
209 _max_vertex_transforms = 0;
210 _max_vertex_transform_indices = 0;
212 _supports_occlusion_query =
false;
213 _supports_timer_query =
false;
216 _timer_queries_active =
false;
217 _last_query_frame = 0;
218 _last_num_queried = 0;
221 _pstats_gpu_thread = -1;
226 _copy_texture_inverted =
false;
229 _supports_multisample =
false;
230 _supports_generate_mipmap =
false;
231 _supports_depth_texture =
false;
232 _supports_depth_stencil =
false;
233 _supports_shadow_filter =
false;
234 _supports_sampler_objects =
false;
235 _supports_basic_shaders =
false;
236 _supports_geometry_shaders =
false;
237 _supports_tessellation_shaders =
false;
238 _supports_glsl =
false;
240 _supports_stencil =
false;
241 _supports_stencil_wrap =
false;
242 _supports_two_sided_stencil =
false;
243 _supports_geometry_instancing =
false;
246 _max_color_targets = 1;
248 _supported_geom_rendering = 0;
253 _color_scale_via_lighting = color_scale_via_lighting;
257 _alpha_scale_via_texture = alpha_scale_via_texture;
261 _runtime_color_scale =
false;
264 _auto_detect_shader_model = SM_00;
265 _shader_model = SM_00;
268 _texture_quality_override = Texture::QL_default;
276 GraphicsStateGuardian::
277 ~GraphicsStateGuardian() {
292 nassertr(_engine != (
GraphicsEngine *)NULL, GraphicsEngine::get_global_ptr());
311 return _supports_multisample;
328 return _supported_geom_rendering;
357 if (cs == CS_default) {
358 cs = get_default_coordinate_system();
360 if (_coordinate_system == cs) {
363 _coordinate_system = cs;
366 if (_internal_coordinate_system == CS_default ||
367 _internal_coordinate_system == _coordinate_system) {
368 _cs_transform = TransformState::make_identity();
369 _inv_cs_transform = TransformState::make_identity();
373 TransformState::make_mat
375 _internal_coordinate_system));
377 TransformState::make_mat
379 _coordinate_system));
398 return _internal_coordinate_system;
410 return _prepared_objects;
453 void *callback_arg) {
455 PreparedGraphicsObjects::Textures::const_iterator ti;
456 for (ti = _prepared_objects->_prepared_textures.begin();
457 ti != _prepared_objects->_prepared_textures.end();
459 bool result = (*func)(*ti, callback_arg);
492 _flash_texture = tex;
505 _flash_texture = NULL;
518 return _flash_texture;
533 _scene_setup = scene_setup;
534 _current_lens = scene_setup->
get_lens();
535 if (_current_lens == (
Lens *)NULL) {
541 _projection_mat = calc_projection_mat(_current_lens);
542 if (_projection_mat == 0) {
545 _projection_mat_inv = _projection_mat->get_inverse();
777 end_occlusion_query() {
780 _current_occlusion_query = NULL;
791 issue_timer_query(
int pstats_index) {
824 if (!nc_state->_mungers.empty()) {
825 RenderState::Mungers::const_iterator mi = nc_state->_last_mi;
826 if (!(*mi).first.was_deleted() && (*mi).first ==
this) {
827 if ((*mi).second->is_registered()) {
834 RenderState::Mungers::iterator mi = nc_state->_mungers.find(
this);
835 if (mi != nc_state->_mungers.end() && !(*mi).first.was_deleted()) {
836 if ((*mi).second->is_registered()) {
837 nc_state->_last_mi = mi;
842 nc_state->_mungers.erase(mi);
846 PT(
GeomMunger) munger = make_geom_munger(nc_state, current_thread);
847 nassertr(munger != (
GeomMunger *)NULL && munger->is_registered(), munger);
849 mi = nc_state->_mungers.insert(
RenderState::Mungers::value_type(this, munger)).first;
850 nc_state->_last_mi = mi;
880 switch (_internal_coordinate_system) {
895 <<
"Invalid coordinate system in compute_distance_to: "
896 << (int)_internal_coordinate_system <<
"\n";
938 if (altered & spec._dep[0]) {
940 if (t != &spec._cache[0]) {
944 if (altered & spec._dep[1]) {
946 if (t != &spec._cache[1]) {
952 case Shader::SMF_compose:
953 spec._value.multiply(spec._cache[0], spec._cache[1]);
955 case Shader::SMF_transform_dlight:
956 spec._value = spec._cache[0];
964 case Shader::SMF_transform_plight:
965 spec._value = spec._cache[0];
968 case Shader::SMF_transform_slight:
969 spec._value = spec._cache[0];
975 case Shader::SMF_first:
976 return &spec._cache[0];
993 case Shader::SMO_identity: {
996 case Shader::SMO_window_size: {
998 _current_display_region->get_pixel_height(),
1002 case Shader::SMO_pixel_size: {
1004 _current_display_region->get_pixel_height(),
1008 case Shader::SMO_frame_time: {
1010 t =
LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time);
1013 case Shader::SMO_frame_delta: {
1015 t =
LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt);
1018 case Shader::SMO_texpad_x: {
1019 Texture *tex = _target_shader->get_shader_input_texture(name);
1027 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,cx,cy,cz,0);
1030 case Shader::SMO_texpix_x: {
1031 Texture *tex = _target_shader->get_shader_input_texture(name);
1036 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,px,py,pz,0);
1039 case Shader::SMO_attr_material: {
1041 _target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
1043 if (target_material->
is_off()) {
1044 t =
LMatrix4(1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0);
1053 t =
LMatrix4(amb[0],amb[1],amb[2],amb[3],
1054 dif[0],dif[1],dif[2],dif[3],
1055 emm[0],emm[1],emm[2],emm[3],
1056 spc[0],spc[1],spc[2],spc[3]);
1059 case Shader::SMO_attr_color: {
1061 _target_rs->get_attrib_def(ColorAttrib::get_class_slot());
1066 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]);
1069 case Shader::SMO_attr_colorscale: {
1071 _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot());
1076 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,cs[0],cs[1],cs[2],cs[3]);
1079 case Shader::SMO_attr_fog: {
1081 _target_rs->get_attrib_def(FogAttrib::get_class_slot());
1083 if (fog == (
Fog*) NULL) {
1086 PN_stdfloat start, end;
1088 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,fog->
get_exp_density(),start,end,1.0f/(end-start));
1091 case Shader::SMO_attr_fogcolor: {
1093 _target_rs->get_attrib_def(FogAttrib::get_class_slot());
1095 if (fog == (
Fog*) NULL) {
1099 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]);
1102 case Shader::SMO_alight_x: {
1103 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1107 LColor const &c = lt->get_color();
1108 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]);
1111 case Shader::SMO_satten_x: {
1112 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1116 LVecBase3 const &a = lt->get_attenuation();
1117 PN_stdfloat x = lt->get_exponent();
1118 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,a[0],a[1],a[2],x);
1121 case Shader::SMO_dlight_x: {
1123 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1127 LColor const &c = lt->get_color();
1128 LColor const &s = lt->get_specular_color();
1129 t = np.get_net_transform()->
get_mat() *
1135 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);
1138 case Shader::SMO_plight_x: {
1140 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1144 LColor const &c = lt->get_color();
1145 LColor const &s = lt->get_specular_color();
1146 t = np.get_net_transform()->
get_mat() *
1150 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);
1153 case Shader::SMO_slight_x: {
1155 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1159 Lens *lens = lt->get_lens();
1161 LColor const &c = lt->get_color();
1162 LColor const &s = lt->get_specular_color();
1163 PN_stdfloat cutoff = ccos(deg_2_rad(lens->get_hfov() * 0.5f));
1164 t = np.get_net_transform()->
get_mat() *
1168 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);
1171 case Shader::SMO_light_ambient: {
1172 LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
1174 _target_rs->get_attrib_def(LightAttrib::get_class_slot());
1177 if (num_on_lights == 0) {
1182 for (
int li = 0; li < num_on_lights; li++) {
1188 if (light_obj->get_type() == AmbientLight::get_class_type()) {
1189 cur_ambient_light += light_obj->get_color();
1192 t.
set_row(3, cur_ambient_light);
1196 case Shader::SMO_texmat_x: {
1199 int stagenr = atoi(name->get_name().c_str());
1200 if (stagenr >= ta->get_num_on_stages()) {
1203 return &tma->
get_mat(ta->get_on_stage(stagenr));
1205 case Shader::SMO_plane_x: {
1206 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1210 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,p[0],p[1],p[2],p[3]);
1213 case Shader::SMO_clipplane_x: {
1215 int planenr = atoi(name->get_name().c_str());
1223 p.xform(np.get_net_transform()->
get_mat());
1224 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,p[0],p[1],p[2],p[3]);
1227 case Shader::SMO_apiview_clipplane_i: {
1238 CPT(TransformState) transform =
1240 plane.
get_transform(_scene_setup->get_scene_root().get_parent()));
1242 LPlane xformed_plane = plane_node->get_plane() * transform->get_mat();
1246 case Shader::SMO_mat_constant_x: {
1247 return &_target_shader->get_shader_input_matrix(name, t);
1249 case Shader::SMO_vec_constant_x: {
1250 const LVecBase4 &input = _target_shader->get_shader_input_vector(name);
1251 const PN_stdfloat *data = input.
get_data();
1252 t =
LMatrix4(data[0],data[1],data[2],data[3],
1253 data[0],data[1],data[2],data[3],
1254 data[0],data[1],data[2],data[3],
1255 data[0],data[1],data[2],data[3]);
1258 case Shader::SMO_world_to_view: {
1262 case Shader::SMO_view_to_world: {
1265 case Shader::SMO_model_to_view: {
1266 return &(get_external_transform()->get_mat());
1268 case Shader::SMO_model_to_apiview: {
1269 return &(get_internal_transform()->get_mat());
1271 case Shader::SMO_view_to_model: {
1272 t = get_external_transform()->get_inverse()->get_mat();
1275 case Shader::SMO_apiview_to_model: {
1276 t = get_internal_transform()->get_inverse()->get_mat();
1279 case Shader::SMO_apiview_to_view: {
1280 return &(_inv_cs_transform->get_mat());
1282 case Shader::SMO_view_to_apiview: {
1283 return &(_cs_transform->get_mat());
1285 case Shader::SMO_clip_to_view: {
1286 if (_current_lens->get_coordinate_system() == _coordinate_system) {
1287 return &(_current_lens->get_projection_mat_inv(_current_stereo_channel));
1289 t = _current_lens->get_projection_mat_inv(_current_stereo_channel) *
1294 case Shader::SMO_view_to_clip: {
1295 if (_current_lens->get_coordinate_system() == _coordinate_system) {
1296 return &(_current_lens->get_projection_mat(_current_stereo_channel));
1299 _current_lens->get_projection_mat(_current_stereo_channel);
1303 case Shader::SMO_apiclip_to_view: {
1304 t = _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat();
1307 case Shader::SMO_view_to_apiclip: {
1308 t = _cs_transform->get_mat() * _projection_mat->get_mat();
1311 case Shader::SMO_apiclip_to_apiview: {
1312 return &(_projection_mat_inv->get_mat());
1314 case Shader::SMO_apiview_to_apiclip: {
1315 return &(_projection_mat->get_mat());
1317 case Shader::SMO_view_x_to_view: {
1318 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1320 t = np.get_net_transform()->
get_mat() *
1324 case Shader::SMO_view_to_view_x: {
1325 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1328 np.get_net_transform()->get_inverse()->
get_mat();
1331 case Shader::SMO_apiview_x_to_view: {
1332 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1335 np.get_net_transform()->
get_mat() *
1339 case Shader::SMO_view_to_apiview_x: {
1340 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1343 np.get_net_transform()->get_inverse()->
get_mat() *
1347 case Shader::SMO_clip_x_to_view: {
1348 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1352 t = lens->get_projection_mat_inv(_current_stereo_channel) *
1354 np.get_net_transform()->
get_mat() *
1358 case Shader::SMO_view_to_clip_x: {
1359 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1364 np.get_net_transform()->get_inverse()->
get_mat() *
1366 lens->get_projection_mat(_current_stereo_channel);
1369 case Shader::SMO_apiclip_x_to_view: {
1370 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1374 t = calc_projection_mat(lens)->get_inverse()->get_mat() *
1375 get_cs_transform_for(lens->get_coordinate_system())->get_inverse()->get_mat() *
1376 np.get_net_transform()->
get_mat() *
1380 case Shader::SMO_view_to_apiclip_x: {
1381 const NodePath &np = _target_shader->get_shader_input_nodepath(name);
1386 np.get_net_transform()->get_inverse()->
get_mat() *
1387 get_cs_transform_for(lens->get_coordinate_system())->get_mat() *
1388 calc_projection_mat(lens)->get_mat();
1391 case Shader::SMO_vec_constant_x_attrib: {
1393 if (_target_shader->has_shader_input(name)) {
1396 const LVecBase4 &data = _target_shader->get_shader_input_vector(name);
1397 t =
LMatrix4(data[0],data[1],data[2],data[3],
1398 data[0],data[1],data[2],data[3],
1399 data[0],data[1],data[2],data[3],
1400 data[0],data[1],data[2],data[3]);
1404 const NodePath &np = _target_shader->get_shader_input_nodepath(name->get_parent());
1418 static const CPT_InternalName IN_constantAttenuation(
"constantAttenuation");
1420 static const CPT_InternalName IN_quadraticAttenuation(
"quadraticAttenuation");
1422 if (attrib == IN_ambient) {
1427 c.componentwise_mult(_light_color_scale);
1435 }
else if (attrib == IN_diffuse) {
1443 c.componentwise_mult(_light_color_scale);
1448 }
else if (attrib == IN_specular) {
1454 }
else if (attrib == IN_position) {
1457 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
1459 }
else if (np.
node()->
is_of_type(DirectionalLight::get_class_type())) {
1463 CPT(TransformState) transform = np.
get_transform(_scene_setup->get_scene_root().get_parent());
1466 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,dir[0],dir[1],dir[2],0);
1474 CPT(TransformState) transform =
1476 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1478 const LMatrix4 &light_mat = transform->get_mat();
1479 LPoint3 pos = lens->get_nodal_point() * light_mat;
1484 }
else if (attrib == IN_halfVector) {
1487 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
1489 }
else if (np.
node()->
is_of_type(DirectionalLight::get_class_type())) {
1493 CPT(TransformState) transform = np.
get_transform(_scene_setup->get_scene_root().get_parent());
1499 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,dir[0],dir[1],dir[2],1);
1507 CPT(TransformState) transform =
1509 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1511 const LMatrix4 &light_mat = transform->get_mat();
1512 LPoint3 pos = lens->get_nodal_point() * light_mat;
1516 t =
LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,pos[0],pos[1],pos[2],1);
1520 }
else if (attrib == IN_spotDirection) {
1531 CPT(TransformState) transform =
1533 np.
get_transform(_scene_setup->get_scene_root().get_parent()));
1535 const LMatrix4 &light_mat = transform->get_mat();
1536 LVector3 dir = lens->get_view_vector() * light_mat;
1541 }
else if (attrib == IN_spotCutoff) {
1548 float cutoff = lens->get_hfov() * 0.5f;
1557 }
else if (attrib == IN_spotCosCutoff) {
1564 float cutoff = lens->get_hfov() * 0.5f;
1572 }
else if (attrib == IN_spotExponent) {
1579 }
else if (attrib == IN_constantAttenuation) {
1586 }
else if (attrib == IN_linearAttenuation) {
1593 }
else if (attrib == IN_quadraticAttenuation) {
1602 <<
"Shader input requests invalid attribute " << *name
1603 <<
" from node " << np <<
"\n";
1620 return (_target_shader->get_shader_input_ptr(spec._arg));
1632 _current_display_region = dr->get_object();
1635 _effective_incomplete_render = _incomplete_render && _current_display_region->get_incomplete_render();
1637 _stereo_buffer_mask = ~0;
1642 switch (output_channel) {
1644 output_channel = Lens::SC_right;
1647 case Lens::SC_right:
1648 output_channel = Lens::SC_left;
1656 switch (output_channel) {
1659 if (_current_properties->is_stereo()) {
1664 case Lens::SC_right:
1666 if (_current_properties->is_stereo()) {
1672 case Lens::SC_stereo:
1673 _color_write_mask = ColorWriteAttrib::C_all;
1703 reissue_transforms();
1706 _state_rs = RenderState::make_empty();
1707 _state_mask.
clear();
1723 DCAST_INTO_V(win, window);
1752 calc_projection_mat(const
Lens *lens) {
1753 if (lens == (
Lens *)NULL) {
1757 if (!lens->is_linear()) {
1761 return TransformState::make_identity();
1779 _prepared_objects->begin_frame(
this, current_thread);
1787 _state_rs = RenderState::make_empty();
1788 _state_mask.
clear();
1794 if (_last_query_frame < frame) {
1795 _last_query_frame = frame;
1796 _timer_queries_pcollector.clear_level();
1804 if (_timer_queries_active) {
1807 issue_timer_query(0x8000);
1808 issue_timer_query(0x0000);
1813 return !_needs_reset;
1852 _scene_setup = _scene_null;
1858 for (i = 0; i < _num_lights_enabled; ++i) {
1859 enable_light(i,
false);
1861 _num_lights_enabled = 0;
1864 for (i = 0; i < _num_clip_planes_enabled; ++i) {
1865 enable_clip_plane(i,
false);
1867 _num_clip_planes_enabled = 0;
1870 _state_rs = RenderState::make_empty();
1871 _state_mask.
clear();
1883 _prepared_objects->end_frame(current_thread);
1886 _data_transferred_pcollector.flush_level();
1888 _primitive_batches_pcollector.flush_level();
1889 _primitive_batches_tristrip_pcollector.flush_level();
1890 _primitive_batches_trifan_pcollector.flush_level();
1891 _primitive_batches_tri_pcollector.flush_level();
1892 _primitive_batches_patch_pcollector.flush_level();
1893 _primitive_batches_other_pcollector.flush_level();
1894 _vertices_tristrip_pcollector.flush_level();
1895 _vertices_trifan_pcollector.flush_level();
1896 _vertices_tri_pcollector.flush_level();
1897 _vertices_patch_pcollector.flush_level();
1898 _vertices_other_pcollector.flush_level();
1900 _state_pcollector.flush_level();
1901 _texture_state_pcollector.flush_level();
1902 _transform_state_pcollector.flush_level();
1903 _draw_primitive_pcollector.flush_level();
1906 _prepared_objects->_graphics_memory_lru.begin_epoch();
1923 PStatClient *client = PStatClient::get_global_pstats();
1925 if (!client->client_is_connected()) {
1926 _timer_queries_active =
false;
1930 if (!_timer_queries_active) {
1931 if (pstats_gpu_timing && _supports_timer_query) {
1933 _timer_queries_active =
true;
1941 if (_pstats_gpu_thread == -1) {
1944 PStatThread gpu_thread(client, _pstats_gpu_thread);
1948 if (!_pending_timer_queries.empty()) {
1949 int count = _pending_timer_queries.size();
1956 if (_last_num_queried > 0) {
1959 int i = min(_last_num_queried, count) - 1;
1961 if (_pending_timer_queries[i]->is_answer_ready()) {
1963 while (i < count - 1) {
1964 if (!_pending_timer_queries[++i]->is_answer_ready()) {
1972 if (_pending_timer_queries[--i]->is_answer_ready()) {
1983 int step = count / 2;
1984 int i = first + step;
1985 if (_pending_timer_queries[i]->is_answer_ready()) {
1998 _last_num_queried = first;
2002 for (
int i = 0; i < first; ++i) {
2005 double time_data = query->get_timestamp();
2007 if (query->_pstats_index == _command_latency_pcollector.get_index()) {
2010 cdef = client->get_collector_ptr(query->_pstats_index)->get_def(client, query->_pstats_index);
2011 _pstats_gpu_data.add_level(query->_pstats_index, time_data * cdef->_factor);
2013 }
else if (query->_pstats_index & 0x8000) {
2014 _pstats_gpu_data.add_stop(query->_pstats_index & 0x7fff, time_data);
2017 _pstats_gpu_data.add_start(query->_pstats_index & 0x7fff, time_data);
2023 if (query->_pstats_index == 0x8000) {
2025 _pstats_gpu_data.clear();
2032 _pending_timer_queries.erase(
2033 _pending_timer_queries.begin(),
2034 _pending_timer_queries.begin() + first
2036 _timer_queries_pcollector.add_level_now(first);
2066 begin_decal_base_first() {
2069 if (decal_base_first == (const
RenderState *)NULL) {
2070 decal_base_first = RenderState::make
2071 (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
2074 return decal_base_first;
2088 begin_decal_nested() {
2093 decal_nested = RenderState::make
2094 (DepthWriteAttrib::make(DepthWriteAttrib::M_off),
2097 return decal_nested;
2116 begin_decal_base_second() {
2121 if (decal_base_second == (const
RenderState *)NULL) {
2122 decal_base_second = RenderState::make
2123 (ColorWriteAttrib::make(ColorWriteAttrib::C_off),
2130 return decal_base_second;
2158 _data_reader = data_reader;
2159 return _data_reader->has_vertex();
2243 _data_reader = NULL;
2254 _needs_reset =
false;
2257 _state_rs = RenderState::make_empty();
2259 _state_mask.
clear();
2260 _internal_transform = _cs_transform;
2262 _scene_setup = _scene_null;
2264 _color_write_mask = ColorWriteAttrib::C_all;
2266 _has_scene_graph_color =
false;
2267 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2268 _transform_stale =
true;
2269 _color_blend_involves_color_scale =
false;
2270 _texture_involves_color_scale =
false;
2271 _vertex_colors_enabled =
true;
2272 _lighting_enabled =
false;
2273 _num_lights_enabled = 0;
2274 _num_clip_planes_enabled = 0;
2275 _clip_planes_enabled =
false;
2277 _color_scale_enabled =
false;
2278 _current_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
2279 _has_texture_alpha_scale =
false;
2281 _has_material_force_color =
false;
2282 _material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2283 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
2285 _tex_gen_modifies_mat =
false;
2286 _last_max_stage_index = 0;
2310 const TransformState *trans) {
2350 get_cs_transform_for(CoordinateSystem cs)
const {
2351 if (_coordinate_system == cs) {
2353 return _cs_transform;
2355 }
else if (_internal_coordinate_system == CS_default ||
2356 _internal_coordinate_system == cs) {
2357 return TransformState::make_identity();
2360 return TransformState::make_mat
2376 get_cs_transform()
const {
2377 return _cs_transform;
2387 void GraphicsStateGuardian::
2388 do_issue_clip_plane() {
2389 int num_enabled = 0;
2390 int num_on_planes = 0;
2393 _target_rs->get_attrib_def(ClipPlaneAttrib::get_class_slot());
2396 CPT(
ClipPlaneAttrib) new_plane = target_clip_plane->filter_to_max(_max_clip_planes);
2398 num_on_planes = new_plane->get_num_on_planes();
2399 for (
int li = 0; li < num_on_planes; li++) {
2400 NodePath plane = new_plane->get_on_plane(li);
2403 DCAST_INTO_V(plane_node, plane.
node());
2404 if ((plane_node->get_clip_effect() & PlaneNode::CE_visible) != 0) {
2406 if (!_clip_planes_enabled) {
2407 enable_clip_planes(
true);
2408 _clip_planes_enabled =
true;
2411 enable_clip_plane(num_enabled,
true);
2412 if (num_enabled == 0) {
2413 begin_bind_clip_planes();
2416 bind_clip_plane(plane, num_enabled);
2423 for (i = num_enabled; i < _num_clip_planes_enabled; ++i) {
2424 enable_clip_plane(i,
false);
2426 _num_clip_planes_enabled = num_enabled;
2429 if (num_enabled == 0) {
2430 if (_clip_planes_enabled) {
2431 enable_clip_planes(
false);
2432 _clip_planes_enabled =
false;
2435 end_bind_clip_planes();
2455 _target_rs->get_attrib_def(ColorAttrib::get_class_slot());
2458 case ColorAttrib::T_flat:
2461 _scene_graph_color = target_color->
get_color();
2462 _has_scene_graph_color =
true;
2463 _vertex_colors_enabled =
false;
2466 case ColorAttrib::T_off:
2469 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2470 _has_scene_graph_color =
false;
2471 _vertex_colors_enabled =
false;
2474 case ColorAttrib::T_vertex:
2477 _scene_graph_color.set(1.0f, 1.0f, 1.0f, 1.0f);
2478 _has_scene_graph_color =
false;
2479 _vertex_colors_enabled =
true;
2483 if (_color_scale_via_lighting) {
2484 _state_mask.
clear_bit(LightAttrib::get_class_slot());
2485 _state_mask.
clear_bit(MaterialAttrib::get_class_slot());
2487 determine_light_color_scale();
2496 void GraphicsStateGuardian::
2497 do_issue_color_scale() {
2500 if (_has_texture_alpha_scale) {
2501 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2505 _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot());
2507 _color_scale_enabled = target_color_scale->
has_scale();
2508 _current_color_scale = target_color_scale->
get_scale();
2509 _has_texture_alpha_scale =
false;
2511 if (_color_blend_involves_color_scale) {
2512 _state_mask.
clear_bit(TransparencyAttrib::get_class_slot());
2514 if (_texture_involves_color_scale) {
2515 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2517 if (_color_scale_via_lighting) {
2518 _state_mask.
clear_bit(LightAttrib::get_class_slot());
2519 _state_mask.
clear_bit(MaterialAttrib::get_class_slot());
2521 determine_light_color_scale();
2524 if (_alpha_scale_via_texture && !_has_scene_graph_color &&
2528 _state_mask.
clear_bit(TextureAttrib::get_class_slot());
2529 _state_mask.
clear_bit(TexMatrixAttrib::get_class_slot());
2531 _has_texture_alpha_scale =
true;
2559 LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
2562 int num_enabled = 0;
2563 int num_on_lights = 0;
2566 _target_rs->get_attrib_def(LightAttrib::get_class_slot());
2568 if (display_cat.is_spam()) {
2570 <<
"do_issue_light: " << target_light <<
"\n";
2573 CPT(
LightAttrib) new_light = target_light->filter_to_max(_max_lights);
2574 if (display_cat.is_spam()) {
2575 new_light->write(display_cat.spam(
false), 2);
2578 num_on_lights = new_light->get_num_on_lights();
2579 for (
int li = 0; li < num_on_lights; li++) {
2580 NodePath light = new_light->get_on_light(li);
2583 nassertv(light_obj != (
Light *)NULL);
2586 if (!_lighting_enabled) {
2587 enable_lighting(
true);
2588 _lighting_enabled =
true;
2591 if (light_obj->get_type() == AmbientLight::get_class_type()) {
2594 cur_ambient_light += light_obj->get_color();
2599 if (color[0] != 0.0 || color[1] != 0.0 || color[2] != 0.0) {
2600 enable_light(num_enabled,
true);
2601 if (num_enabled == 0) {
2602 begin_bind_lights();
2605 light_obj->bind(
this, light, num_enabled);
2612 for (i = num_enabled; i < _num_lights_enabled; ++i) {
2613 enable_light(i,
false);
2615 _num_lights_enabled = num_enabled;
2618 if (num_on_lights == 0) {
2619 if (_color_scale_via_lighting && (_has_material_force_color || _light_color_scale !=
LVecBase4(1.0f, 1.0f, 1.0f, 1.0f))) {
2622 if (!_lighting_enabled) {
2623 enable_lighting(
true);
2624 _lighting_enabled =
true;
2626 set_ambient_light(
LColor(1.0f, 1.0f, 1.0f, 1.0f));
2629 if (_lighting_enabled) {
2630 enable_lighting(
false);
2631 _lighting_enabled =
false;
2636 set_ambient_light(cur_ambient_light);
2639 if (num_enabled != 0) {
2719 void GraphicsStateGuardian::
2720 init_frame_pstats() {
2722 _data_transferred_pcollector.clear_level();
2723 _vertex_buffer_switch_pcollector.clear_level();
2724 _index_buffer_switch_pcollector.clear_level();
2726 _primitive_batches_pcollector.clear_level();
2727 _primitive_batches_tristrip_pcollector.clear_level();
2728 _primitive_batches_trifan_pcollector.clear_level();
2729 _primitive_batches_tri_pcollector.clear_level();
2730 _primitive_batches_patch_pcollector.clear_level();
2731 _primitive_batches_other_pcollector.clear_level();
2732 _vertices_tristrip_pcollector.clear_level();
2733 _vertices_trifan_pcollector.clear_level();
2734 _vertices_tri_pcollector.clear_level();
2735 _vertices_patch_pcollector.clear_level();
2736 _vertices_other_pcollector.clear_level();
2738 _state_pcollector.clear_level();
2739 _transform_state_pcollector.clear_level();
2740 _texture_state_pcollector.clear_level();
2752 create_gamma_table (PN_stdfloat gamma,
unsigned short *red_table,
unsigned short *green_table,
unsigned short *blue_table) {
2760 for (i = 0; i < 256; i++) {
2763 PN_stdfloat gamma_correction;
2765 x = ((double) i / 255.0);
2766 gamma_correction = 1.0 / gamma;
2767 x = pow (x, (
double) gamma_correction);
2773 red_table [i] = (int)g;
2774 green_table [i] = (int)g;
2775 blue_table [i] = (int)g;
2787 void GraphicsStateGuardian::
2788 reissue_transforms() {
2799 void GraphicsStateGuardian::
2800 enable_lighting(
bool enable) {
2811 void GraphicsStateGuardian::
2822 void GraphicsStateGuardian::
2823 enable_light(
int light_id,
bool enable) {
2838 void GraphicsStateGuardian::
2839 begin_bind_lights() {
2851 void GraphicsStateGuardian::
2863 void GraphicsStateGuardian::
2864 enable_clip_planes(
bool enable) {
2875 void GraphicsStateGuardian::
2876 enable_clip_plane(
int plane_id,
bool enable) {
2891 void GraphicsStateGuardian::
2892 begin_bind_clip_planes() {
2903 void GraphicsStateGuardian::
2904 bind_clip_plane(
const NodePath &plane,
int plane_id) {
2916 void GraphicsStateGuardian::
2917 end_bind_clip_planes() {
2926 void GraphicsStateGuardian::
2927 determine_target_texture() {
2929 _target_rs->get_attrib_def(TextureAttrib::get_class_slot());
2931 _target_rs->get_attrib_def(TexGenAttrib::get_class_slot());
2935 _target_texture = target_texture;
2936 _target_tex_gen = target_tex_gen;
2938 if (_has_texture_alpha_scale) {
2942 _target_texture = DCAST(
TextureAttrib, _target_texture->add_on_stage(stage, texture));
2943 _target_tex_gen = DCAST(
TexGenAttrib, _target_tex_gen->add_stage
2944 (stage, TexGenAttrib::M_constant,
LTexCoord3(_current_color_scale[3], 0.0f, 0.0f)));
2948 _target_texture = _target_texture->filter_to_max(max_texture_stages);
2949 nassertv(_target_texture->get_num_on_stages() <= max_texture_stages);
2970 void GraphicsStateGuardian::
2977 _closing_gsg =
true;
2979 if (display_cat.is_debug()) {
2981 <<
this <<
" close_gsg " << get_type() <<
"\n";
2998 _prepared_objects->begin_frame(
this, current_thread);
2999 _prepared_objects->end_frame(current_thread);
3005 _pending_timer_queries.clear();
3020 void GraphicsStateGuardian::
3021 panic_deactivate() {
3024 <<
"Deactivating " << get_type() <<
".\n";
3026 throw_event(
"panic-deactivate-gsg",
this);
3038 void GraphicsStateGuardian::
3039 determine_light_color_scale() {
3040 if (_has_scene_graph_color) {
3044 _has_material_force_color =
true;
3045 _material_force_color = _scene_graph_color;
3046 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3047 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3048 _material_force_color.set(_scene_graph_color[0] * _current_color_scale[0],
3049 _scene_graph_color[1] * _current_color_scale[1],
3050 _scene_graph_color[2] * _current_color_scale[2],
3051 _scene_graph_color[3] * _current_color_scale[3]);
3057 _has_material_force_color =
false;
3058 _light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
3059 if (!_color_blend_involves_color_scale && _color_scale_enabled) {
3060 _light_color_scale = _current_color_scale;
3074 state = RenderState::make(LightAttrib::make_all_off());
3085 get_unclipped_state() {
3088 state = RenderState::make(ClipPlaneAttrib::make_all_off());
3099 get_untextured_state() {
3102 state = RenderState::make(TextureAttrib::make_off());
3118 void GraphicsStateGuardian::
3120 nassertv(_loader != (
Loader *)NULL);
3124 priority = _current_display_region->get_texture_reload_priority();
3127 string task_name = string(
"reload:") + tc->
get_texture()->get_name();
3132 int num_tasks = orig_tasks.get_num_tasks();
3133 for (
int ti = 0; ti < num_tasks; ++ti) {
3134 AsyncTask *task = orig_tasks.get_task(ti);
3135 if (task->
is_exact_type(TextureReloadRequest::get_class_type()) &&
3148 _prepared_objects, tc->get_texture(),
3149 _supports_compressed_texture);
3150 request->set_priority(priority);
3151 _loader->load_async(request);
3166 nassertr(light_np.node()->is_of_type(DirectionalLight::get_class_type()) ||
3167 light_np.node()->is_of_type(PointLight::get_class_type()) ||
3168 light_np.node()->is_of_type(Spotlight::get_class_type()), NULL);
3171 if (light == NULL || !light->_shadow_caster) {
3175 bool is_point = light->is_of_type(PointLight::get_class_type());
3177 nassertr(light->_sbuffers.count(
this) == 0, NULL);
3179 display_cat.debug() <<
"Constructing shadow buffer for light '" << light->get_name()
3180 <<
"', size=" << light->_sb_xsize <<
"x" << light->_sb_ysize
3181 <<
", sort=" << light->_sb_sort <<
"\n";
3185 fbp.set_depth_bits(1);
3187 int flags = GraphicsPipe::BF_refuse_window;
3189 flags |= GraphicsPipe::BF_size_square;
3194 light->_sb_sort, fbp, props, flags, this, DCAST(
GraphicsOutput, host));
3195 nassertr(sbuffer != NULL, NULL);
3200 if (light->_sb_xsize != light->_sb_ysize) {
3202 <<
"PointLight shadow buffers must have an equal width and height!\n";
3204 tex->setup_cube_map(light->_sb_xsize, Texture::T_unsigned_byte, Texture::F_depth_component);
3206 tex->setup_2d_texture(light->_sb_xsize, light->_sb_ysize, Texture::T_unsigned_byte, Texture::F_depth_component);
3208 tex->make_ram_image();
3209 sbuffer->add_render_texture(tex, GraphicsOutput::RTM_bind_or_copy, GraphicsOutput::RTP_depth);
3213 tex->set_wrap_u(SamplerState::WM_clamp);
3214 tex->set_wrap_v(SamplerState::WM_clamp);
3216 tex->set_wrap_u(SamplerState::WM_border_color);
3217 tex->set_wrap_v(SamplerState::WM_border_color);
3218 tex->set_border_color(
LVecBase4(1, 1, 1, 1));
3223 tex->set_minfilter(SamplerState::FT_shadow);
3224 tex->set_magfilter(SamplerState::FT_shadow);
3227 tex->set_minfilter(SamplerState::FT_linear);
3228 tex->set_magfilter(SamplerState::FT_linear);
3233 for (
int i = 0; i < 6; ++i) {
3234 PT(
DisplayRegion) dr = sbuffer->make_mono_display_region(0, 1, 0, 1);
3235 dr->set_lens_index(i);
3236 dr->set_target_tex_page(i);
3237 dr->set_camera(light_np);
3238 dr->set_clear_depth_active(true);
3241 PT(
DisplayRegion) dr = sbuffer->make_mono_display_region(0, 1, 0, 1);
3242 dr->set_camera(light_np);
3243 dr->set_clear_depth_active(true);
3245 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.
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 ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
A light shining from infinitely far away in a particular direction, like sunlight.
virtual int get_driver_version_major()
Returns major version of the video driver.
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.
const float * get_data() const
Returns the address of the first of the four data elements in the vector.
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...
virtual void release_shader(ShaderContext *sc)
Releases the resources allocated by prepare_shader.
PN_stdfloat get_exp_density() const
Returns the density of the fog for exponential calculations.
virtual TextureContext * prepare_texture(Texture *tex)
Creates whatever structures the GSG requires to represent the texture internally, and returns a newly...
const LColor & get_ambient() const
Returns the ambient color setting, if it has been set.
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.
int get_pad_z_size() const
Returns size of the pad region.
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.
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.
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.
bool get_supports_shadow_filter() const
Returns true if this particular GSG supports the filter mode FT_shadow for depth textures.
virtual bool draw_patches(const GeomPrimitivePipelineReader *reader, bool force)
Draws a series of "patches", which can only be processed by a tessellation shader.
virtual CoordinateSystem get_internal_coordinate_system() const
Returns the coordinate system used internally by the GSG.
virtual bool update_texture(TextureContext *tc, bool force)
Ensures that the current Texture data is refreshed onto the GSG.
bool is_off() const
Returns true if the MaterialAttrib is an 'off' MaterialAttrib, indicating that it should disable the ...
int get_priority() const
Returns the task's current priority value.
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...
static int get_max_priority()
Returns the maximum priority number (sometimes called override) that may be set on any node...
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 PN_stdfloat get_exponent() const
For spotlights, returns the exponent that controls the amount of light falloff from the center of the...
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.
A node that contains a Lens.
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
virtual bool get_supports_cg_profile(const string &name) const
Returns true if this particular GSG supports the specified Cg Shader Profile.
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.
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...
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-...
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
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...
bool is_identity() const
Returns true if the ColorScaleAttrib is an identity attrib, false if it is either an off attrib or it...
Material * get_material() const
If the MaterialAttrib is not an 'off' MaterialAttrib, returns the material that is associated...
GraphicsPipe * get_pipe() const
Returns the graphics pipe on which this GSG was created.
bool has_scale() const
Returns true if the ColorScaleAttrib has a non-identity scale, false otherwise (in which case it migh...
PandaNode * node() const
Returns the referenced node of the path.
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 remove_window(GraphicsOutputBase *window)
This is simply a transparent call to GraphicsEngine::remove_window().
bool is_exact_type(TypeHandle handle) const
Returns true if the current object is the indicated type exactly.
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 ...
Type get_color_type() const
Returns the type of color specified by this ColorAttrib.
Texture * get_texture() const
Returns the pointer to the associated Texture object.
PN_stdfloat get_shininess() const
Returns the shininess exponent of the material.
virtual SceneSetup * get_scene() const
Returns the current SceneSetup object.
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...
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...
int get_buffer_mask() const
Converts the non-aux bitplanes of the framebuffer into a RenderBuffer::Type.
virtual GeomContext * prepare_geom(Geom *geom)
Prepares the indicated Geom for retained-mode rendering, by creating whatever structures are necessar...
static const LMatrix4f & convert_mat(CoordinateSystem from, CoordinateSystem to)
Returns a matrix that transforms from the indicated coordinate system to the indicated coordinate sys...
virtual int get_supported_geom_rendering() const
Returns the union of Geom::GeomRendering values that this particular GSG can support directly...
const LColor & get_emission() const
Returns the emission color setting, if it has been set.
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
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...
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.
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.
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...
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...
const LColor & get_color() const
Returns the color of the fog.
void clear_flash_texture()
Resets the "flash texture", so that no textures will flash.
virtual void clear_state_and_transform()
Forgets the current graphics state and current transform, so that the next call to set_state_and_tran...
int get_z_size() const
Returns the depth of the texture image in texels.
const LColor & get_color() const
If the type is T_flat or T_off, this returns the color that will be applied to geometry.
This is a 4-by-4 transform matrix.
virtual string get_driver_vendor()
Returns the vendor of the video card driver.
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 ...
const LVector3 & get_direction() const
Returns the direction in which the light is aimed.
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.
const LVecBase4 & get_scale() const
Returns the scale to be applied to colors.
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.
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.
NodePath get_on_plane(int n) const
Returns the nth plane enabled by the attribute, sorted in render order.
A light originating from a single point in space, and shining in a particular direction, with a cone-shaped falloff.
const LColor & get_specular() const
Returns the specular 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...
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.
Similar to MutexHolder, but for a reentrant mutex.
virtual ShaderContext * prepare_shader(Shader *shader)
Compile a vertex/fragment shader body.
const TransformState * get_world_transform() const
Returns the position of the starting node relative to the camera.
int get_num_on_planes() const
Returns the number of planes that are enabled by the attribute.
int get_num_on_lights() const
Returns the number of lights that are turned on by the attribute.
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.
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...
const LMatrix4 & get_mat() const
Returns the transformation matrix associated with the default texture stage.
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 ...
bool has_alpha_scale() const
Returns true if the ColorScaleAttrib has a non-identity scale in the alpha component (ignoring RGB)...
static const LMatrix4f & zeros_mat()
Returns an matrix filled with zeros.
Applies a transform matrix to UV's before they are rendered.
This class represents a concrete task performed by an AsyncManager.
virtual bool get_supports_multisample() const
Returns true if this particular GSG supports using the multisample bits to provide antialiasing...
bool get_swap_eyes() const
Returns the current setting of the "swap eyes" flag.
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.
const TransformState * get_camera_transform() const
Returns the position of the camera relative to the starting node.
A thread; that is, a lightweight process.
int get_pad_y_size() const
Returns size of the pad region.
A derivative of Light and of Camera.
virtual bool has_extension(const string &extension) const
Returns true if the GSG implements the extension identified by the given string.
This is a special class object that holds all the information returned by a particular GSG to indicat...
Encapsulates all the communication with a particular instance of a given rendering backend...
int get_pad_x_size() const
Returns size of the pad region.
GraphicsOutput * get_window() const
Returns the GraphicsOutput that this DisplayRegion is ultimately associated with, or NULL if no windo...
bool is_empty() const
Returns true if the NodePath contains no nodes.
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.
const LColor & get_color() const
Returns the basic color of the light.
static bool is_connected()
Returns true if the client believes it is connected to a working PStatServer, false otherwise...
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.
virtual const LColor & get_specular_color() const
Returns the color of specular highlights generated by the light.
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.
GraphicsEngine * get_engine() const
Returns the graphics engine that created this GSG.
LVecBase3f get_row3(int row) const
Retrieves the row column of the matrix as a 3-component vector, ignoring the last column...
An abstract base class for GraphicsOutput, for all the usual reasons.
Returned from a GSG in response to begin_occlusion_query() .
This class is the main interface to controlling the render process.
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.
This is the preferred interface for loading textures from image files.
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.
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:
NodePath get_on_light(int n) const
Returns the nth light turned on by the attribute, sorted in render order.
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.
Fog * get_fog() const
If the FogAttrib is not an 'off' FogAttrib, returns the fog that is associated.
Defines the properties of a named stage of the multitexture pipeline.
const LMatrix4 & get_mat() const
Returns the transform matrix that has been applied to the referenced node, or the identity matrix if ...
Computes texture coordinates for geometry automatically based on vertex position and/or normal...
const LColor & get_diffuse() const
Returns the diffuse color setting, if it has been set.
virtual void finish_decal()
Called during draw to clean up after decals are finished.
void set_flash_texture(Texture *tex)
Sets the "flash texture".
Lens::StereoChannel get_stereo_channel() const
Returns whether the DisplayRegion is specified as the left or right channel of a stereo pair...
int get_y_size() const
Returns the height of the texture image in texels.
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...
int get_max_texture_stages() const
Returns the maximum number of simultaneous textures that may be applied to geometry with multitexturi...
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.
A light originating from a single point in space, and shining in all directions.
const Lens * get_lens() const
Returns the particular Lens used for rendering.
int get_x_size() const
Returns the width of the texture image in texels.
A node that contains a plane.
LVecBase3f xform_point(const LVecBase3f &v) const
The matrix transforms a 3-component point (including translation component) and returns the result...
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...
This is the data for one array of a GeomVertexData structure.
virtual const LVecBase3 & get_attenuation() const
Returns the terms of the attenuation equation for the light.
Indicates which set of lights should be considered "on" to illuminate geometry at this level and belo...
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...
virtual bool begin_scene()
Called between begin_frame() and end_frame() to mark the beginning of drawing commands for a "scene" ...
Texture * get_flash_texture() const
Returns the current "flash texture", if any, or NULL if none.
LVecBase3f xform_vec(const LVecBase3f &v) const
The matrix transforms a 3-component vector (without translation component) and returns the result...
virtual string get_driver_renderer()
Returns GL_Renderer.
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.
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...