mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
Added support for shorthand shaderinput lexicons like mspos_camshadow and
trans_model_to_clip_of_camshadow to GLSL.
This commit is contained in:
parent
4166327919
commit
3d05d84d87
@ -47,6 +47,164 @@ TypeHandle CLP(ShaderContext)::_type_handle;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::ParseAndSetShaderUniformVars
|
||||
// Access: Public
|
||||
// Description: The Panda CG shader syntax defines a useful set of shorthand notations for setting nodepath
|
||||
// properties as shaderinputs. For example, float4 mspos_XXX refers to nodepath XXX's position
|
||||
// in model space. This function is a rough attempt to reimplement some of the shorthand
|
||||
// notations for GLSL. The code is ~99% composed of excerpts dealing with matrix shaderinputs
|
||||
// from Shader::compile_parameter.
|
||||
//
|
||||
// Given a uniform variable name queried from the compiled shader passed in via arg_id,
|
||||
// 1) parse the name
|
||||
// 2a) if the name refers to a Panda shorthand notation
|
||||
// push the appropriate matrix into shader._mat_spec
|
||||
// returns True
|
||||
// 2b) If the name doesn't refer to a Panda shorthand notation
|
||||
// returns False
|
||||
//
|
||||
// The boolean return is used to notify down-river processing whether the shader var/parm was
|
||||
// actually picked up and the appropriate ShaderMatSpec pushed onto _mat_spec.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ShaderContext)::
|
||||
parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, Shader *objShader) {
|
||||
Shader::ShaderArgInfo p;
|
||||
|
||||
p._id = arg_id;
|
||||
|
||||
string basename(arg_id._name);
|
||||
// Split it at the underscores.
|
||||
vector_string pieces;
|
||||
tokenize(basename, pieces, "_");
|
||||
|
||||
if (pieces[0] == "mstrans") {
|
||||
pieces[0] = "trans";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("model");
|
||||
}
|
||||
if (pieces[0] == "wstrans") {
|
||||
pieces[0] = "trans";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("world");
|
||||
}
|
||||
if (pieces[0] == "vstrans") {
|
||||
pieces[0] = "trans";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("view");
|
||||
}
|
||||
if (pieces[0] == "cstrans") {
|
||||
pieces[0] = "trans";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("clip");
|
||||
}
|
||||
if (pieces[0] == "mspos") {
|
||||
pieces[0] = "row3";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("model");
|
||||
}
|
||||
if (pieces[0] == "wspos") {
|
||||
pieces[0] = "row3";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("world");
|
||||
}
|
||||
if (pieces[0] == "vspos") {
|
||||
pieces[0] = "row3";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("view");
|
||||
}
|
||||
if (pieces[0] == "cspos") {
|
||||
pieces[0] = "row3";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("clip");
|
||||
}
|
||||
|
||||
if ((pieces[0] == "mat")||(pieces[0] == "inv")||
|
||||
(pieces[0] == "tps")||(pieces[0] == "itp")) {
|
||||
if (!objShader->cp_errchk_parameter_words(p, 2)) {
|
||||
return false;
|
||||
}
|
||||
string trans = pieces[0];
|
||||
string matrix = pieces[1];
|
||||
pieces.clear();
|
||||
if (matrix == "modelview") {
|
||||
tokenize("trans_model_to_apiview", pieces, "_");
|
||||
} else if (matrix == "projection") {
|
||||
tokenize("trans_apiview_to_apiclip", pieces, "_");
|
||||
} else if (matrix == "modelproj") {
|
||||
tokenize("trans_model_to_apiclip", pieces, "_");
|
||||
} else {
|
||||
objShader->cp_report_error(p,"unrecognized matrix name");
|
||||
return false;
|
||||
}
|
||||
if (trans=="mat") {
|
||||
pieces[0] = "trans";
|
||||
} else if (trans=="inv") {
|
||||
string t = pieces[1];
|
||||
pieces[1] = pieces[3];
|
||||
pieces[3] = t;
|
||||
} else if (trans=="tps") {
|
||||
pieces[0] = "tpose";
|
||||
} else if (trans=="itp") {
|
||||
string t = pieces[1];
|
||||
pieces[1] = pieces[3];
|
||||
pieces[3] = t;
|
||||
pieces[0] = "tpose";
|
||||
}
|
||||
}
|
||||
// Implement the transform-matrix generator.
|
||||
|
||||
if ((pieces[0]=="trans")||
|
||||
(pieces[0]=="tpose")||
|
||||
(pieces[0]=="row0")||
|
||||
(pieces[0]=="row1")||
|
||||
(pieces[0]=="row2")||
|
||||
(pieces[0]=="row3")||
|
||||
(pieces[0]=="col0")||
|
||||
(pieces[0]=="col1")||
|
||||
(pieces[0]=="col2")||
|
||||
(pieces[0]=="col3")) {
|
||||
|
||||
Shader::ShaderMatSpec bind;
|
||||
bind._id = arg_id;
|
||||
bind._func = Shader::SMF_compose;
|
||||
|
||||
int next = 1;
|
||||
pieces.push_back("");
|
||||
|
||||
// Decide whether this is a matrix or vector.
|
||||
if (pieces[0]=="trans") bind._piece = Shader::SMP_whole;
|
||||
else if (pieces[0]=="tpose") bind._piece = Shader::SMP_transpose;
|
||||
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 (!objShader->cp_parse_coord_sys(p, pieces, next, bind, true)) {
|
||||
return false;
|
||||
}
|
||||
if (!objShader->cp_parse_delimiter(p, pieces, next)) {
|
||||
return false;
|
||||
}
|
||||
if (!objShader->cp_parse_coord_sys(p, pieces, next, bind, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!objShader->cp_parse_eol(p, pieces, next)) {
|
||||
return false;
|
||||
}
|
||||
objShader->cp_optimize_mat_spec(bind);
|
||||
objShader->_mat_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::Constructor
|
||||
// Access: Public
|
||||
@ -205,6 +363,11 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//Tries to parse shorthand notations like mspos_XXX and trans_model_to_clip_of_XXX
|
||||
if (parse_and_set_short_hand_shader_vars( arg_id, s )) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param_size==1) {
|
||||
switch (param_type) {
|
||||
#ifndef OPENGLES
|
||||
|
@ -76,7 +76,7 @@ private:
|
||||
void glsl_report_program_errors(GSG *gsg, unsigned int program);
|
||||
unsigned int glsl_compile_entry_point(GSG *gsg, Shader::ShaderType type);
|
||||
bool glsl_compile_shader(GSG *gsg);
|
||||
|
||||
bool parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, Shader *s);
|
||||
void release_resources(GSG *gsg);
|
||||
|
||||
public:
|
||||
|
@ -399,7 +399,7 @@ public:
|
||||
string _tess_evaluation;
|
||||
};
|
||||
|
||||
private:
|
||||
public:
|
||||
// These routines help split the shader into sections,
|
||||
// for those shader implementations that need to do so.
|
||||
// Don't use them when you use separate shader programs.
|
||||
|
Loading…
x
Reference in New Issue
Block a user