mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
Add support for k_time / osg_FrameTime inputs, and change the Shader Generator not to require a separate texcoord set for every texture in an effort to cut down on register overuse.
This commit is contained in:
parent
89749133ff
commit
4da840805f
@ -996,6 +996,16 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
|
||||
0.0);
|
||||
return &t;
|
||||
}
|
||||
case Shader::SMO_frame_time: {
|
||||
PN_stdfloat time = ClockObject::get_global_clock()->get_frame_time();
|
||||
t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time);
|
||||
return &t;
|
||||
}
|
||||
case Shader::SMO_frame_delta: {
|
||||
PN_stdfloat dt = ClockObject::get_global_clock()->get_dt();
|
||||
t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt);
|
||||
return &t;
|
||||
}
|
||||
case Shader::SMO_texpad_x: {
|
||||
Texture *tex = _target_shader->get_shader_input_texture(name);
|
||||
nassertr(tex != 0, &LMatrix4::zeros_mat());
|
||||
|
@ -71,14 +71,13 @@ TypeHandle CLP(ShaderContext)::_type_handle;
|
||||
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");
|
||||
@ -119,9 +118,9 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, Shader *objSha
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("clip");
|
||||
}
|
||||
|
||||
if ((pieces[0] == "mat")||(pieces[0] == "inv")||
|
||||
(pieces[0] == "tps")||(pieces[0] == "itp")) {
|
||||
|
||||
if ((pieces[0] == "mat") || (pieces[0] == "inv") ||
|
||||
(pieces[0] == "tps") || (pieces[0] == "itp")) {
|
||||
if (!objShader->cp_errchk_parameter_words(p, 2)) {
|
||||
return false;
|
||||
}
|
||||
@ -138,33 +137,33 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, Shader *objSha
|
||||
objShader->cp_report_error(p,"unrecognized matrix name");
|
||||
return false;
|
||||
}
|
||||
if (trans=="mat") {
|
||||
if (trans == "mat") {
|
||||
pieces[0] = "trans";
|
||||
} else if (trans=="inv") {
|
||||
} else if (trans == "inv") {
|
||||
string t = pieces[1];
|
||||
pieces[1] = pieces[3];
|
||||
pieces[3] = t;
|
||||
} else if (trans=="tps") {
|
||||
} else if (trans == "tps") {
|
||||
pieces[0] = "tpose";
|
||||
} else if (trans=="itp") {
|
||||
} 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")) {
|
||||
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;
|
||||
@ -174,27 +173,26 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, Shader *objSha
|
||||
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 (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;
|
||||
}
|
||||
@ -338,7 +336,7 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
||||
}
|
||||
bind._arg[0] = NULL;
|
||||
bind._arg[1] = NULL;
|
||||
|
||||
|
||||
if (matrix_name == "ModelViewProjectionMatrix") {
|
||||
bind._func = Shader::SMF_compose;
|
||||
if (inverse) {
|
||||
@ -418,15 +416,14 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
||||
// them as well, to increase compatibility.
|
||||
// Other inputs we may support in the future:
|
||||
// int osg_FrameNumber
|
||||
// float osg_FrameTime
|
||||
// float osg_DeltaFrameTime
|
||||
|
||||
Shader::ShaderMatSpec bind;
|
||||
bind._id = arg_id;
|
||||
bind._arg[0] = NULL;
|
||||
bind._arg[1] = NULL;
|
||||
|
||||
if (param_name == "osg_ViewMatrix") {
|
||||
Shader::ShaderMatSpec bind;
|
||||
bind._id = arg_id;
|
||||
bind._piece = Shader::SMP_whole;
|
||||
bind._arg[0] = NULL;
|
||||
bind._arg[1] = NULL;
|
||||
bind._func = Shader::SMF_first;
|
||||
bind._part[0] = Shader::SMO_world_to_view;
|
||||
bind._part[1] = Shader::SMO_identity;
|
||||
@ -436,11 +433,7 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
||||
continue;
|
||||
|
||||
} else if (param_name == "osg_InverseViewMatrix") {
|
||||
Shader::ShaderMatSpec bind;
|
||||
bind._id = arg_id;
|
||||
bind._piece = Shader::SMP_whole;
|
||||
bind._arg[0] = NULL;
|
||||
bind._arg[1] = NULL;
|
||||
bind._func = Shader::SMF_first;
|
||||
bind._part[0] = Shader::SMO_view_to_world;
|
||||
bind._part[1] = Shader::SMO_identity;
|
||||
@ -448,6 +441,26 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
||||
bind._dep[1] = Shader::SSD_NONE;
|
||||
s->_mat_spec.push_back(bind);
|
||||
continue;
|
||||
|
||||
} else if (param_name == "osg_FrameTime") {
|
||||
bind._piece = Shader::SMP_row3x1;
|
||||
bind._func = Shader::SMF_first;
|
||||
bind._part[0] = Shader::SMO_frame_time;
|
||||
bind._part[1] = Shader::SMO_identity;
|
||||
bind._dep[0] = Shader::SSD_general;
|
||||
bind._dep[1] = Shader::SSD_NONE;
|
||||
s->_mat_spec.push_back(bind);
|
||||
continue;
|
||||
|
||||
} else if (param_name == "osg_DeltaFrameTime") {
|
||||
bind._piece = Shader::SMP_row3x1;
|
||||
bind._func = Shader::SMF_first;
|
||||
bind._part[0] = Shader::SMO_frame_delta;
|
||||
bind._part[1] = Shader::SMO_identity;
|
||||
bind._dep[0] = Shader::SSD_general;
|
||||
bind._dep[1] = Shader::SSD_NONE;
|
||||
s->_mat_spec.push_back(bind);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,7 +468,7 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
||||
if (parse_and_set_short_hand_shader_vars(arg_id, s)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (param_size == 1) {
|
||||
switch (param_type) {
|
||||
#ifndef OPENGLES
|
||||
@ -706,7 +719,7 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gsg->report_my_gl_errors();
|
||||
}
|
||||
|
||||
@ -1162,12 +1175,13 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
InternalName *name = _shader->_var_spec[i]._name;
|
||||
int texslot = _shader->_var_spec[i]._append_uv;
|
||||
if (texslot >= 0 && texslot < gsg->_state_texture->get_num_on_stages()) {
|
||||
TextureStage *stage = gsg->_state_texture->get_on_stage(texslot);
|
||||
InternalName *texname = stage->get_texcoord_name();
|
||||
|
||||
if (name == InternalName::get_texcoord()) {
|
||||
name = texname;
|
||||
} else if (texname != InternalName::get_texcoord()) {
|
||||
|
@ -414,23 +414,23 @@ cp_dependency(ShaderMatInput inp) {
|
||||
(inp == SMO_view_to_model)) {
|
||||
dep |= SSD_transform;
|
||||
}
|
||||
if ((inp == SMO_texpad_x)||
|
||||
(inp == SMO_texpix_x)||
|
||||
(inp == SMO_alight_x)||
|
||||
(inp == SMO_dlight_x)||
|
||||
(inp == SMO_plight_x)||
|
||||
(inp == SMO_slight_x)||
|
||||
(inp == SMO_satten_x)||
|
||||
(inp == SMO_mat_constant_x)||
|
||||
(inp == SMO_vec_constant_x)||
|
||||
(inp == SMO_clipplane_x)||
|
||||
(inp == SMO_view_x_to_view)||
|
||||
(inp == SMO_view_to_view_x)||
|
||||
(inp == SMO_apiview_x_to_view)||
|
||||
(inp == SMO_view_to_apiview_x)||
|
||||
(inp == SMO_clip_x_to_view)||
|
||||
(inp == SMO_view_to_clip_x)||
|
||||
(inp == SMO_apiclip_x_to_view)||
|
||||
if ((inp == SMO_texpad_x) ||
|
||||
(inp == SMO_texpix_x) ||
|
||||
(inp == SMO_alight_x) ||
|
||||
(inp == SMO_dlight_x) ||
|
||||
(inp == SMO_plight_x) ||
|
||||
(inp == SMO_slight_x) ||
|
||||
(inp == SMO_satten_x) ||
|
||||
(inp == SMO_mat_constant_x) ||
|
||||
(inp == SMO_vec_constant_x) ||
|
||||
(inp == SMO_clipplane_x) ||
|
||||
(inp == SMO_view_x_to_view) ||
|
||||
(inp == SMO_view_to_view_x) ||
|
||||
(inp == SMO_apiview_x_to_view) ||
|
||||
(inp == SMO_view_to_apiview_x) ||
|
||||
(inp == SMO_clip_x_to_view) ||
|
||||
(inp == SMO_view_to_clip_x) ||
|
||||
(inp == SMO_apiclip_x_to_view) ||
|
||||
(inp == SMO_view_to_apiclip_x)) {
|
||||
dep |= SSD_shaderinputs;
|
||||
}
|
||||
@ -588,36 +588,45 @@ compile_parameter(const ShaderArgId &arg_id,
|
||||
}
|
||||
ShaderVarSpec bind;
|
||||
bind._id = arg_id;
|
||||
bind._append_uv = -1;
|
||||
|
||||
if (pieces.size() == 2) {
|
||||
if (pieces[1]=="position") {
|
||||
if (pieces[1] == "position") {
|
||||
bind._name = InternalName::get_vertex();
|
||||
bind._append_uv = -1;
|
||||
_var_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
if (pieces[1].substr(0,8)=="texcoord") {
|
||||
if (pieces[1].substr(0, 8) == "texcoord") {
|
||||
bind._name = InternalName::get_texcoord();
|
||||
bind._append_uv = atoi(pieces[1].c_str()+8);
|
||||
if (pieces[1].size() > 8) {
|
||||
bind._append_uv = atoi(pieces[1].c_str() + 8);
|
||||
}
|
||||
_var_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
if (pieces[1].substr(0,7)=="tangent") {
|
||||
if (pieces[1].substr(0, 7) == "tangent") {
|
||||
bind._name = InternalName::get_tangent();
|
||||
bind._append_uv = atoi(pieces[1].c_str()+7);
|
||||
if (pieces[1].size() > 7) {
|
||||
bind._append_uv = atoi(pieces[1].c_str() + 7);
|
||||
}
|
||||
_var_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
if (pieces[1].substr(0,8)=="binormal") {
|
||||
if (pieces[1].substr(0, 8) == "binormal") {
|
||||
bind._name = InternalName::get_binormal();
|
||||
bind._append_uv = atoi(pieces[1].c_str()+8);
|
||||
if (pieces[1].size() > 8) {
|
||||
bind._append_uv = atoi(pieces[1].c_str() + 8);
|
||||
}
|
||||
_var_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bind._name = InternalName::get_root();
|
||||
bind._append_uv = -1;
|
||||
for (int i=1; i<(int)(pieces.size()-0); i++)
|
||||
for (int i = 1; i < pieces.size(); ++i) {
|
||||
bind._name = bind._name->append(pieces[i]);
|
||||
}
|
||||
_var_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
@ -1008,7 +1017,7 @@ compile_parameter(const ShaderArgId &arg_id,
|
||||
// Keywords to access unusual parameters.
|
||||
|
||||
if (pieces[0] == "sys") {
|
||||
if ((!cp_errchk_parameter_words(p,2)) ||
|
||||
if ((!cp_errchk_parameter_words(p, 2)) ||
|
||||
(!cp_errchk_parameter_in(p)) ||
|
||||
(!cp_errchk_parameter_uniform(p))) {
|
||||
return false;
|
||||
@ -1025,14 +1034,24 @@ compile_parameter(const ShaderArgId &arg_id,
|
||||
}
|
||||
bind._part[0] = SMO_pixel_size;
|
||||
bind._arg[0] = NULL;
|
||||
|
||||
} else if (pieces[1] == "windowsize") {
|
||||
if (!cp_errchk_parameter_float(p, 2, 2)) {
|
||||
return false;
|
||||
}
|
||||
bind._part[0] = SMO_window_size;
|
||||
bind._arg[0] = NULL;
|
||||
|
||||
} else if (pieces[1] == "time") {
|
||||
if (!cp_errchk_parameter_float(p, 1, 1)) {
|
||||
return false;
|
||||
}
|
||||
bind._piece = SMP_row3x1;
|
||||
bind._part[0] = SMO_frame_time;
|
||||
bind._arg[0] = NULL;
|
||||
|
||||
} else {
|
||||
cp_report_error(p,"unknown system parameter");
|
||||
cp_report_error(p, "unknown system parameter");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "pta_LVecBase2.h"
|
||||
|
||||
#ifdef HAVE_CG
|
||||
// I don't want to include the Cg header file into panda as a
|
||||
// I don't want to include the Cg header file into panda as a
|
||||
// whole. Instead, I'll just excerpt some opaque declarations.
|
||||
typedef struct _CGcontext *CGcontext;
|
||||
typedef struct _CGprogram *CGprogram;
|
||||
@ -40,8 +40,8 @@ typedef struct _CGparameter *CGparameter;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Shader
|
||||
// Summary: The Shader class is meant to select the Shader Language,
|
||||
// select the available profile, compile the shader, and
|
||||
// finally compile and store the shader parameters
|
||||
// select the available profile, compile the shader, and
|
||||
// finally compile and store the shader parameters
|
||||
// in the appropriate structure.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_GOBJ Shader : public TypedWritableReferenceCount {
|
||||
@ -115,11 +115,11 @@ public:
|
||||
SMO_pixel_size,
|
||||
SMO_texpad_x,
|
||||
SMO_texpix_x,
|
||||
|
||||
|
||||
SMO_attr_material,
|
||||
SMO_attr_color,
|
||||
SMO_attr_colorscale,
|
||||
|
||||
|
||||
SMO_alight_x,
|
||||
SMO_dlight_x,
|
||||
SMO_plight_x,
|
||||
@ -128,7 +128,7 @@ public:
|
||||
SMO_texmat_x,
|
||||
SMO_plane_x,
|
||||
SMO_clipplane_x,
|
||||
|
||||
|
||||
SMO_mat_constant_x,
|
||||
SMO_vec_constant_x,
|
||||
|
||||
@ -146,7 +146,7 @@ public:
|
||||
|
||||
SMO_apiclip_to_view,
|
||||
SMO_view_to_apiclip,
|
||||
|
||||
|
||||
SMO_view_x_to_view,
|
||||
SMO_view_to_view_x,
|
||||
|
||||
@ -161,11 +161,15 @@ public:
|
||||
|
||||
SMO_attr_fog,
|
||||
SMO_attr_fogcolor,
|
||||
|
||||
|
||||
SMO_frame_number,
|
||||
SMO_frame_time,
|
||||
SMO_frame_delta,
|
||||
|
||||
SMO_INVALID
|
||||
};
|
||||
|
||||
enum ShaderArgClass {
|
||||
|
||||
enum ShaderArgClass {
|
||||
SAC_scalar,
|
||||
SAC_vector,
|
||||
SAC_matrix,
|
||||
@ -173,28 +177,28 @@ public:
|
||||
SAC_array,
|
||||
SAC_unknown,
|
||||
};
|
||||
|
||||
enum ShaderArgType {
|
||||
SAT_scalar,
|
||||
SAT_vec1,
|
||||
SAT_vec2,
|
||||
SAT_vec3,
|
||||
SAT_vec4,
|
||||
SAT_mat1x1,
|
||||
SAT_mat1x2,
|
||||
SAT_mat1x3,
|
||||
|
||||
enum ShaderArgType {
|
||||
SAT_scalar,
|
||||
SAT_vec1,
|
||||
SAT_vec2,
|
||||
SAT_vec3,
|
||||
SAT_vec4,
|
||||
SAT_mat1x1,
|
||||
SAT_mat1x2,
|
||||
SAT_mat1x3,
|
||||
SAT_mat1x4,
|
||||
SAT_mat2x1,
|
||||
SAT_mat2x2,
|
||||
SAT_mat2x3,
|
||||
SAT_mat2x4,
|
||||
SAT_mat3x1,
|
||||
SAT_mat3x2,
|
||||
SAT_mat3x3,
|
||||
SAT_mat3x4,
|
||||
SAT_mat4x1,
|
||||
SAT_mat4x2,
|
||||
SAT_mat4x3,
|
||||
SAT_mat2x2,
|
||||
SAT_mat2x3,
|
||||
SAT_mat2x4,
|
||||
SAT_mat3x1,
|
||||
SAT_mat3x2,
|
||||
SAT_mat3x3,
|
||||
SAT_mat3x4,
|
||||
SAT_mat4x1,
|
||||
SAT_mat4x2,
|
||||
SAT_mat4x3,
|
||||
SAT_mat4x4,
|
||||
SAT_sampler1d,
|
||||
SAT_sampler2d,
|
||||
@ -230,20 +234,20 @@ public:
|
||||
};
|
||||
|
||||
enum ShaderStateDep {
|
||||
SSD_NONE = 0,
|
||||
SSD_general = 1,
|
||||
SSD_transform = 2,
|
||||
SSD_color = 4,
|
||||
SSD_colorscale = 8,
|
||||
SSD_material = 16,
|
||||
SSD_shaderinputs = 32,
|
||||
SSD_fog = 64,
|
||||
SSD_NONE = 0x000,
|
||||
SSD_general = 0x001,
|
||||
SSD_transform = 0x002,
|
||||
SSD_color = 0x004,
|
||||
SSD_colorscale = 0x008,
|
||||
SSD_material = 0x010,
|
||||
SSD_shaderinputs = 0x020,
|
||||
SSD_fog = 0x040,
|
||||
};
|
||||
|
||||
enum ShaderBug {
|
||||
SBUG_ati_draw_buffers,
|
||||
};
|
||||
|
||||
|
||||
enum ShaderMatFunc {
|
||||
SMF_compose,
|
||||
SMF_transform_dlight,
|
||||
@ -251,36 +255,36 @@ public:
|
||||
SMF_transform_slight,
|
||||
SMF_first,
|
||||
};
|
||||
|
||||
|
||||
struct ShaderArgId {
|
||||
string _name;
|
||||
ShaderType _type;
|
||||
int _seqno;
|
||||
};
|
||||
|
||||
struct ShaderArgInfo {
|
||||
};
|
||||
|
||||
struct ShaderArgInfo {
|
||||
ShaderArgId _id;
|
||||
ShaderArgClass _class;
|
||||
ShaderArgClass _subclass;
|
||||
ShaderArgType _type;
|
||||
ShaderArgType _type;
|
||||
ShaderArgDir _direction;
|
||||
bool _varying;
|
||||
NotifyCategory *_cat;
|
||||
};
|
||||
|
||||
|
||||
enum ShaderPtrType {
|
||||
SPT_float,
|
||||
SPT_double,
|
||||
SPT_unknown
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
// Container structure for data of parameters ShaderPtrSpec.
|
||||
struct ShaderPtrData {
|
||||
private:
|
||||
PT(ReferenceCount) _pta;
|
||||
|
||||
public:
|
||||
void *_ptr;
|
||||
void *_ptr;
|
||||
ShaderPtrType _type;
|
||||
bool _updated;
|
||||
int _size; //number of elements vec3[4]=12
|
||||
@ -339,8 +343,8 @@ public:
|
||||
PT(InternalName) _name;
|
||||
int _append_uv;
|
||||
};
|
||||
|
||||
struct ShaderPtrSpec {
|
||||
|
||||
struct ShaderPtrSpec {
|
||||
ShaderArgId _id;
|
||||
int _dim[3]; //n_elements,rows,cols
|
||||
int _dep[2];
|
||||
@ -376,8 +380,8 @@ public:
|
||||
public:
|
||||
INLINE ShaderFile() {};
|
||||
INLINE ShaderFile(const string &shared);
|
||||
INLINE ShaderFile(const string &vertex,
|
||||
const string &fragment,
|
||||
INLINE ShaderFile(const string &vertex,
|
||||
const string &fragment,
|
||||
const string &geometry,
|
||||
const string &tess_control,
|
||||
const string &tess_evaluation);
|
||||
@ -404,18 +408,18 @@ public:
|
||||
void parse_upto(string &result, string pattern, bool include);
|
||||
void parse_rest(string &result);
|
||||
bool parse_eof();
|
||||
|
||||
|
||||
void cp_report_error(ShaderArgInfo &arg, const string &msg);
|
||||
bool cp_errchk_parameter_words(ShaderArgInfo &arg, int len);
|
||||
bool cp_errchk_parameter_in(ShaderArgInfo &arg);
|
||||
bool cp_errchk_parameter_ptr(ShaderArgInfo &p);
|
||||
bool cp_errchk_parameter_ptr(ShaderArgInfo &p);
|
||||
bool cp_errchk_parameter_varying(ShaderArgInfo &arg);
|
||||
bool cp_errchk_parameter_uniform(ShaderArgInfo &arg);
|
||||
bool cp_errchk_parameter_float(ShaderArgInfo &arg, int lo, int hi);
|
||||
bool cp_errchk_parameter_sampler(ShaderArgInfo &arg);
|
||||
bool cp_parse_eol(ShaderArgInfo &arg,
|
||||
vector_string &pieces, int &next);
|
||||
bool cp_parse_delimiter(ShaderArgInfo &arg,
|
||||
bool cp_parse_delimiter(ShaderArgInfo &arg,
|
||||
vector_string &pieces, int &next);
|
||||
string cp_parse_non_delimiter(vector_string &pieces, int &next);
|
||||
bool cp_parse_coord_sys(ShaderArgInfo &arg,
|
||||
@ -425,12 +429,12 @@ public:
|
||||
void cp_optimize_mat_spec(ShaderMatSpec &spec);
|
||||
|
||||
#ifdef HAVE_CG
|
||||
void cg_recurse_parameters(CGparameter parameter,
|
||||
const ShaderType &type,
|
||||
void cg_recurse_parameters(CGparameter parameter,
|
||||
const ShaderType &type,
|
||||
bool &success);
|
||||
#endif
|
||||
|
||||
bool compile_parameter(const ShaderArgId &arg_id,
|
||||
|
||||
bool compile_parameter(const ShaderArgId &arg_id,
|
||||
const ShaderArgClass &arg_class,
|
||||
const ShaderArgClass &arg_subclass,
|
||||
const ShaderArgType &arg_type,
|
||||
@ -443,7 +447,7 @@ public:
|
||||
|
||||
#ifdef HAVE_CG
|
||||
private:
|
||||
ShaderArgClass cg_parameter_class(CGparameter p);
|
||||
ShaderArgClass cg_parameter_class(CGparameter p);
|
||||
ShaderArgType cg_parameter_type(CGparameter p);
|
||||
ShaderArgDir cg_parameter_dir(CGparameter p);
|
||||
|
||||
@ -455,7 +459,7 @@ private:
|
||||
bool cg_compile_shader(const ShaderCaps &caps);
|
||||
void cg_release_resources();
|
||||
void cg_report_errors();
|
||||
|
||||
|
||||
// Determines the appropriate cg profile settings and stores them in the active shader caps
|
||||
// based on any profile settings stored in the shader's header
|
||||
void cg_get_profile_from_header(ShaderCaps &caps);
|
||||
@ -477,24 +481,24 @@ public:
|
||||
bool cg_compile_for(const ShaderCaps &caps, CGcontext &ctx,
|
||||
CGprogram &vprogram, CGprogram &fprogram,
|
||||
CGprogram &gprogram, pvector<CGparameter> &map);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
public:
|
||||
pvector <ShaderPtrSpec> _ptr_spec;
|
||||
pvector <ShaderPtrSpec> _ptr_spec;
|
||||
epvector <ShaderMatSpec> _mat_spec;
|
||||
pvector <ShaderTexSpec> _tex_spec;
|
||||
pvector <ShaderVarSpec> _var_spec;
|
||||
|
||||
|
||||
bool _error_flag;
|
||||
CPT(ShaderFile) _text;
|
||||
|
||||
protected:
|
||||
CPT(ShaderFile) _filename;
|
||||
CPT(ShaderFile) _filename;
|
||||
int _parse;
|
||||
bool _loaded;
|
||||
ShaderLanguage _language;
|
||||
|
||||
|
||||
static ShaderCaps _default_caps;
|
||||
static ShaderUtilization _shader_utilization;
|
||||
static int _shaders_generated;
|
||||
@ -510,7 +514,7 @@ protected:
|
||||
typedef pmap <PreparedGraphicsObjects *, ShaderContext *> Contexts;
|
||||
Contexts _contexts;
|
||||
|
||||
private:
|
||||
private:
|
||||
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
|
||||
|
||||
Shader();
|
||||
|
@ -622,15 +622,13 @@ synthesize_shader(const RenderState *rs) {
|
||||
|
||||
// These variables will hold the results of register allocation.
|
||||
|
||||
char *ntangent_vreg = 0;
|
||||
char *ntangent_freg = 0;
|
||||
char *nbinormal_vreg = 0;
|
||||
char *nbinormal_freg = 0;
|
||||
char *htangent_vreg = 0;
|
||||
char *hbinormal_vreg = 0;
|
||||
pvector<char *> texcoord_freg;
|
||||
pvector<char *> dlightcoord_freg;
|
||||
pvector<char *> slightcoord_freg;
|
||||
char *tangent_freg = 0;
|
||||
char *binormal_freg = 0;
|
||||
string tangent_input;
|
||||
string binormal_input;
|
||||
pmap<const InternalName *, char *> texcoord_fregs;
|
||||
pvector<char *> dlightcoord_fregs;
|
||||
pvector<char *> slightcoord_fregs;
|
||||
char *world_position_freg = 0;
|
||||
char *world_normal_freg = 0;
|
||||
char *eye_position_freg = 0;
|
||||
@ -659,11 +657,39 @@ synthesize_shader(const RenderState *rs) {
|
||||
for (int i = 0; i < _num_textures; ++i) {
|
||||
TextureStage *stage = texture->get_on_stage(i);
|
||||
if (!tex_gen->has_stage(stage)) {
|
||||
texcoord_freg.push_back(alloc_freg());
|
||||
text << "\t in float4 vtx_texcoord" << i << " : " << alloc_vreg() << ",\n";
|
||||
text << "\t out float4 l_texcoord" << i << " : " << texcoord_freg[i] << ",\n";
|
||||
} else {
|
||||
texcoord_freg.push_back(NULL);
|
||||
const InternalName *texcoord_name = stage->get_texcoord_name();
|
||||
|
||||
if (texcoord_fregs.count(texcoord_name) == 0) {
|
||||
char *freg = alloc_freg();
|
||||
string tcname = texcoord_name->join("_");
|
||||
texcoord_fregs[texcoord_name] = freg;
|
||||
|
||||
text << "\t in float4 vtx_" << tcname << " : " << alloc_vreg() << ",\n";
|
||||
text << "\t out float4 l_" << tcname << " : " << freg << ",\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ((_map_index_normal == i && _lighting && _auto_normal_on) || _map_index_height == i) {
|
||||
const InternalName *texcoord_name = stage->get_texcoord_name();
|
||||
PT(InternalName) tangent_name = InternalName::get_tangent();
|
||||
PT(InternalName) binormal_name = InternalName::get_binormal();
|
||||
|
||||
if (texcoord_name != InternalName::get_texcoord()) {
|
||||
tangent_name = tangent_name->append(texcoord_name->get_basename());
|
||||
binormal_name = binormal_name->append(texcoord_name->get_basename());
|
||||
}
|
||||
tangent_input = tangent_name->join("_");
|
||||
binormal_input = binormal_name->join("_");
|
||||
|
||||
text << "\t in float4 vtx_" << tangent_input << " : " << alloc_vreg() << ",\n";
|
||||
text << "\t in float4 vtx_" << binormal_input << " : " << alloc_vreg() << ",\n";
|
||||
|
||||
if (_map_index_normal == i && _lighting && _auto_normal_on) {
|
||||
tangent_freg = alloc_freg();
|
||||
binormal_freg = alloc_freg();
|
||||
text << "\t out float4 l_tangent : " << tangent_freg << ",\n";
|
||||
text << "\t out float4 l_binormal : " << binormal_freg << ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_vertex_colors) {
|
||||
@ -695,49 +721,27 @@ synthesize_shader(const RenderState *rs) {
|
||||
text << "\t in float4 vtx_normal : NORMAL,\n";
|
||||
}
|
||||
if (_map_index_height >= 0) {
|
||||
htangent_vreg = alloc_vreg();
|
||||
hbinormal_vreg = alloc_vreg();
|
||||
if (_map_index_normal == _map_index_height) {
|
||||
ntangent_vreg = htangent_vreg;
|
||||
nbinormal_vreg = hbinormal_vreg;
|
||||
}
|
||||
text << "\t in float4 vtx_tangent" << _map_index_height << " : " << htangent_vreg << ",\n";
|
||||
text << "\t in float4 vtx_binormal" << _map_index_height << " : " << hbinormal_vreg << ",\n";
|
||||
text << "\t uniform float4 mspos_view,\n";
|
||||
text << "\t out float3 l_eyevec,\n";
|
||||
}
|
||||
if (_lighting) {
|
||||
if (_map_index_normal >= 0 && _auto_normal_on) {
|
||||
// If we had a height map and it used the same stage, that means we already have those inputs.
|
||||
if (_map_index_normal != _map_index_height) {
|
||||
ntangent_vreg = alloc_vreg();
|
||||
nbinormal_vreg = alloc_vreg();
|
||||
// NB. If we used TANGENT and BINORMAL, Cg would have them overlap with TEXCOORD6-7.
|
||||
text << "\t in float4 vtx_tangent" << _map_index_normal << " : " << ntangent_vreg << ",\n";
|
||||
text << "\t in float4 vtx_binormal" << _map_index_normal << " : " << nbinormal_vreg << ",\n";
|
||||
}
|
||||
ntangent_freg = alloc_freg();
|
||||
nbinormal_freg = alloc_freg();
|
||||
text << "\t out float4 l_tangent : " << ntangent_freg << ",\n";
|
||||
text << "\t out float4 l_binormal : " << nbinormal_freg << ",\n";
|
||||
}
|
||||
if (_shadows && _auto_shadow_on) {
|
||||
for (int i=0; i < (int)_dlights.size(); i++) {
|
||||
if (_dlights[i]->_shadow_caster) {
|
||||
dlightcoord_freg.push_back(alloc_freg());
|
||||
dlightcoord_fregs.push_back(alloc_freg());
|
||||
text << "\t uniform float4x4 trans_model_to_clip_of_dlight" << i << ",\n";
|
||||
text << "\t out float4 l_dlightcoord" << i << " : " << dlightcoord_freg[i] << ",\n";
|
||||
text << "\t out float4 l_dlightcoord" << i << " : " << dlightcoord_fregs[i] << ",\n";
|
||||
} else {
|
||||
dlightcoord_freg.push_back(NULL);
|
||||
dlightcoord_fregs.push_back(NULL);
|
||||
}
|
||||
}
|
||||
for (int i=0; i < (int)_slights.size(); i++) {
|
||||
if (_slights[i]->_shadow_caster) {
|
||||
slightcoord_freg.push_back(alloc_freg());
|
||||
slightcoord_fregs.push_back(alloc_freg());
|
||||
text << "\t uniform float4x4 trans_model_to_clip_of_slight" << i << ",\n";
|
||||
text << "\t out float4 l_slightcoord" << i << " : " << slightcoord_freg[i] << ",\n";
|
||||
text << "\t out float4 l_slightcoord" << i << " : " << slightcoord_fregs[i] << ",\n";
|
||||
} else {
|
||||
slightcoord_freg.push_back(NULL);
|
||||
slightcoord_fregs.push_back(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -768,18 +772,19 @@ synthesize_shader(const RenderState *rs) {
|
||||
text << "\t l_eye_normal.xyz = mul((float3x3)tpose_view_to_model, vtx_normal.xyz);\n";
|
||||
text << "\t l_eye_normal.w = 0;\n";
|
||||
}
|
||||
for (int i = 0; i < _num_textures; ++i) {
|
||||
if (!tex_gen->has_stage(texture->get_on_stage(i))) {
|
||||
text << "\t l_texcoord" << i << " = vtx_texcoord" << i << ";\n";
|
||||
}
|
||||
pmap<const InternalName *, char *>::const_iterator it;
|
||||
for (it = texcoord_fregs.begin(); it != texcoord_fregs.end(); ++it) {
|
||||
// Pass through all texcoord inputs as-is.
|
||||
string tcname = it->first->join("_");
|
||||
text << "\t l_" << tcname << " = vtx_" << tcname << ";\n";
|
||||
}
|
||||
if (_vertex_colors) {
|
||||
text << "\t l_color = vtx_color;\n";
|
||||
}
|
||||
if (_lighting && (_map_index_normal >= 0 && _auto_normal_on)) {
|
||||
text << "\t l_tangent.xyz = mul((float3x3)tpose_view_to_model, vtx_tangent" << _map_index_normal << ".xyz);\n";
|
||||
text << "\t l_tangent.xyz = mul((float3x3)tpose_view_to_model, vtx_" << tangent_input << ".xyz);\n";
|
||||
text << "\t l_tangent.w = 0;\n";
|
||||
text << "\t l_binormal.xyz = mul((float3x3)tpose_view_to_model, -vtx_binormal" << _map_index_normal << ".xyz);\n";
|
||||
text << "\t l_binormal.xyz = mul((float3x3)tpose_view_to_model, -vtx_" << binormal_input << ".xyz);\n";
|
||||
text << "\t l_binormal.w = 0;\n";
|
||||
}
|
||||
if (_shadows && _auto_shadow_on) {
|
||||
@ -824,22 +829,22 @@ synthesize_shader(const RenderState *rs) {
|
||||
if (_need_eye_normal) {
|
||||
text << "\t in float4 l_eye_normal : " << eye_normal_freg << ",\n";
|
||||
}
|
||||
for (it = texcoord_fregs.begin(); it != texcoord_fregs.end(); ++it) {
|
||||
text << "\t in float4 l_" << it->first->join("_") << " : " << it->second << ",\n";
|
||||
}
|
||||
const TexMatrixAttrib *tex_matrix = DCAST(TexMatrixAttrib, rs->get_attrib_def(TexMatrixAttrib::get_class_slot()));
|
||||
for (int i=0; i<_num_textures; i++) {
|
||||
TextureStage *stage = texture->get_on_stage(i);
|
||||
Texture *tex = texture->get_on_texture(stage);
|
||||
nassertr(tex != NULL, NULL);
|
||||
text << "\t uniform sampler" << texture_type_as_string(tex->get_texture_type()) << " tex_" << i << ",\n";
|
||||
if (!tex_gen->has_stage(stage)) {
|
||||
text << "\t in float4 l_texcoord" << i << " : " << texcoord_freg[i] << ",\n";
|
||||
}
|
||||
if (tex_matrix->has_stage(stage)) {
|
||||
text << "\t uniform float4x4 texmat_" << i << ",\n";
|
||||
}
|
||||
}
|
||||
if (_lighting && (_map_index_normal >= 0 && _auto_normal_on)) {
|
||||
text << "\t in float3 l_tangent : " << ntangent_freg << ",\n";
|
||||
text << "\t in float3 l_binormal : " << nbinormal_freg << ",\n";
|
||||
text << "\t in float3 l_tangent : " << tangent_freg << ",\n";
|
||||
text << "\t in float3 l_binormal : " << binormal_freg << ",\n";
|
||||
}
|
||||
if (_lighting) {
|
||||
for (int i=0; i < (int)_alights.size(); i++) {
|
||||
@ -853,7 +858,7 @@ synthesize_shader(const RenderState *rs) {
|
||||
} else {
|
||||
text << "\t uniform sampler2D k_dlighttex" << i << ",\n";
|
||||
}
|
||||
text << "\t in float4 l_dlightcoord" << i << " : " << dlightcoord_freg[i] << ",\n";
|
||||
text << "\t in float4 l_dlightcoord" << i << " : " << dlightcoord_fregs[i] << ",\n";
|
||||
}
|
||||
}
|
||||
for (int i=0; i < (int)_plights.size(); i++) {
|
||||
@ -868,7 +873,7 @@ synthesize_shader(const RenderState *rs) {
|
||||
} else {
|
||||
text << "\t uniform sampler2D k_slighttex" << i << ",\n";
|
||||
}
|
||||
text << "\t in float4 l_slightcoord" << i << " : " << slightcoord_freg[i] << ",\n";
|
||||
text << "\t in float4 l_slightcoord" << i << " : " << slightcoord_fregs[i] << ",\n";
|
||||
}
|
||||
}
|
||||
if (_need_material_props) {
|
||||
@ -916,26 +921,30 @@ synthesize_shader(const RenderState *rs) {
|
||||
if (tex_gen != NULL && tex_gen->has_stage(stage)) {
|
||||
switch (tex_gen->get_mode(stage)) {
|
||||
case TexGenAttrib::M_world_position:
|
||||
text << "\t float4 l_texcoord" << i << " = l_world_position;\n";
|
||||
text << "\t float4 texcoord" << i << " = l_world_position;\n";
|
||||
break;
|
||||
case TexGenAttrib::M_world_normal:
|
||||
text << "\t float4 l_texcoord" << i << " = l_world_normal;\n";
|
||||
text << "\t float4 texcoord" << i << " = l_world_normal;\n";
|
||||
break;
|
||||
case TexGenAttrib::M_eye_position:
|
||||
text << "\t float4 l_texcoord" << i << " = l_eye_position;\n";
|
||||
text << "\t float4 texcoord" << i << " = l_eye_position;\n";
|
||||
break;
|
||||
case TexGenAttrib::M_eye_normal:
|
||||
text << "\t float4 l_texcoord" << i << " = l_eye_normal;\n";
|
||||
text << "\t l_texcoord" << i << ".w = 1.0f;\n";
|
||||
text << "\t float4 texcoord" << i << " = l_eye_normal;\n";
|
||||
text << "\t texcoord" << i << ".w = 1.0f;\n";
|
||||
break;
|
||||
default:
|
||||
pgraph_cat.error() << "Unsupported TexGenAttrib mode\n";
|
||||
text << "\t float4 l_texcoord" << i << " = float4(0, 0, 0, 0);\n";
|
||||
text << "\t float4 texcoord" << i << " = float4(0, 0, 0, 0);\n";
|
||||
}
|
||||
} else {
|
||||
// Cg seems to be able to optimize this temporary away when appropriate.
|
||||
const InternalName *texcoord_name = stage->get_texcoord_name();
|
||||
text << "\t float4 texcoord" << i << " = l_" << texcoord_name->join("_") << ";\n";
|
||||
}
|
||||
if (tex_matrix != NULL && tex_matrix->has_stage(stage)) {
|
||||
text << "\t l_texcoord" << i << " = mul(texmat_" << i << ", l_texcoord" << i << ");\n";
|
||||
text << "\t l_texcoord" << i << ".xyz /= l_texcoord" << i << ".w;\n";
|
||||
text << "\t texcoord" << i << " = mul(texmat_" << i << ", texcoord" << i << ");\n";
|
||||
text << "\t texcoord" << i << ".xyz /= texcoord" << i << ".w;\n";
|
||||
}
|
||||
}
|
||||
text << "\t // Fetch all textures.\n";
|
||||
@ -943,7 +952,7 @@ synthesize_shader(const RenderState *rs) {
|
||||
Texture *tex = texture->get_on_texture(texture->get_on_stage(_map_index_height));
|
||||
nassertr(tex != NULL, NULL);
|
||||
text << "\t float4 tex" << _map_index_height << " = tex" << texture_type_as_string(tex->get_texture_type());
|
||||
text << "(tex_" << _map_index_height << ", l_texcoord" << _map_index_height << ".";
|
||||
text << "(tex_" << _map_index_height << ", texcoord" << _map_index_height << ".";
|
||||
switch (tex->get_texture_type()) {
|
||||
case Texture::TT_cube_map:
|
||||
case Texture::TT_3d_texture:
|
||||
@ -983,21 +992,21 @@ synthesize_shader(const RenderState *rs) {
|
||||
nassertr(tex != NULL, NULL);
|
||||
// Parallax mapping pushes the texture coordinates of the other textures away from the camera.
|
||||
if (_map_index_height >= 0 && parallax_mapping_samples > 0) {
|
||||
text << "\t l_texcoord" << i << ".xyz -= parallax_offset;\n";
|
||||
text << "\t texcoord" << i << ".xyz -= parallax_offset;\n";
|
||||
}
|
||||
text << "\t float4 tex" << i << " = tex" << texture_type_as_string(tex->get_texture_type());
|
||||
text << "(tex_" << i << ", l_texcoord" << i << ".";
|
||||
text << "(tex_" << i << ", texcoord" << i << ".";
|
||||
switch(tex->get_texture_type()) {
|
||||
case Texture::TT_cube_map:
|
||||
case Texture::TT_3d_texture:
|
||||
case Texture::TT_2d_texture_array:
|
||||
text << "xyz";
|
||||
text << "xyz";
|
||||
break;
|
||||
case Texture::TT_2d_texture:
|
||||
case Texture::TT_2d_texture:
|
||||
text << "xy";
|
||||
break;
|
||||
case Texture::TT_1d_texture:
|
||||
text << "x";
|
||||
case Texture::TT_1d_texture:
|
||||
text << "x";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1240,7 +1249,7 @@ synthesize_shader(const RenderState *rs) {
|
||||
} else if (_flat_colors) {
|
||||
text << "\t result = attr_color;\n";
|
||||
} else {
|
||||
text << "\t result = float4(1,1,1,1);\n";
|
||||
text << "\t result = float4(1, 1, 1, 1);\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,8 +86,8 @@ protected:
|
||||
int _vtregs_used;
|
||||
int _ftregs_used;
|
||||
void reset_register_allocator();
|
||||
INLINE char *alloc_vreg();
|
||||
INLINE char *alloc_freg();
|
||||
char *alloc_vreg();
|
||||
char *alloc_freg();
|
||||
|
||||
// RenderState analysis information. Created by analyze_renderstate:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user