diff --git a/panda/src/glstuff/glCgShaderContext_src.cxx b/panda/src/glstuff/glCgShaderContext_src.cxx index fc1dac82ca..3a9b2fea6a 100644 --- a/panda/src/glstuff/glCgShaderContext_src.cxx +++ b/panda/src/glstuff/glCgShaderContext_src.cxx @@ -885,17 +885,21 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) { _glgsg->enable_vertex_attrib_array(p); - if (bind._integer) { - _glgsg->_glVertexAttribIPointer(p, num_values, type, - stride, client_pointer); - } else if (numeric_type == GeomEnums::NT_packed_dabc) { + if (numeric_type == GeomEnums::NT_packed_dabc) { // GL_BGRA is a special accepted value available since OpenGL 3.2. // It requires us to pass GL_TRUE for normalized. _glgsg->_glVertexAttribPointer(p, GL_BGRA, GL_UNSIGNED_BYTE, GL_TRUE, stride, client_pointer); - } else { + } else if (bind._numeric_type == Shader::SPT_float || + numeric_type == GeomEnums::NT_float32) { _glgsg->_glVertexAttribPointer(p, num_values, type, normalized, stride, client_pointer); + } else if (bind._numeric_type == Shader::SPT_double) { + _glgsg->_glVertexAttribLPointer(p, num_values, type, + stride, client_pointer); + } else { + _glgsg->_glVertexAttribIPointer(p, num_values, type, + stride, client_pointer); } if (divisor > 0) { @@ -952,10 +956,12 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) { // So, we work around this by just binding something silly to 0. // This breaks flat colors, but it's better than invisible objects? _glgsg->enable_vertex_attrib_array(0); - if (bind._integer) { - _glgsg->_glVertexAttribIPointer(0, 4, GL_INT, 0, 0); - } else { + if (bind._numeric_type == Shader::SPT_float) { _glgsg->_glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); + } else if (bind._numeric_type == Shader::SPT_double) { + _glgsg->_glVertexAttribLPointer(0, 4, GL_DOUBLE, 0, 0); + } else { + _glgsg->_glVertexAttribIPointer(0, 4, GL_INT, 0, 0); } } else if (p >= 0) { diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 979c6dada1..a96a07a2e8 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -426,18 +426,34 @@ reflect_attribute(int i, char *name_buffer, GLsizei name_buflen) { bind._elements = 1; // Check if this is an integer input- if so, we have to bind it differently. - bind._integer = (param_type == GL_BOOL || - param_type == GL_BOOL_VEC2 || - param_type == GL_BOOL_VEC3 || - param_type == GL_BOOL_VEC4 || - param_type == GL_INT || - param_type == GL_INT_VEC2 || - param_type == GL_INT_VEC3 || - param_type == GL_INT_VEC4 || - param_type == GL_UNSIGNED_INT_VEC2 || - param_type == GL_UNSIGNED_INT_VEC3 || - param_type == GL_UNSIGNED_INT_VEC4 || - param_type == GL_UNSIGNED_INT); + switch (param_type) { + case GL_INT: + case GL_INT_VEC2: + case GL_INT_VEC3: + case GL_INT_VEC4: + bind._numeric_type = Shader::SPT_int; + break; + case GL_BOOL: + case GL_BOOL_VEC2: + case GL_BOOL_VEC3: + case GL_BOOL_VEC4: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_VEC2: + case GL_UNSIGNED_INT_VEC3: + case GL_UNSIGNED_INT_VEC4: + bind._numeric_type = Shader::SPT_uint; + break; +#ifndef OPENGLES + case GL_DOUBLE: + case GL_DOUBLE_VEC2: + case GL_DOUBLE_VEC3: + case GL_DOUBLE_VEC4: + bind._numeric_type = Shader::SPT_double; + break; +#endif + default: + bind._numeric_type = Shader::SPT_float; + } // Check if it has a p3d_ prefix - if so, assign special meaning. if (strncmp(name_buffer, "p3d_", 4) == 0) { @@ -2264,7 +2280,7 @@ disable_shader_vertex_arrays() { return; } - for (int i=0; i<(int)_shader->_var_spec.size(); i++) { + for (size_t i = 0; i < _shader->_var_spec.size(); ++i) { const Shader::ShaderVarSpec &bind = _shader->_var_spec[i]; GLint p = bind._id._seqno; @@ -2389,21 +2405,25 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) { } client_pointer += start; + GLenum type = _glgsg->get_numeric_type(numeric_type); for (int i = 0; i < num_elements; ++i) { _glgsg->enable_vertex_attrib_array(p); - if (bind._integer) { - _glgsg->_glVertexAttribIPointer(p, num_values, _glgsg->get_numeric_type(numeric_type), - stride, client_pointer); - } else if (numeric_type == GeomEnums::NT_packed_dabc) { + if (numeric_type == GeomEnums::NT_packed_dabc) { // GL_BGRA is a special accepted value available since OpenGL 3.2. // It requires us to pass GL_TRUE for normalized. _glgsg->_glVertexAttribPointer(p, GL_BGRA, GL_UNSIGNED_BYTE, GL_TRUE, stride, client_pointer); - } else { - _glgsg->_glVertexAttribPointer(p, num_values, - _glgsg->get_numeric_type(numeric_type), + } else if (bind._numeric_type == Shader::SPT_float || + numeric_type == GeomEnums::NT_float32) { + _glgsg->_glVertexAttribPointer(p, num_values, type, normalized, stride, client_pointer); + } else if (bind._numeric_type == Shader::SPT_double) { + _glgsg->_glVertexAttribLPointer(p, num_values, type, + stride, client_pointer); + } else { + _glgsg->_glVertexAttribIPointer(p, num_values, type, + stride, client_pointer); } if (divisor > 0) { diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 22a5389b8b..220bd56ed2 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -619,12 +619,29 @@ cg_recurse_parameters(CGparameter parameter, const ShaderType &type, p._type = arg_type; p._direction = arg_dir; p._varying = (vbl == CG_VARYING); - p._integer = (base_type == CG_UINT || base_type == CG_INT || - base_type == CG_ULONG || base_type == CG_LONG || - base_type == CG_USHORT || base_type == CG_SHORT || - base_type == CG_UCHAR || base_type == CG_CHAR); p._cat = shader_cat.get_safe_ptr(); + //NB. Cg does have a CG_DOUBLE type, but at least for the ARB + // profiles and GLSL profiles it just maps to float. + switch (base_type) { + case CG_UINT: + case CG_ULONG: + case CG_USHORT: + case CG_UCHAR: + case CG_BOOL: + p._numeric_type = SPT_uint; + break; + case CG_INT: + case CG_LONG: + case CG_SHORT: + case CG_CHAR: + p._numeric_type = SPT_int; + break; + default: + p._numeric_type = SPT_float; + break; + } + success &= compile_parameter(p, arg_dim); break; } @@ -681,7 +698,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { ShaderVarSpec bind; bind._id = p._id; bind._append_uv = -1; - bind._integer = p._integer; + bind._numeric_type = p._numeric_type; if (pieces.size() == 2) { if (pieces[1] == "position") { diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index 1cc6533044..99b8d45e53 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -331,6 +331,14 @@ public: int _seqno; }; + enum ShaderPtrType { + SPT_float, + SPT_double, + SPT_int, + SPT_uint, + SPT_unknown + }; + struct ShaderArgInfo { ShaderArgId _id; ShaderArgClass _class; @@ -338,18 +346,10 @@ public: ShaderArgType _type; ShaderArgDir _direction; bool _varying; - bool _integer; + ShaderPtrType _numeric_type; NotifyCategory *_cat; }; - enum ShaderPtrType { - SPT_float, - SPT_double, - SPT_int, - SPT_uint, - SPT_unknown - }; - // Container structure for data of parameters ShaderPtrSpec. struct ShaderPtrData { private: @@ -425,7 +425,7 @@ public: PT(InternalName) _name; int _append_uv; int _elements; - bool _integer; + ShaderPtrType _numeric_type; }; struct ShaderPtrSpec {