mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
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.
This commit is contained in:
parent
c99fe581d3
commit
ba388e2866
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
@ -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";
|
||||
|
||||
|
@ -87,7 +87,7 @@ private:
|
||||
pvector <CGparameter> _cg_parameter_map;
|
||||
#endif
|
||||
|
||||
LMatrix4 *_mat_part_cache = nullptr;
|
||||
LVecBase4f *_mat_part_cache = nullptr;
|
||||
|
||||
private:
|
||||
void release_resources(void);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ private:
|
||||
long _transform_table_size;
|
||||
long _slider_table_size;
|
||||
|
||||
LMatrix4 *_mat_part_cache = nullptr;
|
||||
LVecBase4f *_mat_part_cache = nullptr;
|
||||
pvector<CGparameter> _cg_parameter_map;
|
||||
|
||||
WCPT(RenderState) _state_rs;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ private:
|
||||
};
|
||||
pvector<ImageInput> _glsl_img_inputs;
|
||||
|
||||
LMatrix4 *_mat_part_cache = nullptr;
|
||||
LVecBase4f *_mat_part_cache = nullptr;
|
||||
|
||||
CLP(GraphicsStateGuardian) *_glgsg;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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]);
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user