From: Mikko Rasa Date: Sun, 21 Mar 2021 15:28:59 +0000 (+0200) Subject: Rearrange vertex attributes X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=68b74ce23dd20822b07d79dc25aa0a0a19ef27a5;p=libs%2Fgl.git Rearrange vertex attributes Since fixed function is no longer supported, I don't have to care what attribute number Nvidia gives the fixed function attributes. The old layout had weird holes and made custom attributes hard to add; now the free attributes are neatly at the end. The duality between standard and generic attributes has been removed. User-defined attributes now have their own range. No deprecated versions have been kept since they would be difficult to support properly. --- diff --git a/blender/io_mspgl/export_mesh.py b/blender/io_mspgl/export_mesh.py index 974685b3..a6501bc6 100644 --- a/blender/io_mspgl/export_mesh.py +++ b/blender/io_mspgl/export_mesh.py @@ -75,7 +75,7 @@ class MeshExporter: st.append(Token("TANGENT3")) st.append(Token("BINORMAL3")) if mesh.vertex_groups: - st.append(Token("ATTRIB{}_5".format(mesh.max_groups_per_vertex*2))) + st.append(Token("GENERIC{}_0".format(mesh.max_groups_per_vertex*2))) st.append(Token("VERTEX3")) normal = None @@ -107,7 +107,7 @@ class MeshExporter: group_attr.append((0, 0.0)) group_attr = list(itertools.chain(*group_attr)) if group_attr!=group: - st.sub.append(Statement("attrib", 5, *group_attr)) + st.sub.append(Statement("generic", 0, *group_attr)) group = group_attr st.sub.append(Statement("vertex", *v.co)) diff --git a/shaderlib/msp_interface.glsl b/shaderlib/msp_interface.glsl index e20e36dd..2458b97d 100644 --- a/shaderlib/msp_interface.glsl +++ b/shaderlib/msp_interface.glsl @@ -38,12 +38,15 @@ uniform Clipping #pragma MSP stage(vertex) layout(location=0) in vec4 vertex; -layout(location=8) in vec4 texcoord; -layout(location=3) in vec4 color; +layout(location=1) in vec4 color; layout(location=2) in vec3 normal; -layout(location=4) in vec3 tangent; -layout(location=5) in vec3 binormal; -layout(location=12) in vec4 instance_transform[3]; +layout(location=3) in vec3 tangent; +layout(location=4) in vec3 binormal; +layout(location=7) in vec4 texcoord; +layout(location=8) in vec4 texcoord1; +layout(location=9) in vec4 texcoord2; +layout(location=10) in vec4 texcoord3; +layout(location=13) in vec4 instance_transform[3]; #pragma MSP stage(fragment) layout(location=0) out vec4 frag_color; diff --git a/source/builders/vertexbuilder.h b/source/builders/vertexbuilder.h index 6c360572..b5278045 100644 --- a/source/builders/vertexbuilder.h +++ b/source/builders/vertexbuilder.h @@ -140,17 +140,20 @@ public: void color(const Color &c) { attrib(get_attribute_semantic(COLOR4_FLOAT), Vector4(c.r, c.g, c.b, c.a)); } - void attrib(unsigned i, float x) - { attrib(i, x, 0, 0, 1); } + void generic(unsigned i, float x) + { generic(i, x, 0, 0, 1); } - void attrib(unsigned i, float x, float y) - { attrib(i, x, y, 0, 1); } + void generic(unsigned i, float x, float y) + { generic(i, x, y, 0, 1); } - void attrib(unsigned i, float x, float y, float z) - { attrib(i, x, y, z, 1); } + void generic(unsigned i, float x, float y, float z) + { generic(i, x, y, z, 1); } - void attrib(unsigned i, float x, float y, float z, float w) - { attrib(i, Vector4(x, y, z, w)); } + void generic(unsigned i, float x, float y, float z, float w) + { generic(i, Vector4(x, y, z, w)); } + + void generic(unsigned i, const Vector4 &a) + { attrib(get_attribute_semantic(GENERIC4)+i, a); } }; } // namespace GL diff --git a/source/core/vertexarray.cpp b/source/core/vertexarray.cpp index 0703b1dd..712e76e6 100644 --- a/source/core/vertexarray.cpp +++ b/source/core/vertexarray.cpp @@ -70,10 +70,10 @@ VertexArray::Loader::Loader(VertexArray &a): add("multitexcoord", static_cast(&Loader::multitexcoord)); add("color", static_cast(&Loader::color)); add("color", static_cast(&Loader::color)); - add("attrib", static_cast(&Loader::attrib)); - add("attrib", static_cast(&Loader::attrib)); - add("attrib", static_cast(&Loader::attrib)); - add("attrib", static_cast(&Loader::attrib)); + add("generic", static_cast(&Loader::generic)); + add("generic", static_cast(&Loader::generic)); + add("generic", static_cast(&Loader::generic)); + add("generic", static_cast(&Loader::generic)); add("tangent", static_cast(&Loader::tangent)); add("binormal", static_cast(&Loader::binormal)); @@ -91,10 +91,10 @@ VertexArray::Loader::Loader(VertexArray &a): add("multitexcoord4", static_cast(&Loader::multitexcoord)); add("color3", static_cast(&Loader::color)); add("color4", static_cast(&Loader::color)); - add("attrib1", static_cast(&Loader::attrib)); - add("attrib2", static_cast(&Loader::attrib)); - add("attrib3", static_cast(&Loader::attrib)); - add("attrib4", static_cast(&Loader::attrib)); + add("generic1", static_cast(&Loader::generic)); + add("generic2", static_cast(&Loader::generic)); + add("generic3", static_cast(&Loader::generic)); + add("generic4", static_cast(&Loader::generic)); add("tangent3", static_cast(&Loader::tangent)); add("binormal3", static_cast(&Loader::binormal)); } diff --git a/source/core/vertexformat.cpp b/source/core/vertexformat.cpp index 05364be8..5d026e2e 100644 --- a/source/core/vertexformat.cpp +++ b/source/core/vertexformat.cpp @@ -3,7 +3,9 @@ #include #include #include "error.h" +#include "misc.h" #include "vertexformat.h" +#include using namespace std; @@ -82,19 +84,25 @@ int VertexFormat::offset(VertexAttribute attr) const VertexAttribute make_indexed_attribute(VertexAttribute attr, unsigned index) { + unsigned base = attr; if(attr>=TEXCOORD1 && attr<=TEXCOORD4) { if(index>=4) throw out_of_range("make_indexed_attribute"); } - else if(attr>=ATTRIB1 && attr<=ATTRIB4) - { - if(index>=24) - throw out_of_range("make_indexed_attribute"); - } - else + else if(attr>=RAW_ATTRIB1 && attr<=RAW_ATTRIB4) + base &= 7; + else if(attrGENERIC4) throw invalid_argument("make_indexed_attribute"); - return static_cast(attr+index*4); + + static int max_attribs = -1; + if(max_attribs<0) + max_attribs = get_i(GL_MAX_VERTEX_ATTRIBS); + + if(static_cast((base>>3)+index)>=max_attribs) + throw out_of_range("make_indexed_attribute"); + + return static_cast(base+index*8); } void operator>>(const LexicalConverter &conv, VertexAttribute &a) @@ -116,23 +124,23 @@ void operator>>(const LexicalConverter &conv, VertexAttribute &a) { if(str.size()==9) a = static_cast(TEXCOORD1+(str[8]-'1')); - else if(str.size()==11 && str[9]=='_' && str[10]>='0' && str[10]<='7') - a = static_cast(TEXCOORD1+(str[8]-'1')+(str[10]-'0')*4); + else if(str.size()==11 && str[9]=='_' && str[10]>='0' && str[10]<='3') + a = make_indexed_attribute(static_cast(TEXCOORD1+(str[8]-'1')), str[10]-'0'); else throw lexical_error(format("conversion of '%s' to VertexAttribute", str)); } - else if(str.size()>=9 && !str.compare(0, 6, "ATTRIB") && str[6]>='1' && str[6]<='4' && str[7]=='_') + else if(str.size()>=10 && !str.compare(0, 6, "GENERIC") && str[7]>='1' && str[7]<='4' && str[8]=='_') { unsigned n; try { - n = lexical_cast(str.substr(8)); + n = lexical_cast(str.substr(9)); } catch(const lexical_error &) { throw lexical_error(format("conversion of '%s' to VertexAttribute", str)); } - a = static_cast(ATTRIB1+(str[6]-'1')+n*4); + a = make_indexed_attribute(static_cast(GENERIC1+(str[7]-'1')), n); } else throw lexical_error(format("conversion of '%s' to VertexAttribute", str)); diff --git a/source/core/vertexformat.h b/source/core/vertexformat.h index 3317a015..93794c35 100644 --- a/source/core/vertexformat.h +++ b/source/core/vertexformat.h @@ -7,28 +7,39 @@ namespace Msp { namespace GL { -/** A single vertex component. Symbolic names are provided for commonly used -attributes. These are aliased with with generic attributes, so be careful when -picking your attribute indices. */ +/** A single vertex attribute. Commonly used attributes are named by their +semantical meaning in the standard shaders. Texture coordinates and generic +attributes can additionally be given an index. There are four texture +coordinate attributes available. The number of available generic attributes +depends on implementation limits, but is at least five. + +RAW_ATTRIB is handled in a special way; creating an indexed attribute based on +it uses the index as raw attribute number. Only use it if you know what you +are doing. */ enum VertexAttribute { VERTEX2 = 1, VERTEX3, VERTEX4, - NORMAL3 = 10, - COLOR4_UBYTE = 12, - COLOR3_FLOAT = 14, + COLOR4_UBYTE = 8, + COLOR3_FLOAT = 10, COLOR4_FLOAT, - TANGENT3 = 18, - BINORMAL3 = 22, - TEXCOORD1 = 32, + NORMAL3 = 18, + TANGENT3 = 26, + BINORMAL3 = 34, + // Attributes 5 and 6 reserved for vertex groups and weights + TEXCOORD1 = 56, TEXCOORD2, TEXCOORD3, TEXCOORD4, - ATTRIB1 = 64, - ATTRIB2, - ATTRIB3, - ATTRIB4 + GENERIC1 = 88, + GENERIC2, + GENERIC3, + GENERIC4, + RAW_ATTRIB1 = 248, + RAW_ATTRIB2, + RAW_ATTRIB3, + RAW_ATTRIB4 }; DEPRECATED typedef VertexAttribute VertexComponent; @@ -69,7 +80,7 @@ DEPRECATED inline VertexAttribute make_indexed_component(VertexAttribute a, unsi { return make_indexed_attribute(a, i); } inline unsigned get_attribute_semantic(unsigned char a) -{ return a>>2; } +{ return a>>3; } inline unsigned get_attribute_size(unsigned char a) { return (a&3)+1; } diff --git a/source/core/vertexsetup.cpp b/source/core/vertexsetup.cpp index 6a41397a..0cbe9a92 100644 --- a/source/core/vertexsetup.cpp +++ b/source/core/vertexsetup.cpp @@ -80,12 +80,7 @@ unsigned VertexSetup::get_attribs(const VertexFormat &fmt) { unsigned mask = 0; for(const unsigned char *a=fmt.begin(); a!=fmt.end(); ++a) - { - unsigned sem = get_attribute_semantic(*a); - if(sem>=get_attribute_semantic(ATTRIB1)) - sem -= get_attribute_semantic(ATTRIB1); - mask |= 1<=get_attribute_semantic(ATTRIB1)) - sem -= get_attribute_semantic(ATTRIB1); unsigned sz = get_attribute_size(*a); if(direct) { diff --git a/source/render/instancearray.cpp b/source/render/instancearray.cpp index 028af3ad..bef6ec17 100644 --- a/source/render/instancearray.cpp +++ b/source/render/instancearray.cpp @@ -44,9 +44,9 @@ InstanceArray::InstanceArray(const Object &o): if(ARB_vertex_array_object && ARB_instanced_arrays && ARB_draw_instanced) { - instance_data = new VertexArray((ATTRIB4,matrix_location, ATTRIB4,matrix_location+1, ATTRIB4,matrix_location+2)); + instance_data = new VertexArray((RAW_ATTRIB4,matrix_location, RAW_ATTRIB4,matrix_location+1, RAW_ATTRIB4,matrix_location+2)); const VertexFormat &fmt = instance_data->get_format(); - matrix_offset = fmt.offset(make_indexed_attribute(ATTRIB4, matrix_location)); + matrix_offset = fmt.offset(make_indexed_attribute(RAW_ATTRIB4, matrix_location)); instance_buffer = new Buffer(ARRAY_BUFFER); instance_data->use_buffer(instance_buffer);