From ba388e28666e28b752d326ba0e680421db3c9bb1 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 17 Sep 2023 15:56:36 +0200 Subject: [PATCH] shader: More efficient state-based shader input fetching Previously every input was fetched as a matrix. Now, every input is fetched as a vector, with matrices taking up multiple vectors. This saves a lot of copying and a lot of space in the cache. Furthermore, integer state-based inputs can be defined (for future use) Naming still needs to be revised, since it's called the "mat part cache" etc. --- panda/src/display/graphicsStateGuardian.cxx | 586 +++++++++++--------- panda/src/display/graphicsStateGuardian.h | 8 +- panda/src/dxgsg9/dxShaderContext9.cxx | 102 +--- panda/src/dxgsg9/dxShaderContext9.h | 2 +- panda/src/glstuff/glCgShaderContext_src.cxx | 52 +- panda/src/glstuff/glCgShaderContext_src.h | 2 +- panda/src/glstuff/glShaderContext_src.cxx | 235 ++++---- panda/src/glstuff/glShaderContext_src.h | 2 +- panda/src/glstuff/glmisc_src.h | 8 - panda/src/gobj/shader.cxx | 213 +++++-- panda/src/gobj/shader.h | 48 +- 11 files changed, 649 insertions(+), 609 deletions(-) diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 00672f6dbc..e29d48646d 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -887,12 +887,12 @@ compute_distance_to(const LPoint3 &point) const { * have changed based on the aspects of the render state that were altered. */ void GraphicsStateGuardian:: -update_shader_matrix_cache(Shader *shader, LMatrix4 *cache, int altered) { +update_shader_matrix_cache(Shader *shader, LVecBase4f *cache, int altered) { for (Shader::ShaderMatPart &part : shader->_mat_parts) { if (altered & part._dep) { fetch_specified_part(part._part, part._arg, cache, part._count); } - cache += part._count; + cache += part._count * part._size; } } @@ -921,51 +921,54 @@ update_shader_matrix_cache(Shader *shader, LMatrix4 *cache, int altered) { * This may allow data to be cached and not reevaluated. * */ -const LMatrix4 *GraphicsStateGuardian:: -fetch_specified_value(Shader::ShaderMatSpec &spec, const LMatrix4 *cache, int altered) { - LVecBase3 v; - - const LMatrix4 *cache0 = cache + spec._cache_offset[0]; - const LMatrix4 *cache1 = cache + spec._cache_offset[1]; +const LVecBase4f *GraphicsStateGuardian:: +fetch_specified_value(Shader::ShaderMatSpec &spec, const LVecBase4f *cache, int altered) { + LVecBase3f v; + const LVecBase4f *cache0 = cache + spec._cache_offset[0]; + const LVecBase4f *cache1 = cache + spec._cache_offset[1]; switch (spec._func) { + case Shader::SMF_first: + return cache0; + case Shader::SMF_compose: - spec._value.multiply((*cache0), (*cache1)); - return &spec._value; + spec._value.multiply(*(LMatrix4f *)cache0, *(LMatrix4f *)cache1); + return (LVecBase4f *)&spec._value; + case Shader::SMF_transform_dlight: - spec._value = (*cache0); - v = (*cache1).xform_vec((*cache0).get_row3(2)); + spec._value = *(LMatrix4f *)cache0; + v = (*(LMatrix4f *)cache1).xform_vec(cache0[2].get_xyz()); v.normalize(); spec._value.set_row(2, v); - v = (*cache1).xform_vec((*cache0).get_row3(3)); + v = (*(LMatrix4f *)cache1).xform_vec(cache0[3].get_xyz()); v.normalize(); spec._value.set_row(3, v); - return &spec._value; + return (LVecBase4f *)&spec._value; + case Shader::SMF_transform_plight: { // Careful not to touch the w component, which contains the near value. - spec._value = *cache0; - LPoint3 point = (*cache1).xform_point((*cache0).get_row3(2)); + spec._value = *(LMatrix4f *)cache0; + LPoint3f point = (*(LMatrix4f *)cache1).xform_point(cache0[2].get_xyz()); spec._value(2, 0) = point[0]; spec._value(2, 1) = point[1]; spec._value(2, 2) = point[2]; - return &spec._value; + return (LVecBase4f *)&spec._value; } + case Shader::SMF_transform_slight: - spec._value = *cache0; - spec._value.set_row(2, (*cache1).xform_point((*cache0).get_row3(2))); - v = (*cache1).xform_vec((*cache0).get_row3(3)); + spec._value = *(LMatrix4f *)cache0; + spec._value.set_row(2, (*(LMatrix4f *)cache1).xform_point(cache0[2].get_xyz())); + v = (*(LMatrix4f *)cache1).xform_vec(cache0[3].get_xyz()); v.normalize(); spec._value.set_row(3, v); - return &spec._value; - case Shader::SMF_first: - return cache0; - default: - // should never get here - spec._value = LMatrix4::ident_mat(); - return &spec._value; + return (LVecBase4f *)&spec._value; } + + // Should never get here + spec._value = LMatrix4f::ident_mat(); + return (LVecBase4f *)&spec._value; } /** @@ -973,30 +976,35 @@ fetch_specified_value(Shader::ShaderMatSpec &spec, const LMatrix4 *cache, int al */ void GraphicsStateGuardian:: fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, - LMatrix4 *into, int count) { + LVecBase4f *into, int count) { nassertv(count > 0); switch (part) { case Shader::SMO_identity: { for (int i = 0; i < count; ++i) { - into[i] = LMatrix4::ident_mat(); + ((LMatrix4f *)into)[i] = LMatrix4f::ident_mat(); } return; } case Shader::SMO_window_size: case Shader::SMO_pixel_size: { LVecBase2i pixel_size = _current_display_region->get_pixel_size(); - into[0] = LMatrix4::translate_mat(pixel_size[0], pixel_size[1], 0); + into[0].set(pixel_size[0], pixel_size[1], 0, 1); + return; + } + case Shader::SMO_frame_number: { + int count = ClockObject::get_global_clock()->get_frame_count(); + ((LVecBase4i *)into)[0].fill(count); return; } case Shader::SMO_frame_time: { PN_stdfloat time = ClockObject::get_global_clock()->get_frame_time(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time); + into[0].fill(time); return; } case Shader::SMO_frame_delta: { PN_stdfloat dt = ClockObject::get_global_clock()->get_dt(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt); + into[0].fill(dt); return; } case Shader::SMO_texpad_x: { @@ -1008,7 +1016,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, double cx = (sx * 0.5) / tex->get_x_size(); double cy = (sy * 0.5) / tex->get_y_size(); double cz = (sz * 0.5) / tex->get_z_size(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cx, cy, cz, 0); + into[0].set(cx, cy, cz, 0); return; } case Shader::SMO_texpix_x: { @@ -1017,7 +1025,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, double px = 1.0 / tex->get_x_size(); double py = 1.0 / tex->get_y_size(); double pz = 1.0 / tex->get_z_size(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, px, py, pz, 0); + into[0].set(px, py, pz, 0); return; } case Shader::SMO_attr_material: { @@ -1025,53 +1033,52 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, _target_rs->get_attrib_def(MaterialAttrib::get_class_slot()); // Material matrix contains AMBIENT, DIFFUSE, EMISSION, SPECULAR+SHININESS if (target_material->is_off()) { - into[0].set(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0); + into[0].set(1, 1, 1, 1); + into[1].set(1, 1, 1, 1); + into[2].set(0, 0, 0, 0); + into[3].set(0, 0, 0, 0); return; } Material *m = target_material->get_material(); - LVecBase4 const &amb = m->get_ambient(); - LVecBase4 const &dif = m->get_diffuse(); - LVecBase4 const &emm = m->get_emission(); LVecBase4 spc = m->get_specular(); spc[3] = m->get_shininess(); - into[0].set(amb[0], amb[1], amb[2], amb[3], - dif[0], dif[1], dif[2], dif[3], - emm[0], emm[1], emm[2], emm[3], - spc[0], spc[1], spc[2], spc[3]); + into[0] = LCAST(float, m->get_ambient()); + into[1] = LCAST(float, m->get_diffuse()); + into[2] = LCAST(float, m->get_emission()); + into[3] = LCAST(float, spc); return; } case Shader::SMO_attr_material2: { const MaterialAttrib *target_material = (const MaterialAttrib *) _target_rs->get_attrib_def(MaterialAttrib::get_class_slot()); if (target_material->is_off()) { - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1); + into[0].set(0, 0, 0, 0); + into[1].set(0, 0, 0, 1); return; } Material *m = target_material->get_material(); - into[0].set_row(0, m->get_base_color()); - into[0].set_row(3, LVecBase4(m->get_metallic(), m->get_refractive_index(), 0, m->get_roughness())); + into[0] = LCAST(float, m->get_base_color()); + into[1].set(m->get_metallic(), m->get_refractive_index(), 0, m->get_roughness()); return; } case Shader::SMO_attr_color: { const ColorAttrib *target_color = (const ColorAttrib *) _target_rs->get_attrib_def(ColorAttrib::get_class_slot()); if (target_color->get_color_type() != ColorAttrib::T_flat) { - into[0] = LMatrix4::ones_mat(); + into[0].set(1, 1, 1, 1); return; } - LVecBase4 c = target_color->get_color(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]); + into[0] = LCAST(float, target_color->get_color()); return; } case Shader::SMO_attr_colorscale: { const ColorScaleAttrib *target_color = (const ColorScaleAttrib *) _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot()); if (target_color->is_identity()) { - into[0] = LMatrix4::ones_mat(); + into[0].set(1, 1, 1, 1); return; } - LVecBase4 cs = target_color->get_scale(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cs[0], cs[1], cs[2], cs[3]); + into[0] = LCAST(float, target_color->get_scale()); return; } case Shader::SMO_attr_fog: { @@ -1079,13 +1086,12 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, _target_rs->get_attrib_def(FogAttrib::get_class_slot()); Fog *fog = target_fog->get_fog(); if (fog == nullptr) { - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1); + into[0].set(0, 1, 1, 1); return; } PN_stdfloat start, end; fog->get_linear_range(start, end); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - fog->get_exp_density(), start, end, 1.0f / (end - start)); + into[0].set(fog->get_exp_density(), start, end, 1.0f / (end - start)); return; } case Shader::SMO_attr_fogcolor: { @@ -1093,11 +1099,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, _target_rs->get_attrib_def(FogAttrib::get_class_slot()); Fog *fog = target_fog->get_fog(); if (fog == nullptr) { - into[0] = LMatrix4::ones_mat(); + into[0].set(1, 1, 1, 1); return; } - LVecBase4 c = fog->get_color(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]); + into[0] = LCAST(float, fog->get_color()); return; } case Shader::SMO_alight_x: { @@ -1105,8 +1110,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, nassertv(!np.is_empty()); AmbientLight *lt; DCAST_INTO_V(lt, np.node()); - LColor const &c = lt->get_color(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]); + into[0] = LCAST(float, lt->get_color()); return; } case Shader::SMO_satten_x: { @@ -1116,7 +1120,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, DCAST_INTO_V(lt, np.node()); LVecBase3 const &a = lt->get_attenuation(); PN_stdfloat x = lt->get_exponent(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a[0], a[1], a[2], x); + into[0].set(a[0], a[1], a[2], x); return; } case Shader::SMO_dlight_x: { @@ -1127,16 +1131,16 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, DCAST_INTO_V(lt, np.node()); LColor const &c = lt->get_color(); LColor const &s = lt->get_specular_color(); - *into = np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); - LVecBase3 d = -(into[0].xform_vec(lt->get_direction())); + LMatrix4 t = np.get_net_transform()->get_mat() * + _scene_setup->get_world_transform()->get_mat(); + LVecBase3 d = -(t.xform_vec(lt->get_direction())); d.normalize(); LVecBase3 h = d + LVecBase3(0,-1,0); h.normalize(); - into[0].set(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); + into[0].set(c[0], c[1], c[2], c[3]); + into[1].set(s[0], s[1], s[2], c[3]); + into[2].set(d[0], d[1], d[2], 0); + into[3].set(h[0], h[1], h[2], 0); return; } case Shader::SMO_plight_x: { @@ -1147,17 +1151,17 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, DCAST_INTO_V(lt, np.node()); LColor const &c = lt->get_color(); LColor const &s = lt->get_specular_color(); - into[0] = np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); - LVecBase3 p = (into[0].xform_point(lt->get_point())); + LMatrix4 t = np.get_net_transform()->get_mat() * + _scene_setup->get_world_transform()->get_mat(); + LVecBase3 p = (t.xform_point(lt->get_point())); LVecBase3 a = lt->get_attenuation(); Lens *lens = lt->get_lens(0); PN_stdfloat lnear = lens->get_near(); PN_stdfloat lfar = lens->get_far(); - into[0].set(c[0], c[1], c[2], c[3], - s[0], s[1], s[2], s[3], - p[0], p[1], p[2], lnear, - a[0], a[1], a[2], lfar); + into[0].set(c[0], c[1], c[2], c[3]); + into[1].set(s[0], s[1], s[2], s[3]); + into[2].set(p[0], p[1], p[2], lnear); + into[3].set(a[0], a[1], a[2], lfar); return; } case Shader::SMO_slight_x: { @@ -1171,14 +1175,14 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LColor const &c = lt->get_color(); LColor const &s = lt->get_specular_color(); PN_stdfloat cutoff = ccos(deg_2_rad(lens->get_hfov() * 0.5f)); - into[0] = np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); - LVecBase3 p = into[0].xform_point(lens->get_nodal_point()); - LVecBase3 d = -(into[0].xform_vec(lens->get_view_vector())); - into[0].set(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); + LMatrix4 t = np.get_net_transform()->get_mat() * + _scene_setup->get_world_transform()->get_mat(); + LVecBase3 p = t.xform_point(lens->get_nodal_point()); + LVecBase3 d = -(t.xform_vec(lens->get_view_vector())); + into[0].set(c[0], c[1], c[2], c[3]); + into[1].set(s[0], s[1], s[2], s[3]); + into[2].set(p[0], p[1], p[2], 0); + into[3].set(d[0], d[1], d[2], cutoff); return; } case Shader::SMO_light_ambient: { @@ -1189,9 +1193,9 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, if (!target_light->has_any_on_light()) { // There are no lights at all. This means, to follow the fixed- // function model, we pretend there is an all-white ambient light. - into[0].set_row(3, LVecBase4(1, 1, 1, 1)); + into[0].set(1, 1, 1, 1); } else { - into[0].set_row(3, target_light->get_ambient_contribution()); + into[0] = LCAST(float, target_light->get_ambient_contribution()); } return; } @@ -1206,10 +1210,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, int i = 0; for (; i < num_stages; ++i) { - into[i] = tma->get_mat(ta->get_on_stage(i)); + ((LMatrix4f *)into)[i] = LCAST(float, tma->get_mat(ta->get_on_stage(i))); } for (; i < count; ++i) { - into[i] = LMatrix4::ident_mat(); + ((LMatrix4f *)into)[i] = LMatrix4f::ident_mat(); } return; } @@ -1224,10 +1228,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, int i = 0; for (; i < num_stages; ++i) { - into[i] = tma->get_transform(ta->get_on_stage(i))->get_inverse()->get_mat(); + ((LMatrix4f *)into)[i] = LCAST(float, tma->get_transform(ta->get_on_stage(i))->get_inverse()->get_mat()); } for (; i < count; ++i) { - into[i] = LMatrix4::ident_mat(); + ((LMatrix4f *)into)[i] = LMatrix4f::ident_mat(); } return; } @@ -1243,10 +1247,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, int i = 0; for (; i < num_stages; ++i) { LVecBase3 scale = tma->get_transform(ta->get_on_stage(i))->get_scale(); - into[i].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, scale[0], scale[1], scale[2], 0); + into[i].set(scale[0], scale[1], scale[2], 0); } for (; i < count; ++i) { - into[i] = LMatrix4::ident_mat(); + into[i].set(0, 0, 0, 1); } return; } @@ -1261,10 +1265,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, int i = 0; for (; i < num_stages; ++i) { TextureStage *ts = ta->get_on_stage(i); - into[i].set_row(3, ts->get_color()); + into[i] = LCAST(float, ts->get_color()); } for (; i < count; ++i) { - into[i] = LMatrix4::ident_mat(); + into[i].set(0, 0, 0, 1); } return; } @@ -1280,10 +1284,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, int i = 0; for (; i < num_stages; ++i) { LVecBase3 value = tga->get_constant_value(ta->get_on_stage(i)); - into[i].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, value[0], value[1], value[2], 1); + into[i].set(value[0], value[1], value[2], 1); } for (; i < count; ++i) { - into[i] = LMatrix4::ident_mat(); + into[i].set(0, 0, 0, 1); } return; } @@ -1301,10 +1305,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, for (; i < num_stages; ++i) { TextureStage *ts = ta->get_on_stage(i); PN_stdfloat v = (ta->get_on_texture(ts)->get_format() == Texture::F_alpha); - into[i].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v, v, v, 0); + into[i].set(v, v, v, 0); } for (; i < count; ++i) { - into[i] = LMatrix4::zeros_mat(); + into[i].set(0, 0, 0, 0); } return; } @@ -1313,8 +1317,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, nassertv(!np.is_empty()); const PlaneNode *plane_node; DCAST_INTO_V(plane_node, np.node()); - LPlane p = plane_node->get_plane(); - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, p[0], p[1], p[2], p[3]); + into[0] = LCAST(float, plane_node->get_plane()); return; } case Shader::SMO_clipplane_x: { @@ -1322,7 +1325,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, _target_rs->get_attrib_def(cpa); int planenr = atoi(name->get_name().c_str()); if (planenr >= cpa->get_num_on_planes()) { - into[0] = LMatrix4::zeros_mat(); + into[0].set(0, 0, 0, 0); return; } const NodePath &np = cpa->get_on_plane(planenr); @@ -1336,7 +1339,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, if (!transform->is_identity()) { plane.xform(transform->get_mat()); } - into[0].set_row(3, plane); + into[0] = LCAST(float, plane); return; } case Shader::SMO_apiview_clipplane_i: { @@ -1356,122 +1359,125 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, plane.get_transform(_scene_setup->get_scene_root().get_parent())); LPlane xformed_plane = plane_node->get_plane() * transform->get_mat(); - into[i].set_row(3, xformed_plane); + into[i] = LCAST(float, xformed_plane); } for (; i < count; ++i) { // Fill the remainder with zeroes. - into[i] = LMatrix4::zeros_mat(); + into[i].set(0, 0, 0, 0); } return; } case Shader::SMO_mat_constant_x: { - _target_shader->get_shader_input_matrix(name, into[0]); +#ifdef STDFLOAT_DOUBLE + LMatrix4 tmp; + _target_shader->get_shader_input_matrix(name, tmp); + *(LMatrix4f *)into = LCAST(float, tmp); +#else + _target_shader->get_shader_input_matrix(name, *(LMatrix4f *)into); +#endif return; } case Shader::SMO_vec_constant_x: { - const LVecBase4 &input = _target_shader->get_shader_input_vector(name); - const PN_stdfloat *data = input.get_data(); - into[0].set(data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3]); + into[0] = LCAST(float, _target_shader->get_shader_input_vector(name)); return; } case Shader::SMO_world_to_view: { - into[0] = _scene_setup->get_world_transform()->get_mat(); + *(LMatrix4f *)into = LCAST(float, _scene_setup->get_world_transform()->get_mat()); return; } case Shader::SMO_view_to_world: { - into[0] = _scene_setup->get_camera_transform()->get_mat(); + *(LMatrix4f *)into = LCAST(float, _scene_setup->get_camera_transform()->get_mat()); return; } case Shader::SMO_model_to_view: { - into[0] = _inv_cs_transform->compose(_internal_transform)->get_mat(); + *(LMatrix4f *)into = LCAST(float, _inv_cs_transform->compose(_internal_transform)->get_mat()); return; } case Shader::SMO_model_to_apiview: { - into[0] = _internal_transform->get_mat(); + *(LMatrix4f *)into = LCAST(float, _internal_transform->get_mat()); return; } case Shader::SMO_view_to_model: { - into[0] = _internal_transform->invert_compose(_cs_transform)->get_mat(); + *(LMatrix4f *)into = LCAST(float, _internal_transform->invert_compose(_cs_transform)->get_mat()); return; } case Shader::SMO_apiview_to_model: { - into[0] = _internal_transform->get_inverse()->get_mat(); + *(LMatrix4f *)into = LCAST(float, _internal_transform->get_inverse()->get_mat()); return; } case Shader::SMO_apiview_to_view: { - into[0] = _inv_cs_transform->get_mat(); + *(LMatrix4f *)into = LCAST(float, _inv_cs_transform->get_mat()); return; } case Shader::SMO_view_to_apiview: { - into[0] = _cs_transform->get_mat(); + *(LMatrix4f *)into = LCAST(float, _cs_transform->get_mat()); return; } case Shader::SMO_clip_to_view: { if (_current_lens->get_coordinate_system() == _coordinate_system) { - into[0] = _current_lens->get_projection_mat_inv(_current_stereo_channel); + *(LMatrix4f *)into = LCAST(float, _current_lens->get_projection_mat_inv(_current_stereo_channel)); } else { - into[0] = _current_lens->get_projection_mat_inv(_current_stereo_channel) * - LMatrix4::convert_mat(_current_lens->get_coordinate_system(), _coordinate_system); + *(LMatrix4f *)into = LCAST(float, + _current_lens->get_projection_mat_inv(_current_stereo_channel) * + LMatrix4::convert_mat(_current_lens->get_coordinate_system(), _coordinate_system)); } return; } case Shader::SMO_view_to_clip: { if (_current_lens->get_coordinate_system() == _coordinate_system) { - into[0] = _current_lens->get_projection_mat(_current_stereo_channel); + *(LMatrix4f *)into = LCAST(float, _current_lens->get_projection_mat(_current_stereo_channel)); } else { - into[0] = LMatrix4::convert_mat(_coordinate_system, _current_lens->get_coordinate_system()) * - _current_lens->get_projection_mat(_current_stereo_channel); + *(LMatrix4f *)into = LCAST(float, + LMatrix4::convert_mat(_coordinate_system, _current_lens->get_coordinate_system()) * + _current_lens->get_projection_mat(_current_stereo_channel)); } return; } case Shader::SMO_apiclip_to_view: { - into[0] = _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat(); + *(LMatrix4f *)into = LCAST(float, _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat()); return; } case Shader::SMO_view_to_apiclip: { - into[0] = _cs_transform->get_mat() * _projection_mat->get_mat(); + *(LMatrix4f *)into = LCAST(float, _cs_transform->get_mat() * _projection_mat->get_mat()); return; } case Shader::SMO_apiclip_to_apiview: { - into[0] = _projection_mat_inv->get_mat(); + *(LMatrix4f *)into = LCAST(float, _projection_mat_inv->get_mat()); return; } case Shader::SMO_apiview_to_apiclip: { - into[0] = _projection_mat->get_mat(); + *(LMatrix4f *)into = LCAST(float, _projection_mat->get_mat()); return; } case Shader::SMO_view_x_to_view: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertv(!np.is_empty()); - into[0] = np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); + *(LMatrix4f *)into = LCAST(float, np.get_net_transform()->get_mat() * + _scene_setup->get_world_transform()->get_mat()); return; } case Shader::SMO_view_to_view_x: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertv(!np.is_empty()); - into[0] = _scene_setup->get_camera_transform()->get_mat() * - np.get_net_transform()->get_inverse()->get_mat(); + *(LMatrix4f *)into = LCAST(float, _scene_setup->get_camera_transform()->get_mat() * + np.get_net_transform()->get_inverse()->get_mat()); return; } case Shader::SMO_apiview_x_to_view: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertv(!np.is_empty()); - into[0] = LMatrix4::convert_mat(_internal_coordinate_system, _coordinate_system) * + *(LMatrix4f *)into = LCAST(float, LMatrix4::convert_mat(_internal_coordinate_system, _coordinate_system) * np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); + _scene_setup->get_world_transform()->get_mat()); return; } case Shader::SMO_view_to_apiview_x: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertv(!np.is_empty()); - into[0] = (_scene_setup->get_camera_transform()->get_mat() * + *(LMatrix4f *)into = LCAST(float, (_scene_setup->get_camera_transform()->get_mat() * np.get_net_transform()->get_inverse()->get_mat() * - LMatrix4::convert_mat(_coordinate_system, _internal_coordinate_system)); + LMatrix4::convert_mat(_coordinate_system, _internal_coordinate_system))); return; } case Shader::SMO_clip_x_to_view: { @@ -1480,10 +1486,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, const LensNode *node; DCAST_INTO_V(node, np.node()); const Lens *lens = node->get_lens(); - into[0] = lens->get_projection_mat_inv(_current_stereo_channel) * + *(LMatrix4f *)into = LCAST(float, lens->get_projection_mat_inv(_current_stereo_channel) * LMatrix4::convert_mat(lens->get_coordinate_system(), _coordinate_system) * np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); + _scene_setup->get_world_transform()->get_mat()); return; } case Shader::SMO_view_to_clip_x: { @@ -1492,10 +1498,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, const LensNode *node; DCAST_INTO_V(node, np.node()); const Lens *lens = node->get_lens(); - into[0] = _scene_setup->get_camera_transform()->get_mat() * + *(LMatrix4f *)into = LCAST(float, _scene_setup->get_camera_transform()->get_mat() * np.get_net_transform()->get_inverse()->get_mat() * LMatrix4::convert_mat(_coordinate_system, lens->get_coordinate_system()) * - lens->get_projection_mat(_current_stereo_channel); + lens->get_projection_mat(_current_stereo_channel)); return; } case Shader::SMO_apiclip_x_to_view: { @@ -1504,10 +1510,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, const LensNode *node; DCAST_INTO_V(node, np.node()); const Lens *lens = node->get_lens(); - into[0] = calc_projection_mat(lens)->get_inverse()->get_mat() * + *(LMatrix4f *)into = LCAST(float, calc_projection_mat(lens)->get_inverse()->get_mat() * get_cs_transform_for(lens->get_coordinate_system())->get_inverse()->get_mat() * np.get_net_transform()->get_mat() * - _scene_setup->get_world_transform()->get_mat(); + _scene_setup->get_world_transform()->get_mat()); return; } case Shader::SMO_view_to_apiclip_x: { @@ -1516,17 +1522,23 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, const LensNode *node; DCAST_INTO_V(node, np.node()); const Lens *lens = node->get_lens(); - into[0] = _scene_setup->get_camera_transform()->get_mat() * + *(LMatrix4f *)into = LCAST(float, _scene_setup->get_camera_transform()->get_mat() * np.get_net_transform()->get_inverse()->get_mat() * get_cs_transform_for(lens->get_coordinate_system())->get_mat() * - calc_projection_mat(lens)->get_mat(); + calc_projection_mat(lens)->get_mat()); return; } case Shader::SMO_mat_constant_x_attrib: { if (_target_shader->has_shader_input(name)) { // There is an input specifying precisely this whole thing, with dot and // all. Support this, even if only for backward compatibility. - _target_shader->get_shader_input_matrix(name, into[0]); +#ifdef STDFLOAT_DOUBLE + LMatrix4 tmp; + _target_shader->get_shader_input_matrix(name, tmp); + *(LMatrix4f *)into = LCAST(float, tmp); +#else + _target_shader->get_shader_input_matrix(name, *(LMatrix4f *)into); +#endif return; } @@ -1540,11 +1552,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, if (_target_shader->has_shader_input(name)) { // There is an input specifying precisely this whole thing, with dot and // all. Support this, even if only for backward compatibility. - const LVecBase4 &data = _target_shader->get_shader_input_vector(name); - into[0].set(data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3], - data[0], data[1], data[2], data[3]); + into[0] = LCAST(float, _target_shader->get_shader_input_vector(name)); return; } @@ -1554,7 +1562,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, fetch_specified_member(np, name->get_basename(), into[0]); return; } - case Shader::SMO_light_source_i_attrib: { + case Shader::SMO_light_source_i_vec_attrib: { const LightAttrib *target_light; _target_rs->get_attrib_def(target_light); @@ -1571,7 +1579,8 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, // Apply the default OpenGL lights otherwise. // Special exception for light 0, which defaults to white. if (i == 0) { - into[0] = LMatrix4::ones_mat(); + //FIXME: only the color attribute + into[0].set(1, 1, 1, 1); ++i; } for (; i < (size_t)count; ++i) { @@ -1579,6 +1588,45 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, } return; } + case Shader::SMO_apiview_to_apiclip_light_source_i: { + static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.5f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.5f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f); + + const LightAttrib *target_light; + _target_rs->get_attrib_def(target_light); + + // We don't count ambient lights, which would be pretty silly to handle + // via this mechanism. + size_t num_lights = std::min((size_t)count, target_light->get_num_non_ambient_lights()); + + size_t i = 0; + for (i = 0; i < num_lights; ++i) { + NodePath light = target_light->get_on_light(i); + nassertv(!light.is_empty()); + + LensNode *lnode; + DCAST_INTO_V(lnode, light.node()); + Lens *lens = lnode->get_lens(); + + LMatrix4 t = _inv_cs_transform->get_mat() * + _scene_setup->get_camera_transform()->get_mat() * + light.get_net_transform()->get_inverse()->get_mat() * + LMatrix4::convert_mat(_coordinate_system, lens->get_coordinate_system()); + + if (!lnode->is_of_type(PointLight::get_class_type())) { + t *= lens->get_projection_mat() * biasmat; + } + ((LMatrix4f *)into)[i] = LCAST(float, t); + } + + // Apply just the bias matrix otherwise. + for (; i < (size_t)count; ++i) { + ((LMatrix4f *)into)[i] = LCAST(float, biasmat); + } + return; + } case Shader::SMO_light_source_i_packed: { // The light matrix contains COLOR, ATTENUATION, POSITION, VIEWVECTOR const LightAttrib *target_light; @@ -1595,8 +1643,8 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, PandaNode *node = np.node(); Light *light = node->as_light(); nassertv(light != nullptr); - into[i].set_row(0, light->get_color()); - into[i].set_row(1, light->get_attenuation()); + into[0] = LCAST(float, light->get_color()); + into[1] = LVecBase4f(LCAST(float, light->get_attenuation()), 0); LMatrix4 mat = np.get_net_transform()->get_mat() * _scene_setup->get_world_transform()->get_mat(); @@ -1604,47 +1652,50 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, if (node->is_of_type(DirectionalLight::get_class_type())) { LVecBase3 d = mat.xform_vec(((const DirectionalLight *)node)->get_direction()); d.normalize(); - into[i].set_row(2, LVecBase4(d, 0)); - into[i].set_row(3, LVecBase4(-d, 0)); - - } else if (node->is_of_type(LightLensNode::get_class_type())) { + into[2] = LVecBase4f(LCAST(float, d), 0); + into[3] = LVecBase4f(-LCAST(float, d), 0); + } + else if (node->is_of_type(LightLensNode::get_class_type())) { const Lens *lens = ((const LightLensNode *)node)->get_lens(); LPoint3 p = mat.xform_point(lens->get_nodal_point()); - into[i].set_row(3, LVecBase4(p)); + into[3] = LVecBase4f(LCAST(float, p)); // For shadowed point light we need to store near/far. // For spotlight we need to store cutoff angle. if (node->is_of_type(Spotlight::get_class_type())) { PN_stdfloat cutoff = ccos(deg_2_rad(lens->get_hfov() * 0.5f)); LVecBase3 d = -(mat.xform_vec(lens->get_view_vector())); - into[i].set_cell(1, 3, ((const Spotlight *)node)->get_exponent()); - into[i].set_row(2, LVecBase4(d, cutoff)); - - } else if (node->is_of_type(PointLight::get_class_type())) { - into[i].set_cell(1, 3, lens->get_far()); - into[i].set_cell(3, 3, lens->get_near()); + into[1][3] = ((const Spotlight *)node)->get_exponent(); + into[2] = LVecBase4f(LCAST(float, d), cutoff); + } + else if (node->is_of_type(PointLight::get_class_type())) { + into[1][3] = lens->get_far(); + into[3][3] = lens->get_near(); if (node->is_of_type(SphereLight::get_class_type())) { - into[i].set_cell(2, 3, ((const SphereLight *)node)->get_radius()); + into[2][3] = ((const SphereLight *)node)->get_radius(); } } } + + into += i * 4; } // Apply the default OpenGL lights otherwise. // Special exception for light 0, which defaults to white. if (i == 0) { - into[0].set(1, 1, 1, 1, - 1, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0); + into[0].set(1, 1, 1, 1); + into[1].set(1, 0, 0, 0); + into[2].set(0, 0, 0, 0); + into[3].set(0, 0, 0, 0); ++i; } for (; i < (size_t)count; ++i) { - into[i].set(0, 0, 0, 0, - 1, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0); + into[0].set(0, 0, 0, 0); + into[1].set(1, 0, 0, 0); + into[2].set(0, 0, 0, 0); + into[3].set(0, 0, 0, 0); + into += i * 4; } return; } @@ -1672,7 +1723,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, } } - into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, thickness, catten, patten, 0.0f); + into[0].set(thickness, catten, patten, 0.0f); return; } default: @@ -1686,7 +1737,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, * the value for the given member. */ void GraphicsStateGuardian:: -fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) { +fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LVecBase4f &v) { // This system is not ideal. It will be improved in the future. static const CPT_InternalName IN_color("color"); static const CPT_InternalName IN_ambient("ambient"); @@ -1702,7 +1753,6 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) static const CPT_InternalName IN_constantAttenuation("constantAttenuation"); static const CPT_InternalName IN_linearAttenuation("linearAttenuation"); static const CPT_InternalName IN_quadraticAttenuation("quadraticAttenuation"); - static const CPT_InternalName IN_shadowViewMatrix("shadowViewMatrix"); PandaNode *node = nullptr; if (!np.is_empty()) { @@ -1711,68 +1761,68 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) if (attrib == IN_color) { if (node == nullptr) { - t = LMatrix4::ident_mat(); + v.set(0, 0, 0, 1); return; } Light *light = node->as_light(); nassertv(light != nullptr); - LColor c = light->get_color(); - t.set_row(3, c); - - } else if (attrib == IN_ambient) { + v = LCAST(float, light->get_color()); + } + else if (attrib == IN_ambient) { if (node == nullptr) { - t = LMatrix4::ident_mat(); + v.set(0, 0, 0, 1); return; } Light *light = node->as_light(); nassertv(light != nullptr); if (node->is_ambient_light()) { - LColor c = light->get_color(); - t.set_row(3, c); + v = LCAST(float, light->get_color()); } else { // Non-ambient lights don't currently have an ambient color in Panda3D. - t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f)); + v.set(0, 0, 0, 1); } - - } else if (attrib == IN_diffuse) { + } + else if (attrib == IN_diffuse) { if (node == nullptr) { - t = LMatrix4::ident_mat(); + v.set(0, 0, 0, 1); return; } Light *light = node->as_light(); nassertv(light != nullptr); if (node->is_ambient_light()) { // Ambient light has no diffuse color. - t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f)); + v.set(0, 0, 0, 1); } else { - LColor c = light->get_color(); - t.set_row(3, c); + v = LCAST(float, light->get_color()); } - - } else if (attrib == IN_specular) { + } + else if (attrib == IN_specular) { if (node == nullptr) { - t = LMatrix4::ident_mat(); + v.set(0, 0, 0, 1); return; } Light *light = node->as_light(); nassertv(light != nullptr); - t.set_row(3, light->get_specular_color()); - - } else if (attrib == IN_position) { + v = LCAST(float, light->get_specular_color()); + } + else if (attrib == IN_position) { if (np.is_empty()) { - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0); - } else if (node->is_ambient_light()) { + v.set(0, 0, 1, 0); + } + else if (node->is_ambient_light()) { // Ambient light has no position. - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - } else if (node->is_of_type(DirectionalLight::get_class_type())) { + v.set(0, 0, 0, 0); + } + else if (node->is_of_type(DirectionalLight::get_class_type())) { DirectionalLight *light; DCAST_INTO_V(light, node); CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent()); LVector3 dir = -(light->get_direction() * transform->get_mat()); dir *= _scene_setup->get_cs_world_transform()->get_mat(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 0); - } else { + v.set(dir[0], dir[1], dir[2], 0); + } + else { LightLensNode *light; DCAST_INTO_V(light, node); Lens *lens = light->get_lens(); @@ -1784,16 +1834,18 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) const LMatrix4 &light_mat = transform->get_mat(); LPoint3 pos = lens->get_nodal_point() * light_mat; - t = LMatrix4::translate_mat(pos); + v.set(pos[0], pos[1], pos[2], 1); } - - } else if (attrib == IN_halfVector) { + } + else if (attrib == IN_halfVector) { if (np.is_empty()) { - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0); - } else if (node->is_ambient_light()) { + v.set(0, 0, 1, 0); + } + else if (node->is_ambient_light()) { // Ambient light has no half-vector. - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - } else if (node->is_of_type(DirectionalLight::get_class_type())) { + v.set(0, 0, 0, 0); + } + else if (node->is_of_type(DirectionalLight::get_class_type())) { DirectionalLight *light; DCAST_INTO_V(light, node); @@ -1803,8 +1855,9 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) dir.normalize(); dir += LVector3(0, 0, 1); dir.normalize(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 1); - } else { + v.set(dir[0], dir[1], dir[2], 1); + } + else { LightLensNode *light; DCAST_INTO_V(light, node); Lens *lens = light->get_lens(); @@ -1819,16 +1872,18 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) pos.normalize(); pos += LVector3(0, 0, 1); pos.normalize(); - t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pos[0],pos[1],pos[2], 1); + v.set(pos[0], pos[1], pos[2], 1); } - - } else if (attrib == IN_spotDirection) { + } + else if (attrib == IN_spotDirection) { if (node == nullptr) { - t.set_row(3, LVector3(0.0f, 0.0f, -1.0f)); - } else if (node->is_ambient_light()) { + v.set(0, 0, -1, 0); + } + else if (node->is_ambient_light()) { // Ambient light has no spot direction. - t.set_row(3, LVector3(0.0f, 0.0f, 0.0f)); - } else { + v.set(0, 0, 0, 0); + } + else { LightLensNode *light; DCAST_INTO_V(light, node); Lens *lens = light->get_lens(); @@ -1840,10 +1895,10 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) const LMatrix4 &light_mat = transform->get_mat(); LVector3 dir = lens->get_view_vector() * light_mat; - t.set_row(3, dir); + v.set(dir[0], dir[1], dir[2], 0); } - - } else if (attrib == IN_spotCutoff) { + } + else if (attrib == IN_spotCutoff) { if (node != nullptr && node->is_of_type(Spotlight::get_class_type())) { LightLensNode *light; @@ -1852,13 +1907,14 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) nassertv(lens != nullptr); float cutoff = lens->get_hfov() * 0.5f; - t.set_row(3, LVecBase4(cutoff)); - } else { - // Other lights have no cut-off. - t.set_row(3, LVecBase4(180)); + v.fill(cutoff); } - - } else if (attrib == IN_spotCosCutoff) { + else { + // Other lights have no cut-off. + v.fill(180); + } + } + else if (attrib == IN_spotCosCutoff) { if (node != nullptr && node->is_of_type(Spotlight::get_class_type())) { LightLensNode *light; @@ -1867,91 +1923,67 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) nassertv(lens != nullptr); float cutoff = lens->get_hfov() * 0.5f; - t.set_row(3, LVecBase4(ccos(deg_2_rad(cutoff)))); + v.fill(ccos(deg_2_rad(cutoff))); } else { // Other lights have no cut-off. - t.set_row(3, LVecBase4(-1)); + v.fill(-1); } - - } else if (attrib == IN_spotExponent) { + } + else if (attrib == IN_spotExponent) { if (node == nullptr) { - t = LMatrix4::zeros_mat(); + v.fill(0); return; } Light *light = node->as_light(); nassertv(light != nullptr); - t.set_row(3, LVecBase4(light->get_exponent())); - - } else if (attrib == IN_attenuation) { + v.fill(light->get_exponent()); + } + else if (attrib == IN_attenuation) { if (node != nullptr) { Light *light = node->as_light(); nassertv(light != nullptr); - t.set_row(3, LVecBase4(light->get_attenuation(), 0)); + v = LVecBase4f(LCAST(float, light->get_attenuation()), 0); } else { - t.set_row(3, LVecBase4(1, 0, 0, 0)); + v.set(1, 0, 0, 0); } - - } else if (attrib == IN_constantAttenuation) { + } + else if (attrib == IN_constantAttenuation) { if (node == nullptr) { - t = LMatrix4::ones_mat(); + v.fill(1); return; } Light *light = node->as_light(); nassertv(light != nullptr); - t.set_row(3, LVecBase4(light->get_attenuation()[0])); - - } else if (attrib == IN_linearAttenuation) { + v.fill(light->get_attenuation()[0]); + } + else if (attrib == IN_linearAttenuation) { if (node == nullptr) { - t = LMatrix4::zeros_mat(); + v.fill(0); return; } Light *light = node->as_light(); nassertv(light != nullptr); - t.set_row(3, LVecBase4(light->get_attenuation()[1])); - - } else if (attrib == IN_quadraticAttenuation) { + v.fill(light->get_attenuation()[1]); + } + else if (attrib == IN_quadraticAttenuation) { if (node == nullptr) { - t = LMatrix4::zeros_mat(); + v.fill(0); return; } Light *light = node->as_light(); nassertv(light != nullptr); - t.set_row(3, LVecBase4(light->get_attenuation()[2])); - - } else if (attrib == IN_shadowViewMatrix) { - static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.5f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.5f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f); - - if (node == nullptr) { - t = biasmat; - return; - } - - LensNode *lnode; - DCAST_INTO_V(lnode, node); - Lens *lens = lnode->get_lens(); - - t = _inv_cs_transform->get_mat() * - _scene_setup->get_camera_transform()->get_mat() * - np.get_net_transform()->get_inverse()->get_mat() * - LMatrix4::convert_mat(_coordinate_system, lens->get_coordinate_system()); - - if (!node->is_of_type(PointLight::get_class_type())) { - t *= lens->get_projection_mat() * biasmat; - } - - } else { + v.fill(light->get_attenuation()[2]); + } + else { display_cat.error() << "Shader input requests invalid attribute " << *attrib << " from node " << np << "\n"; - t = LMatrix4::ident_mat(); + v.set(0, 0, 0, 1); } } diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 78869cabd6..617174e667 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -336,12 +336,12 @@ public: virtual void clear(DrawableRegion *clearable); - void update_shader_matrix_cache(Shader *shader, LMatrix4 *cache, int altered); - const LMatrix4 *fetch_specified_value(Shader::ShaderMatSpec &spec, const LMatrix4 *cache, int altered); + void update_shader_matrix_cache(Shader *shader, LVecBase4f *cache, int altered); + const LVecBase4f *fetch_specified_value(Shader::ShaderMatSpec &spec, const LVecBase4f *cache, int altered); void fetch_specified_part(Shader::ShaderMatInput input, InternalName *name, - LMatrix4 *into, int count = 1); + LVecBase4f *into, int count = 1); void fetch_specified_member(const NodePath &np, CPT_InternalName member, - LMatrix4 &t); + LVecBase4f &v); PT(Texture) fetch_specified_texture(Shader::ShaderTexSpec &spec, SamplerState &sampler, int &view); const Shader::ShaderPtrData *fetch_ptr_parameter(const Shader::ShaderPtrSpec& spec); diff --git a/panda/src/dxgsg9/dxShaderContext9.cxx b/panda/src/dxgsg9/dxShaderContext9.cxx index a4f3f7e24a..5a3dd6a44d 100644 --- a/panda/src/dxgsg9/dxShaderContext9.cxx +++ b/panda/src/dxgsg9/dxShaderContext9.cxx @@ -75,7 +75,7 @@ DXShaderContext9(Shader *s, GSG *gsg) : ShaderContext(s) { } #endif - _mat_part_cache = new LMatrix4[s->cp_get_mat_cache_size()]; + _mat_part_cache = new LVecBase4f[s->cp_get_mat_cache_size()]; } /** @@ -184,14 +184,6 @@ unbind(GSG *gsg) { * the parameters were issued, no part of the render state has changed except * the external and internal transforms. */ - -#if DEBUG_SHADER -PN_stdfloat *global_data = 0; -ShaderContext::ShaderMatSpec *global_shader_mat_spec = 0; -InternalName *global_internal_name_0 = 0; -InternalName *global_internal_name_1 = 0; -#endif - void DXShaderContext9:: issue_parameters(GSG *gsg, int altered) { #ifdef HAVE_CG @@ -249,106 +241,42 @@ issue_parameters(GSG *gsg, int altered) { continue; } - const LMatrix4 *val = gsg->fetch_specified_value(spec, _mat_part_cache, altered); + const LVecBase4f *val = gsg->fetch_specified_value(spec, _mat_part_cache, altered); if (val) { - HRESULT hr; - PN_stdfloat v [4]; - LMatrix4f temp_matrix = LCAST(float, *val); + const float *data = (const float *)val + spec._offset; + LVecBase4f v; + LMatrix4f temp_matrix; LMatrix3f temp_matrix3; - hr = D3D_OK; - - const float *data; - data = temp_matrix.get_data(); - -#if DEBUG_SHADER - // DEBUG - global_data = (PN_stdfloat *)data; - global_shader_mat_spec = &spec; - global_internal_name_0 = global_shader_mat_spec->_arg[0]; - global_internal_name_1 = global_shader_mat_spec->_arg[1]; -#endif - switch (spec._piece) { - case Shader::SMP_whole: + case Shader::SMP_mat4_whole: // TRANSPOSE REQUIRED - temp_matrix.transpose_in_place(); + temp_matrix.transpose_from(*(const LMatrix4f *)data); data = temp_matrix.get_data(); - - hr = cgD3D9SetUniform(p, data); break; - case Shader::SMP_transpose: - // NO TRANSPOSE REQUIRED - hr = cgD3D9SetUniform(p, data); + case Shader::SMP_mat4_column: + v.set(data[0], data[4], data[8], data[12]); + data = v.get_data(); break; - case Shader::SMP_row0: - hr = cgD3D9SetUniform(p, data + 0); - break; - case Shader::SMP_row1: - hr = cgD3D9SetUniform(p, data + 4); - break; - case Shader::SMP_row2: - hr = cgD3D9SetUniform(p, data + 8); - break; - case Shader::SMP_row3x1: - case Shader::SMP_row3x2: - case Shader::SMP_row3x3: - case Shader::SMP_row3: - hr = cgD3D9SetUniform(p, data + 12); - break; - - case Shader::SMP_col0: - v[0] = data[0]; v[1] = data[4]; v[2] = data[8]; v[3] = data[12]; - hr = cgD3D9SetUniform(p, v); - break; - case Shader::SMP_col1: - v[0] = data[1]; v[1] = data[5]; v[2] = data[9]; v[3] = data[13]; - hr = cgD3D9SetUniform(p, v); - break; - case Shader::SMP_col2: - v[0] = data[2]; v[1] = data[6]; v[2] = data[10]; v[3] = data[14]; - hr = cgD3D9SetUniform(p, v); - break; - case Shader::SMP_col3: - v[0] = data[3]; v[1] = data[7]; v[2] = data[11]; v[3] = data[15]; - hr = cgD3D9SetUniform(p, v); - break; - - case Shader::SMP_upper3x3: + case Shader::SMP_mat4_upper3x3: // TRANSPOSE REQUIRED - temp_matrix3 = temp_matrix.get_upper_3(); - temp_matrix3.transpose_in_place(); + temp_matrix3.set(data[0], data[4], data[8], data[1], data[5], data[9], data[2], data[6], data[10]); data = temp_matrix3.get_data(); - - hr = cgD3D9SetUniform(p, data); break; - case Shader::SMP_transpose3x3: + case Shader::SMP_mat4_transpose3x3: // NO TRANSPOSE REQUIRED - temp_matrix3 = temp_matrix.get_upper_3(); + temp_matrix3.set(data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]); data = temp_matrix3.get_data(); - - hr = cgD3D9SetUniform(p, data); break; - case Shader::SMP_cell15: - hr = cgD3D9SetUniform(p, data + 15); - continue; - case Shader::SMP_cell14: - hr = cgD3D9SetUniform(p, data + 14); - continue; - case Shader::SMP_cell13: - hr = cgD3D9SetUniform(p, data + 13); - continue; - default: - dxgsg9_cat.error() - << "issue_parameters () SMP parameter type not implemented " << spec._piece << "\n"; break; } + HRESULT hr = cgD3D9SetUniform(p, data); if (FAILED(hr)) { std::string name = "unnamed"; diff --git a/panda/src/dxgsg9/dxShaderContext9.h b/panda/src/dxgsg9/dxShaderContext9.h index c02dcea201..f9179069ab 100644 --- a/panda/src/dxgsg9/dxShaderContext9.h +++ b/panda/src/dxgsg9/dxShaderContext9.h @@ -87,7 +87,7 @@ private: pvector _cg_parameter_map; #endif - LMatrix4 *_mat_part_cache = nullptr; + LVecBase4f *_mat_part_cache = nullptr; private: void release_resources(void); diff --git a/panda/src/glstuff/glCgShaderContext_src.cxx b/panda/src/glstuff/glCgShaderContext_src.cxx index edf23b0658..daf671ce04 100644 --- a/panda/src/glstuff/glCgShaderContext_src.cxx +++ b/panda/src/glstuff/glCgShaderContext_src.cxx @@ -329,7 +329,7 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte } } - _mat_part_cache = new LMatrix4[_shader->cp_get_mat_cache_size()]; + _mat_part_cache = new LVecBase4f[_shader->cp_get_mat_cache_size()]; _glgsg->report_my_gl_errors(); } @@ -699,46 +699,36 @@ issue_parameters(int altered) { continue; } - const LMatrix4 *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered); + const LVecBase4f *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered); if (!val) continue; - const PN_stdfloat *data = val->get_data(); + const float *data = val->get_data(); + data += spec._offset; CGparameter p = _cg_parameter_map[spec._id._seqno]; switch (spec._piece) { - case Shader::SMP_whole: GLfc(cgGLSetMatrixParameter)(p, data); continue; - case Shader::SMP_transpose: GLfr(cgGLSetMatrixParameter)(p, data); continue; - case Shader::SMP_col0: GLf(cgGLSetParameter4)(p, data[0], data[4], data[ 8], data[12]); continue; - case Shader::SMP_col1: GLf(cgGLSetParameter4)(p, data[1], data[5], data[ 9], data[13]); continue; - case Shader::SMP_col2: GLf(cgGLSetParameter4)(p, data[2], data[6], data[10], data[14]); continue; - case Shader::SMP_col3: GLf(cgGLSetParameter4)(p, data[3], data[7], data[11], data[15]); continue; - case Shader::SMP_row0: GLfv(cgGLSetParameter4)(p, data+ 0); continue; - case Shader::SMP_row1: GLfv(cgGLSetParameter4)(p, data+ 4); continue; - case Shader::SMP_row2: GLfv(cgGLSetParameter4)(p, data+ 8); continue; - case Shader::SMP_row3: GLfv(cgGLSetParameter4)(p, data+12); continue; - case Shader::SMP_row3x1: GLfv(cgGLSetParameter1)(p, data+12); continue; - case Shader::SMP_row3x2: GLfv(cgGLSetParameter2)(p, data+12); continue; - case Shader::SMP_row3x3: GLfv(cgGLSetParameter3)(p, data+12); continue; - case Shader::SMP_upper3x3: + case Shader::SMP_float: cgGLSetParameter1f(p, data[0]); continue; + case Shader::SMP_vec2: cgGLSetParameter2fv(p, data); continue; + case Shader::SMP_vec3: cgGLSetParameter3fv(p, data); continue; + case Shader::SMP_vec4: cgGLSetParameter4fv(p, data); continue; + case Shader::SMP_mat4_whole: cgGLSetMatrixParameterfc(p, data); continue; + case Shader::SMP_mat4_transpose: cgGLSetMatrixParameterfr(p, data); continue; + case Shader::SMP_mat4_column: cgGLSetParameter4f(p, data[0], data[4], data[ 8], data[12]); continue; + case Shader::SMP_mat4_upper3x3: { - LMatrix3 upper3 = val->get_upper_3(); - GLfc(cgGLSetMatrixParameter)(p, upper3.get_data()); + LMatrix3f upper3(data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]); + cgGLSetMatrixParameterfc(p, upper3.get_data()); continue; } - case Shader::SMP_transpose3x3: + case Shader::SMP_mat4_transpose3x3: { - LMatrix3 upper3 = val->get_upper_3(); - GLfr(cgGLSetMatrixParameter)(p, upper3.get_data()); + LMatrix3f upper3(data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]); + cgGLSetMatrixParameterfr(p, upper3.get_data()); continue; } - case Shader::SMP_cell15: - GLf(cgGLSetParameter1)(p, data[15]); - continue; - case Shader::SMP_cell14: - GLf(cgGLSetParameter1)(p, data[14]); - continue; - case Shader::SMP_cell13: - GLf(cgGLSetParameter1)(p, data[13]); - continue; + case Shader::SMP_int: cgSetParameter1i(p, ((const int *)data)[0]); continue; + case Shader::SMP_ivec2: cgSetParameter2iv(p, (const int *)data); continue; + case Shader::SMP_ivec3: cgSetParameter3iv(p, (const int *)data); continue; + case Shader::SMP_ivec4: cgSetParameter4iv(p, (const int *)data); continue; } } } diff --git a/panda/src/glstuff/glCgShaderContext_src.h b/panda/src/glstuff/glCgShaderContext_src.h index 35a2d5dd36..587504bb68 100644 --- a/panda/src/glstuff/glCgShaderContext_src.h +++ b/panda/src/glstuff/glCgShaderContext_src.h @@ -75,7 +75,7 @@ private: long _transform_table_size; long _slider_table_size; - LMatrix4 *_mat_part_cache = nullptr; + LVecBase4f *_mat_part_cache = nullptr; pvector _cg_parameter_map; WCPT(RenderState) _state_rs; diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index c3af8f63fa..1d74f61c25 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -152,30 +152,54 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_t // Decide whether this is a matrix or vector. if (param_type == GL_FLOAT_MAT4) { - if (pieces[0] == "trans") bind._piece = Shader::SMP_whole; - else if (pieces[0] == "tpose") bind._piece = Shader::SMP_transpose; + if (pieces[0] == "trans") bind._piece = Shader::SMP_mat4_whole; + else if (pieces[0] == "tpose") bind._piece = Shader::SMP_mat4_transpose; else { GLCAT.error() << basename << " should be vec4, not mat3\n"; return false; } } else if (param_type == GL_FLOAT_MAT3) { - if (pieces[0] == "trans") bind._piece = Shader::SMP_upper3x3; - else if (pieces[0] == "tpose") bind._piece = Shader::SMP_transpose3x3; + if (pieces[0] == "trans") bind._piece = Shader::SMP_mat4_upper3x3; + else if (pieces[0] == "tpose") bind._piece = Shader::SMP_mat4_transpose3x3; else { GLCAT.error() << basename << " should be vec4, not mat3\n"; return false; } } else if (param_type == GL_FLOAT_VEC4) { - if (pieces[0] == "trans") bind._piece = Shader::SMP_col0; - else if (pieces[0] == "tpose") bind._piece = Shader::SMP_row0; - else if (pieces[0] == "row0") bind._piece = Shader::SMP_row0; - else if (pieces[0] == "row1") bind._piece = Shader::SMP_row1; - else if (pieces[0] == "row2") bind._piece = Shader::SMP_row2; - else if (pieces[0] == "row3") bind._piece = Shader::SMP_row3; - else if (pieces[0] == "col0") bind._piece = Shader::SMP_col0; - else if (pieces[0] == "col1") bind._piece = Shader::SMP_col1; - else if (pieces[0] == "col2") bind._piece = Shader::SMP_col2; - else if (pieces[0] == "col3") bind._piece = Shader::SMP_col3; + if (pieces[0] == "trans") bind._piece = Shader::SMP_mat4_column; + else if (pieces[0] == "tpose") bind._piece = Shader::SMP_vec4; + else if (pieces[0] == "row0") { + bind._piece = Shader::SMP_vec4; + bind._offset = 0; + } + else if (pieces[0] == "row1") { + bind._piece = Shader::SMP_vec4; + bind._offset = 4; + } + else if (pieces[0] == "row2") { + bind._piece = Shader::SMP_vec4; + bind._offset = 8; + } + else if (pieces[0] == "row3") { + bind._piece = Shader::SMP_vec4; + bind._offset = 12; + } + else if (pieces[0] == "col0") { + bind._piece = Shader::SMP_mat4_column; + bind._offset = 0; + } + else if (pieces[0] == "col1") { + bind._piece = Shader::SMP_mat4_column; + bind._offset = 1; + } + else if (pieces[0] == "col2") { + bind._piece = Shader::SMP_mat4_column; + bind._offset = 2; + } + else if (pieces[0] == "col3") { + bind._piece = Shader::SMP_mat4_column; + bind._offset = 3; + } else { GLCAT.error() << basename << " should be mat4, not vec4\n"; return false; @@ -184,13 +208,13 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_t // We'll permit this too, simply because we can support it. switch (param_type) { case GL_FLOAT: - bind._piece = Shader::SMP_row3x1; + bind._piece = Shader::SMP_float; break; case GL_FLOAT_VEC2: - bind._piece = Shader::SMP_row3x2; + bind._piece = Shader::SMP_vec2; break; case GL_FLOAT_VEC3: - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec3; break; default: GLCAT.error() << basename << " should be vec4\n"; @@ -234,7 +258,7 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_t if (param_size > 1) { // We support arrays of rows and arrays of columns, so we can run the // GLSL shaders that cgc spits out. - if (bind._piece == Shader::SMP_row0 || bind._piece == Shader::SMP_col0) { + if (bind._piece == Shader::SMP_vec4 || bind._piece == Shader::SMP_mat4_column) { if (param_size > 4) { GLCAT.warning() << basename << "[" << param_size << "] is too large, only the first four elements will be defined\n"; param_size = 4; @@ -396,7 +420,7 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext _glgsg->_current_shader_context->bind(); } - _mat_part_cache = new LMatrix4[_shader->cp_get_mat_cache_size()]; + _mat_part_cache = new LVecBase4f[_shader->cp_get_mat_cache_size()]; } /** @@ -827,15 +851,15 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_compose; if (param_type == GL_FLOAT_MAT3) { if (transpose) { - bind._piece = Shader::SMP_upper3x3; + bind._piece = Shader::SMP_mat4_upper3x3; } else { - bind._piece = Shader::SMP_transpose3x3; + bind._piece = Shader::SMP_mat4_transpose3x3; } } else if (param_type == GL_FLOAT_MAT4) { if (transpose) { - bind._piece = Shader::SMP_transpose; + bind._piece = Shader::SMP_mat4_transpose; } else { - bind._piece = Shader::SMP_whole; + bind._piece = Shader::SMP_mat4_whole; } } else { GLCAT.error() @@ -941,13 +965,15 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { // A matrix member of a p3d_LightSource struct. if (strncmp(name_buffer, "shadowViewMatrix", 127) == 0) { if (inverse) { - // Tack inverse back onto the end. - strcpy(name_buffer + strlen(name_buffer), "Inverse"); + GLCAT.error() + << "p3d_LightSource struct does not provide a matrix named " + << name_buffer << "Inverse!\n"; + return; } bind._func = Shader::SMF_first; - bind._part[0] = Shader::SMO_light_source_i_attrib; - bind._arg[0] = InternalName::make(name_buffer); + bind._part[0] = Shader::SMO_apiview_to_apiclip_light_source_i; + bind._arg[0] = nullptr; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; @@ -957,8 +983,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_compose; bind._part[0] = Shader::SMO_model_to_apiview; bind._arg[0] = nullptr; - bind._part[1] = Shader::SMO_light_source_i_attrib; - bind._arg[1] = InternalName::make("shadowViewMatrix"); + bind._part[1] = Shader::SMO_apiview_to_apiclip_light_source_i; + bind._arg[1] = nullptr; static bool warned = false; if (!warned) { @@ -1061,7 +1087,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_Material.baseColor should be vec4\n"; } bind._part[0] = Shader::SMO_attr_material2; - bind._piece = Shader::SMP_row0; + bind._piece = Shader::SMP_vec4; _shader->cp_add_mat_spec(bind); return; @@ -1070,7 +1096,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { GLCAT.error() << "p3d_Material.ambient should be vec4\n"; } - bind._piece = Shader::SMP_row0; + bind._piece = Shader::SMP_vec4; _shader->cp_add_mat_spec(bind); return; @@ -1079,7 +1105,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { GLCAT.error() << "p3d_Material.diffuse should be vec4\n"; } - bind._piece = Shader::SMP_row1; + bind._piece = Shader::SMP_vec4; + bind._offset = 4; _shader->cp_add_mat_spec(bind); return; @@ -1088,7 +1115,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { GLCAT.error() << "p3d_Material.emission should be vec4\n"; } - bind._piece = Shader::SMP_row2; + bind._piece = Shader::SMP_vec4; + bind._offset = 8; _shader->cp_add_mat_spec(bind); return; @@ -1097,7 +1125,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { GLCAT.error() << "p3d_Material.specular should be vec3\n"; } - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec3; + bind._offset = 12; _shader->cp_add_mat_spec(bind); return; @@ -1106,7 +1135,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { GLCAT.error() << "p3d_Material.shininess should be float\n"; } - bind._piece = Shader::SMP_cell15; + bind._piece = Shader::SMP_float; + bind._offset = 15; _shader->cp_add_mat_spec(bind); return; @@ -1116,7 +1146,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_Material.roughness should be float\n"; } bind._part[0] = Shader::SMO_attr_material2; - bind._piece = Shader::SMP_cell15; + bind._piece = Shader::SMP_float; + bind._offset = 7; _shader->cp_add_mat_spec(bind); return; @@ -1126,7 +1157,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_Material.metallic should be bool or float\n"; } bind._part[0] = Shader::SMO_attr_material2; - bind._piece = Shader::SMP_row3x1; + bind._piece = Shader::SMP_float; + bind._offset = 4; _shader->cp_add_mat_spec(bind); return; @@ -1136,7 +1168,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { << "p3d_Material.refractiveIndex should be float\n"; } bind._part[0] = Shader::SMO_attr_material2; - bind._piece = Shader::SMP_cell13; + bind._piece = Shader::SMP_float; + bind._offset = 5; _shader->cp_add_mat_spec(bind); return; } @@ -1151,9 +1184,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._arg[1] = nullptr; if (param_type == GL_FLOAT_VEC3) { - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec3; } else if (param_type == GL_FLOAT_VEC4) { - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec4; } else { GLCAT.error() << "p3d_ColorScale should be vec3 or vec4\n"; @@ -1172,9 +1205,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._arg[1] = nullptr; if (param_type == GL_FLOAT_VEC3) { - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec3; } else if (param_type == GL_FLOAT_VEC4) { - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec3; } else { GLCAT.error() << "p3d_Color should be vec3 or vec4\n"; @@ -1193,7 +1226,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { Shader::ShaderMatSpec bind; bind._id = arg_id; bind._id._seqno = p + i; - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec4; bind._func = Shader::SMF_first; bind._index = i; bind._part[0] = Shader::SMO_apiview_clipplane_i; @@ -1216,9 +1249,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._part[0] = Shader::SMO_attr_fogcolor; if (param_type == GL_FLOAT_VEC3) { - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec4; } else if (param_type == GL_FLOAT_VEC4) { - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec4; } else { GLCAT.error() << "p3d_Fog.color should be vec3 or vec4\n"; @@ -1229,7 +1262,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._part[0] = Shader::SMO_attr_fog; if (param_type == GL_FLOAT) { - bind._piece = Shader::SMP_row3x1; + bind._piece = Shader::SMP_float; } else { GLCAT.error() << "p3d_Fog.density should be float\n"; @@ -1240,7 +1273,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._part[0] = Shader::SMO_attr_fog; if (param_type == GL_FLOAT) { - bind._piece = Shader::SMP_cell13; + bind._piece = Shader::SMP_float; + bind._offset = 13; } else { GLCAT.error() << "p3d_Fog.start should be float\n"; @@ -1251,7 +1285,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._part[0] = Shader::SMO_attr_fog; if (param_type == GL_FLOAT) { - bind._piece = Shader::SMP_cell14; + bind._piece = Shader::SMP_float; + bind._offset = 14; } else { GLCAT.error() << "p3d_Fog.end should be float\n"; @@ -1262,7 +1297,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._part[0] = Shader::SMO_attr_fog; if (param_type == GL_FLOAT) { - bind._piece = Shader::SMP_cell15; + bind._piece = Shader::SMP_float; + bind._offset = 15; } else { GLCAT.error() << "p3d_Fog.scale should be float\n"; @@ -1283,9 +1319,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._arg[1] = nullptr; if (param_type == GL_FLOAT_VEC3) { - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec3; } else if (param_type == GL_FLOAT_VEC4) { - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec4; } else { GLCAT.error() << "p3d_LightModel.ambient should be vec3 or vec4\n"; @@ -1329,26 +1365,26 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._id = arg_id; bind._func = Shader::SMF_first; bind._index = index; - bind._part[0] = Shader::SMO_light_source_i_attrib; + bind._part[0] = Shader::SMO_light_source_i_vec_attrib; bind._arg[0] = InternalName::make(member_name); bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; switch (param_type) { case GL_FLOAT: - bind._piece = Shader::SMP_row3x1; + bind._piece = Shader::SMP_float; break; case GL_FLOAT_VEC2: - bind._piece = Shader::SMP_row3x2; + bind._piece = Shader::SMP_vec2; break; case GL_FLOAT_VEC3: - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec3; break; case GL_FLOAT_VEC4: - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec4; break; default: @@ -1390,7 +1426,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._arg[0] = nullptr; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec4; _shader->cp_add_mat_spec(bind); return; } @@ -1408,7 +1444,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._arg[1] = nullptr; if (noprefix == "ViewMatrix") { - bind._piece = Shader::SMP_whole; + bind._piece = Shader::SMP_mat4_whole; bind._func = Shader::SMF_compose; bind._part[0] = Shader::SMO_world_to_view; bind._part[1] = Shader::SMO_view_to_apiview; @@ -1416,7 +1452,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { return; } else if (noprefix == "InverseViewMatrix" || noprefix == "ViewMatrixInverse") { - bind._piece = Shader::SMP_whole; + bind._piece = Shader::SMP_mat4_whole; bind._func = Shader::SMF_compose; bind._part[0] = Shader::SMO_apiview_to_view; bind._part[1] = Shader::SMO_view_to_world; @@ -1424,7 +1460,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { return; } else if (noprefix == "FrameTime") { - bind._piece = Shader::SMP_row3x1; + bind._piece = Shader::SMP_float; bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_frame_time; bind._part[1] = Shader::SMO_identity; @@ -1432,7 +1468,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { return; } else if (noprefix == "DeltaFrameTime") { - bind._piece = Shader::SMP_row3x1; + bind._piece = Shader::SMP_float; bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_frame_delta; bind._part[1] = Shader::SMO_identity; @@ -1516,7 +1552,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { case GL_FLOAT_MAT3: { Shader::ShaderMatSpec bind; bind._id = arg_id; - bind._piece = Shader::SMP_upper3x3; + bind._piece = Shader::SMP_mat4_upper3x3; bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_mat_constant_x; bind._arg[0] = InternalName::make(param_name); @@ -1528,7 +1564,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { case GL_FLOAT_MAT4: { Shader::ShaderMatSpec bind; bind._id = arg_id; - bind._piece = Shader::SMP_whole; + bind._piece = Shader::SMP_mat4_whole; bind._func = Shader::SMF_first; bind._part[1] = Shader::SMO_identity; bind._arg[1] = nullptr; @@ -1552,8 +1588,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._func = Shader::SMF_compose; bind._part[0] = Shader::SMO_model_to_apiview; bind._arg[0] = nullptr; - bind._part[1] = Shader::SMO_mat_constant_x_attrib; - bind._arg[1] = iname->get_parent()->append("shadowViewMatrix"); + bind._part[1] = Shader::SMO_apiview_to_apiclip_light_source_i; + bind._arg[1] = nullptr; } else { bind._part[0] = Shader::SMO_mat_constant_x_attrib; bind._arg[0] = InternalName::make(param_name); @@ -1578,16 +1614,16 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._id = arg_id; switch (param_type) { case GL_FLOAT: - bind._piece = Shader::SMP_row3x1; + bind._piece = Shader::SMP_float; break; case GL_FLOAT_VEC2: - bind._piece = Shader::SMP_row3x2; + bind._piece = Shader::SMP_vec2; break; case GL_FLOAT_VEC3: - bind._piece = Shader::SMP_row3x3; + bind._piece = Shader::SMP_vec3; break; default: - bind._piece = Shader::SMP_row3; + bind._piece = Shader::SMP_vec4; } bind._func = Shader::SMF_first; bind._part[0] = Shader::SMO_vec_constant_x_attrib; @@ -2263,61 +2299,36 @@ issue_parameters(int altered) { continue; } - const LMatrix4 *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered); + const LVecBase4f *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered); if (!val) continue; -#ifndef STDFLOAT_DOUBLE - // In this case, the data is already single-precision. - const PN_float32 *data = val->get_data(); -#else - // In this case, we have to convert it. - LMatrix4f valf = LCAST(PN_float32, *val); - const PN_float32 *data = valf.get_data(); -#endif + const float *data = val->get_data(); + data += spec._offset; GLint p = spec._id._seqno; switch (spec._piece) { - case Shader::SMP_whole: _glgsg->_glUniformMatrix4fv(p, 1, GL_FALSE, data); continue; - case Shader::SMP_transpose: _glgsg->_glUniformMatrix4fv(p, 1, GL_TRUE, data); continue; - case Shader::SMP_col0: _glgsg->_glUniform4f(p, data[0], data[4], data[ 8], data[12]); continue; - case Shader::SMP_col1: _glgsg->_glUniform4f(p, data[1], data[5], data[ 9], data[13]); continue; - case Shader::SMP_col2: _glgsg->_glUniform4f(p, data[2], data[6], data[10], data[14]); continue; - case Shader::SMP_col3: _glgsg->_glUniform4f(p, data[3], data[7], data[11], data[15]); continue; - case Shader::SMP_row0: _glgsg->_glUniform4fv(p, 1, data+ 0); continue; - case Shader::SMP_row1: _glgsg->_glUniform4fv(p, 1, data+ 4); continue; - case Shader::SMP_row2: _glgsg->_glUniform4fv(p, 1, data+ 8); continue; - case Shader::SMP_row3: _glgsg->_glUniform4fv(p, 1, data+12); continue; - case Shader::SMP_row3x1: _glgsg->_glUniform1fv(p, 1, data+12); continue; - case Shader::SMP_row3x2: _glgsg->_glUniform2fv(p, 1, data+12); continue; - case Shader::SMP_row3x3: _glgsg->_glUniform3fv(p, 1, data+12); continue; - case Shader::SMP_upper3x3: + case Shader::SMP_float: _glgsg->_glUniform1fv(p, 1, data); continue; + case Shader::SMP_vec2: _glgsg->_glUniform2fv(p, 1, data); continue; + case Shader::SMP_vec3: _glgsg->_glUniform3fv(p, 1, data); continue; + case Shader::SMP_vec4: _glgsg->_glUniform4fv(p, 1, data); continue; + case Shader::SMP_mat4_whole: _glgsg->_glUniformMatrix4fv(p, 1, GL_FALSE, data); continue; + case Shader::SMP_mat4_transpose: _glgsg->_glUniformMatrix4fv(p, 1, GL_TRUE, data); continue; + case Shader::SMP_mat4_column: _glgsg->_glUniform4f(p, data[0], data[4], data[8], data[12]); continue; + case Shader::SMP_mat4_upper3x3: { -#ifndef STDFLOAT_DOUBLE - LMatrix3f upper3 = val->get_upper_3(); -#else - LMatrix3f upper3 = valf.get_upper_3(); -#endif + LMatrix3f upper3(data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]); _glgsg->_glUniformMatrix3fv(p, 1, false, upper3.get_data()); continue; } - case Shader::SMP_transpose3x3: + case Shader::SMP_mat4_transpose3x3: { -#ifndef STDFLOAT_DOUBLE - LMatrix3f upper3 = val->get_upper_3(); -#else - LMatrix3f upper3 = valf.get_upper_3(); -#endif + LMatrix3f upper3(data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]); _glgsg->_glUniformMatrix3fv(p, 1, true, upper3.get_data()); continue; } - case Shader::SMP_cell15: - _glgsg->_glUniform1fv(p, 1, data+15); - continue; - case Shader::SMP_cell14: - _glgsg->_glUniform1fv(p, 1, data+14); - continue; - case Shader::SMP_cell13: - _glgsg->_glUniform1fv(p, 1, data+13); - continue; + case Shader::SMP_int: _glgsg->_glUniform1i(p, ((int *)data)[0]); + case Shader::SMP_ivec2: _glgsg->_glUniform2iv(p, 1, (int *)data); + case Shader::SMP_ivec3: _glgsg->_glUniform3iv(p, 1, (int *)data); + case Shader::SMP_ivec4: _glgsg->_glUniform4iv(p, 1, (int *)data); } } } diff --git a/panda/src/glstuff/glShaderContext_src.h b/panda/src/glstuff/glShaderContext_src.h index 878941c114..7e63c1a611 100644 --- a/panda/src/glstuff/glShaderContext_src.h +++ b/panda/src/glstuff/glShaderContext_src.h @@ -112,7 +112,7 @@ private: }; pvector _glsl_img_inputs; - LMatrix4 *_mat_part_cache = nullptr; + LVecBase4f *_mat_part_cache = nullptr; CLP(GraphicsStateGuardian) *_glgsg; diff --git a/panda/src/glstuff/glmisc_src.h b/panda/src/glstuff/glmisc_src.h index 6568c1b2ef..1cc96726fe 100644 --- a/panda/src/glstuff/glmisc_src.h +++ b/panda/src/glstuff/glmisc_src.h @@ -24,16 +24,8 @@ #ifndef STDFLOAT_DOUBLE #define GLf(name) name ## f -#define GLfv(name) name ## fv -#define GLfc(name) name ## fc -#define GLfr(name) name ## fr -#define GLf_str "f" #else // STDFLOAT_DOUBLE #define GLf(name) name ## d -#define GLfv(name) name ## dv -#define GLfc(name) name ## dc -#define GLfr(name) name ## dr -#define GLf_str "d" #endif // STDFLOAT_DOUBLE #endif // GLf diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 93e7df92d5..628445e4dc 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -459,11 +459,13 @@ cp_dependency(ShaderMatInput inp) { } } if ((inp == SMO_light_ambient) || - (inp == SMO_light_source_i_attrib) || + (inp == SMO_light_source_i_vec_attrib) || + (inp == SMO_apiview_to_apiclip_light_source_i) || (inp == SMO_light_source_i_packed)) { dep |= SSD_light | SSD_frame; } - if (inp == SMO_light_source_i_attrib || + if (inp == SMO_light_source_i_vec_attrib || + inp == SMO_apiview_to_apiclip_light_source_i || inp == SMO_light_source_i_packed || inp == SMO_mat_constant_x_attrib || inp == SMO_vec_constant_x_attrib) { @@ -579,14 +581,13 @@ cp_add_mat_spec(ShaderMatSpec &spec) { for (int i = 0; i < 2; ++i) { if (spec._part[i] == SMO_texmat_i || spec._part[i] == SMO_inv_texmat_i || - spec._part[i] == SMO_light_source_i_attrib || + spec._part[i] == SMO_light_source_i_vec_attrib || + spec._part[i] == SMO_apiview_to_apiclip_light_source_i || spec._part[i] == SMO_light_product_i_ambient || spec._part[i] == SMO_light_product_i_diffuse || spec._part[i] == SMO_light_product_i_specular || spec._part[i] == SMO_apiview_clipplane_i || spec._part[i] == SMO_tex_is_alpha_i || - spec._part[i] == SMO_transform_i || - spec._part[i] == SMO_slider_i || spec._part[i] == SMO_light_source_i_packed || spec._part[i] == SMO_texscale_i || spec._part[i] == SMO_texcolor_i) { @@ -610,6 +611,9 @@ cp_add_mat_spec(ShaderMatSpec &spec) { for (i = 0; i < _mat_parts.size(); ++i) { ShaderMatPart &part = _mat_parts[i]; if (part._part == spec._part[p] && part._arg == spec._arg[p]) { + if (spec._func != SMF_first) { + assert(part._size == 4); + } int diff = end[p] - part._count; if (diff <= 0) { // The existing cache entry is big enough. @@ -618,18 +622,18 @@ cp_add_mat_spec(ShaderMatSpec &spec) { // It's not big enough. Enlarge it, which means we have to change the // offset of some of the other spec entries. for (ShaderMatSpec &spec : _mat_spec) { - if (spec._cache_offset[0] >= offset + part._count) { - spec._cache_offset[0] += diff; + if (spec._cache_offset[0] >= offset + part._size * part._count) { + spec._cache_offset[0] += diff * part._size; } - if (spec._cache_offset[1] >= offset + part._count) { - spec._cache_offset[1] += diff; + if (spec._cache_offset[1] >= offset + part._size * part._count) { + spec._cache_offset[1] += diff * part._size; } } part._count = end[p]; break; } } - offset += part._count; + offset += part._count * part._size; } if (i == _mat_parts.size()) { // Didn't find this part yet, create a new one. @@ -638,6 +642,88 @@ cp_add_mat_spec(ShaderMatSpec &spec) { part._count = end[p]; part._arg = spec._arg[p]; part._dep = dep; + + switch (part._part) { + case SMO_INVALID: + part._size = 0; + break; + + case SMO_window_size: + case SMO_pixel_size: + case SMO_texpad_x: + case SMO_texpix_x: + case SMO_attr_material: + case SMO_attr_color: + case SMO_attr_colorscale: + case SMO_satten_x: + case SMO_plane_x: + case SMO_clipplane_x: + case SMO_vec_constant_x: + case SMO_attr_fog: + case SMO_attr_fogcolor: + case SMO_frame_number: + case SMO_frame_time: + case SMO_frame_delta: + case SMO_vec_constant_x_attrib: + case SMO_light_ambient: + case SMO_light_source_i_vec_attrib: + case SMO_light_product_i_ambient: + case SMO_light_product_i_diffuse: + case SMO_light_product_i_specular: + case SMO_apiview_clipplane_i: + case SMO_tex_is_alpha_i: + case SMO_texscale_i: + case SMO_texcolor_i: + case SMO_texconst_i: + case SMO_attr_pointparams: + part._size = 1; + break; + + case SMO_attr_material2: + part._size = 2; + break; + + case SMO_identity: + case SMO_alight_x: + case SMO_dlight_x: + case SMO_plight_x: + case SMO_slight_x: + case SMO_texmat_i: + case SMO_mat_constant_x: + case SMO_world_to_view: + case SMO_view_to_world: + case SMO_model_to_view: + case SMO_view_to_model: + case SMO_apiview_to_view: + case SMO_view_to_apiview: + case SMO_clip_to_view: + case SMO_view_to_clip: + case SMO_apiclip_to_view: + case SMO_view_to_apiclip: + case SMO_view_x_to_view: + case SMO_view_to_view_x: + case SMO_apiview_x_to_view: + case SMO_view_to_apiview_x: + case SMO_clip_x_to_view: + case SMO_view_to_clip_x: + case SMO_apiclip_x_to_view: + case SMO_view_to_apiclip_x: + case SMO_mat_constant_x_attrib: + case SMO_apiview_to_apiclip_light_source_i: + case SMO_model_to_apiview: + case SMO_apiview_to_model: + case SMO_apiview_to_apiclip: + case SMO_apiclip_to_apiview: + case SMO_inv_texmat_i: + case SMO_light_source_i_packed: + part._size = 4; + break; + } + + if (spec._func != SMF_first) { + assert(part._size == 4); + } + _mat_parts.push_back(std::move(part)); } spec._cache_offset[p] = offset + begin[p]; @@ -648,13 +734,14 @@ cp_add_mat_spec(ShaderMatSpec &spec) { } /** - * Returns the total size of the matrix part cache. + * Returns the total size of the matrix part cache in terms of number of + * vectors. */ size_t Shader:: cp_get_mat_cache_size() const { size_t size = 0; for (const ShaderMatPart &part : _mat_parts) { - size += part._count; + size += part._size * part._count; } return size; } @@ -858,12 +945,12 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_whole; + bind._piece = SMP_mat4_whole; bind._func = SMF_compose; - bind._part[1] = SMO_light_source_i_attrib; - bind._arg[1] = InternalName::make("shadowViewMatrix"); bind._part[0] = SMO_view_to_apiview; bind._arg[0] = nullptr; + bind._part[1] = SMO_apiview_to_apiclip_light_source_i; + bind._arg[1] = nullptr; bind._index = atoi(pieces[2].c_str()); cp_add_mat_spec(bind); @@ -969,42 +1056,46 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_whole; + bind._piece = SMP_mat4_whole; bind._func = SMF_compose; - bind._part[1] = SMO_light_source_i_attrib; - bind._arg[1] = InternalName::make("shadowViewMatrix"); bind._part[0] = SMO_view_to_apiview; bind._arg[0] = nullptr; + bind._part[1] = SMO_apiview_to_apiclip_light_source_i; + bind._arg[1] = nullptr; bind._index = atoi(pieces[2].c_str()); int next = 1; pieces.push_back(""); // Decide whether this is a matrix or vector. - if (pieces[0]=="trans") bind._piece = SMP_whole; - else if (pieces[0]=="tpose") bind._piece = SMP_transpose; - else if (pieces[0]=="row0") bind._piece = SMP_row0; - else if (pieces[0]=="row1") bind._piece = SMP_row1; - else if (pieces[0]=="row2") bind._piece = SMP_row2; - else if (pieces[0]=="row3") bind._piece = SMP_row3; - else if (pieces[0]=="col0") bind._piece = SMP_col0; - else if (pieces[0]=="col1") bind._piece = SMP_col1; - else if (pieces[0]=="col2") bind._piece = SMP_col2; - else if (pieces[0]=="col3") bind._piece = SMP_col3; - if ((bind._piece == SMP_whole)||(bind._piece == SMP_transpose)) { + if (pieces[0][0] == 't') { // trans or tpose + bool tpose = (pieces[0][1] == 'p'); if (p._type == SAT_mat3x3) { - if (!cp_errchk_parameter_float(p, 9, 9)) return false; - - if (bind._piece == SMP_transpose) { - bind._piece = SMP_transpose3x3; - } else { - bind._piece = SMP_upper3x3; + if (!cp_errchk_parameter_float(p, 9, 9)) { + return false; } - } else if (!cp_errchk_parameter_float(p, 16, 16)) { + bind._piece = tpose ? SMP_mat4_transpose3x3 : SMP_mat4_upper3x3; + } + else { + if (!cp_errchk_parameter_float(p, 16, 16)) { + return false; + } + bind._piece = tpose ? SMP_mat4_transpose : SMP_mat4_whole; + } + } + else if (pieces[0][0] == 'r') { // row0, row1, row2, row3 + if (!cp_errchk_parameter_float(p, 4, 4)) { return false; } - } else { - if (!cp_errchk_parameter_float(p, 4, 4)) return false; + bind._piece = SMP_vec4; + bind._offset = (pieces[0][3] - '0') * 4; + } + else if (pieces[0][0] == 'c') { // col0, col1, col2, col3 + if (!cp_errchk_parameter_float(p, 4, 4)) { + return false; + } + bind._piece = SMP_mat4_column; + bind._offset = pieces[0][3] - '0'; } if (!cp_parse_coord_sys(p, pieces, next, bind, true)) { @@ -1037,7 +1128,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_transpose; + bind._piece = SMP_mat4_transpose; bind._func = SMF_first; bind._part[0] = SMO_attr_material; bind._arg[0] = nullptr; @@ -1048,7 +1139,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_attr_color; bind._arg[0] = nullptr; @@ -1059,7 +1150,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_attr_colorscale; bind._arg[0] = nullptr; @@ -1070,7 +1161,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_attr_fog; bind._arg[0] = nullptr; @@ -1081,7 +1172,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_attr_fogcolor; bind._arg[0] = nullptr; @@ -1092,7 +1183,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_light_ambient; bind._arg[0] = nullptr; @@ -1103,7 +1194,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_transpose; + bind._piece = SMP_mat4_transpose; bind._func = SMF_first; bind._part[0] = SMO_light_source_i_packed; bind._arg[0] = nullptr; @@ -1115,9 +1206,9 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; - bind._part[0] = SMO_light_source_i_attrib; + bind._part[0] = SMO_light_source_i_vec_attrib; bind._arg[0] = InternalName::make("specular"); bind._part[1] = SMO_identity; bind._arg[1] = nullptr; @@ -1127,7 +1218,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { return false; } bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_attr_pointparams; bind._arg[0] = nullptr; @@ -1165,7 +1256,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_alight_x; bind._arg[0] = InternalName::make(pieces[1]); @@ -1185,7 +1276,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_satten_x; bind._arg[0] = InternalName::make(pieces[1]); @@ -1204,7 +1295,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_transpose; + bind._piece = SMP_mat4_transpose; int next = 1; pieces.push_back(""); if (pieces[next] == "") { @@ -1245,7 +1336,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_whole; + bind._piece = SMP_mat4_whole; bind._func = SMF_first; bind._part[0] = SMO_texmat_i; bind._arg[0] = nullptr; @@ -1266,7 +1357,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_texscale_i; bind._arg[0] = nullptr; @@ -1287,7 +1378,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_texcolor_i; bind._arg[0] = nullptr; @@ -1308,7 +1399,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_texconst_i; bind._arg[0] = nullptr; @@ -1329,7 +1420,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_plane_x; bind._arg[0] = InternalName::make(pieces[1]); @@ -1349,7 +1440,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_clipplane_x; bind._arg[0] = InternalName::make(pieces[1]); @@ -1370,7 +1461,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[1] = SMO_identity; bind._arg[1] = nullptr; @@ -1392,7 +1483,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { if (!cp_errchk_parameter_float(p, 1, 1)) { return false; } - bind._piece = SMP_row3x1; + bind._piece = SMP_float; bind._part[0] = SMO_frame_time; bind._arg[0] = nullptr; @@ -1479,7 +1570,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_texpad_x; bind._arg[0] = InternalName::make(pieces[1]); @@ -1498,7 +1589,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { } ShaderMatSpec bind; bind._id = p._id; - bind._piece = SMP_row3; + bind._piece = SMP_vec4; bind._func = SMF_first; bind._part[0] = SMO_texpix_x; bind._arg[0] = InternalName::make(pieces[1]); diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index 4f8687fa00..fc7e49ae55 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -183,7 +183,8 @@ public: SMO_vec_constant_x_attrib, SMO_light_ambient, - SMO_light_source_i_attrib, + SMO_light_source_i_vec_attrib, + SMO_apiview_to_apiclip_light_source_i, SMO_light_product_i_ambient, SMO_light_product_i_diffuse, @@ -205,9 +206,6 @@ public: // Hack for text rendering. Don't use in user shaders. SMO_tex_is_alpha_i, - SMO_transform_i, - SMO_slider_i, - SMO_light_source_i_packed, // Texture scale component of texture matrix. @@ -294,24 +292,19 @@ public: }; enum ShaderMatPiece { - SMP_whole, - SMP_transpose, - SMP_row0, - SMP_row1, - SMP_row2, - SMP_row3, - SMP_col0, - SMP_col1, - SMP_col2, - SMP_col3, - SMP_row3x1, - SMP_row3x2, - SMP_row3x3, - SMP_upper3x3, - SMP_transpose3x3, - SMP_cell15, - SMP_cell14, - SMP_cell13, + SMP_float, + SMP_vec2, + SMP_vec3, + SMP_vec4, + SMP_mat4_whole, + SMP_mat4_transpose, + SMP_mat4_column, + SMP_mat4_upper3x3, + SMP_mat4_transpose3x3, + SMP_int, + SMP_ivec2, + SMP_ivec3, + SMP_ivec4, }; enum ShaderStateDep { @@ -339,11 +332,11 @@ public: }; enum ShaderMatFunc { + SMF_first, SMF_compose, SMF_transform_dlight, SMF_transform_plight, SMF_transform_slight, - SMF_first, }; struct ShaderArgId { @@ -422,12 +415,14 @@ public: /** * Describes a matrix making up a single part of the ShaderMatInput cache. - * The cache is made up of a continuous array of matrices, as described by - * a successive list of ShaderMatPart (each of which takes up _count matrices) + * The cache is made up of a continuous array of vectors, as described by + * a successive list of ShaderMatPart (each of which takes up _count times + * _size vectors) */ struct ShaderMatPart { ShaderMatInput _part; PT(InternalName) _arg; + int _size = 1; int _count = 1; int _dep = SSD_NONE; }; @@ -441,10 +436,11 @@ public: ShaderMatFunc _func; ShaderMatInput _part[2]; PT(InternalName) _arg[2]; - LMatrix4 _value; + LMatrix4f _value; int _dep = SSD_NONE; int _index = 0; ShaderMatPiece _piece; + int _offset = 0; }; struct ShaderTexSpec {