Optimize shader matrix generator, allow changing GL internal coord system

This commit is contained in:
rdb 2015-05-11 18:07:14 +02:00
parent 1fb49dc3f7
commit 07ea84a1a0
7 changed files with 96 additions and 36 deletions

View File

@ -1265,10 +1265,17 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
case Shader::SMO_model_to_view: {
return &(get_external_transform()->get_mat());
}
case Shader::SMO_model_to_apiview: {
return &(get_internal_transform()->get_mat());
}
case Shader::SMO_view_to_model: {
t = get_external_transform()->get_inverse()->get_mat();
return &t;
}
case Shader::SMO_apiview_to_model: {
t = get_internal_transform()->get_inverse()->get_mat();
return &t;
}
case Shader::SMO_apiview_to_view: {
return &(_inv_cs_transform->get_mat());
}
@ -1301,6 +1308,12 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
t = _cs_transform->get_mat() * _projection_mat->get_mat();
return &t;
}
case Shader::SMO_apiclip_to_apiview: {
return &(_projection_mat_inv->get_mat());
}
case Shader::SMO_apiview_to_apiclip: {
return &(_projection_mat->get_mat());
}
case Shader::SMO_view_x_to_view: {
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
nassertr(!np.is_empty(), &LMatrix4::ident_mat());

View File

@ -304,7 +304,7 @@ int CLP(GraphicsStateGuardian)::get_driver_shader_version_minor() { return _gl_s
////////////////////////////////////////////////////////////////////
CLP(GraphicsStateGuardian)::
CLP(GraphicsStateGuardian)(GraphicsEngine *engine, GraphicsPipe *pipe) :
GraphicsStateGuardian(CS_yup_right, engine, pipe)
GraphicsStateGuardian(gl_coordinate_system, engine, pipe)
{
_error_count = 0;
@ -2847,7 +2847,8 @@ calc_projection_mat(const Lens *lens) {
// choice in the modelview matrix.
LMatrix4 result =
LMatrix4::convert_mat(CS_yup_right, lens->get_coordinate_system()) *
LMatrix4::convert_mat(_internal_coordinate_system,
lens->get_coordinate_system()) *
lens->get_projection_mat(_current_stereo_channel);
if (_scene_setup->get_inverted()) {

View File

@ -269,10 +269,18 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
Shader::ShaderMatSpec bind;
bind._id = arg_id;
bind._func = Shader::SMF_compose;
if (transpose) {
bind._piece = Shader::SMP_transpose;
if (param_type == GL_FLOAT_MAT3) {
if (transpose) {
bind._piece = Shader::SMP_upper3x3;
} else {
bind._piece = Shader::SMP_transpose3x3;
}
} else {
bind._piece = Shader::SMP_whole;
if (transpose) {
bind._piece = Shader::SMP_transpose;
} else {
bind._piece = Shader::SMP_whole;
}
}
bind._arg[0] = NULL;
bind._arg[1] = NULL;
@ -281,49 +289,34 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
if (matrix_name == "ModelViewProjectionMatrix") {
if (inverse) {
bind._part[0] = Shader::SMO_apiclip_to_view;
bind._part[1] = Shader::SMO_view_to_model;
bind._part[0] = Shader::SMO_apiclip_to_apiview;
bind._part[1] = Shader::SMO_apiview_to_model;
} else {
bind._part[0] = Shader::SMO_model_to_view;
bind._part[1] = Shader::SMO_view_to_apiclip;
bind._part[0] = Shader::SMO_model_to_apiview;
bind._part[1] = Shader::SMO_apiview_to_apiclip;
}
} else if (matrix_name == "ModelViewMatrix") {
if (inverse) {
bind._part[0] = Shader::SMO_apiview_to_view;
bind._part[1] = Shader::SMO_view_to_model;
} else {
bind._part[0] = Shader::SMO_model_to_view;
bind._part[1] = Shader::SMO_view_to_apiview;
}
bind._func = Shader::SMF_first;
bind._part[0] = inverse ? Shader::SMO_apiview_to_model
: Shader::SMO_model_to_apiview;
bind._part[1] = Shader::SMO_identity;
} else if (matrix_name == "ProjectionMatrix") {
if (inverse) {
bind._part[0] = Shader::SMO_apiclip_to_view;
bind._part[1] = Shader::SMO_view_to_apiview;
} else {
bind._part[0] = Shader::SMO_apiview_to_view;
bind._part[1] = Shader::SMO_view_to_apiclip;
}
bind._func = Shader::SMF_first;
bind._part[0] = inverse ? Shader::SMO_apiclip_to_apiview
: Shader::SMO_apiview_to_apiclip;
bind._part[1] = Shader::SMO_identity;
} else if (matrix_name == "NormalMatrix") {
// This is really the upper 3x3 of the ModelViewMatrixInverseTranspose.
if (inverse) {
bind._part[0] = Shader::SMO_model_to_view;
bind._part[1] = Shader::SMO_view_to_apiview;
} else {
bind._part[0] = Shader::SMO_apiview_to_view;
bind._part[1] = Shader::SMO_view_to_model;
}
bind._func = Shader::SMF_first;
bind._part[0] = inverse ? Shader::SMO_model_to_apiview
: Shader::SMO_apiview_to_model;
bind._part[1] = Shader::SMO_identity;
if (param_type != GL_FLOAT_MAT3) {
GLCAT.error() << "p3d_NormalMatrix input should be mat3, not mat4!\n";
} else {
if (transpose) {
bind._piece = Shader::SMP_upper3x3;
} else {
bind._piece = Shader::SMP_transpose3x3;
}
}
} else if (matrix_name == "ModelMatrix") {

View File

@ -278,6 +278,15 @@ ConfigVariableBool gl_support_shadow_filter
"cards suffered from a broken implementation of the "
"shadow map filtering features."));
ConfigVariableEnum<CoordinateSystem> gl_coordinate_system
("gl-coordinate-system", CS_yup_right,
PRC_DESC("Which coordinate system to use as the internal "
"coordinate system for OpenGL operations. If you are "
"using features like fixed-function sphere mapping, it is "
"best to leave this to yup-right. However, if you are "
"creating a shader-only application, it may be easier and "
"more efficient to set this to default."));
extern ConfigVariableBool gl_parallel_arrays;
void CLP(init_classes)() {

View File

@ -17,6 +17,7 @@
#include "configVariableInt.h"
#include "configVariableEnum.h"
#include "geomEnums.h"
#include "coordinateSystem.h"
// Define some macros to transparently map to the double or float
// versions of the OpenGL function names.
@ -76,6 +77,7 @@ extern ConfigVariableBool gl_vertex_array_objects;
extern ConfigVariableBool gl_support_primitive_restart_index;
extern ConfigVariableBool gl_support_sampler_objects;
extern ConfigVariableBool gl_support_shadow_filter;
extern ConfigVariableEnum<CoordinateSystem> gl_coordinate_system;
extern EXPCL_GL void CLP(init_classes)();

View File

@ -483,6 +483,43 @@ cp_optimize_mat_spec(ShaderMatSpec &spec) {
spec._part[0] = spec._part[1];
spec._arg[0] = spec._arg[1];
}
// More optimal combinations for common matrices.
if (spec._part[0] == SMO_model_to_view &&
spec._part[1] == SMO_view_to_apiclip) {
spec._part[0] = SMO_model_to_apiview;
spec._part[1] = SMO_apiview_to_apiclip;
} else if (spec._part[0] == SMO_apiclip_to_view &&
spec._part[1] == SMO_view_to_model) {
spec._part[0] = SMO_apiclip_to_apiview;
spec._part[1] = SMO_apiview_to_model;
} else if (spec._part[0] == SMO_apiview_to_view &&
spec._part[1] == SMO_view_to_apiclip) {
spec._func = SMF_first;
spec._part[0] = SMO_apiview_to_apiclip;
spec._part[1] = SMO_identity;
} else if (spec._part[0] == SMO_apiclip_to_view &&
spec._part[1] == SMO_view_to_apiview) {
spec._func = SMF_first;
spec._part[0] = SMO_apiclip_to_apiview;
spec._part[1] = SMO_identity;
} else if (spec._part[0] == SMO_apiview_to_view &&
spec._part[1] == SMO_view_to_model) {
spec._func = SMF_first;
spec._part[0] = SMO_apiview_to_model;
spec._part[1] = SMO_identity;
} else if (spec._part[0] == SMO_model_to_view &&
spec._part[1] == SMO_view_to_apiview) {
spec._func = SMF_first;
spec._part[0] = SMO_model_to_apiview;
spec._part[1] = SMO_identity;
}
}
// Calculate state and transform dependencies.

View File

@ -186,6 +186,11 @@ public:
// SMO_clipplane_x is world coords, GLSL needs eye coords
SMO_apiview_clipplane_i,
SMO_model_to_apiview,
SMO_apiview_to_model,
SMO_apiview_to_apiclip,
SMO_apiclip_to_apiview,
SMO_INVALID
};