]> git.tdb.fi Git - libs/gl.git/commitdiff
Standard vertex components for tangent and binormal vectors
authorMikko Rasa <tdb@tdb.fi>
Sun, 2 Sep 2012 18:11:56 +0000 (21:11 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 2 Sep 2012 18:11:56 +0000 (21:11 +0300)
This simplifies using normalmapped standard shaders, as the shader is
ready to use without the need to declare tangent and binormal attribute
indices.

13 files changed:
blender/io_mspgl/export_mesh.py
demos/shaders.cpp
source/box.cpp
source/capsule.cpp
source/cylinder.cpp
source/geometrybuilder.cpp
source/geometrybuilder.h
source/grid.cpp
source/programbuilder.cpp
source/vertexarray.cpp
source/vertexbuilder.h
source/vertexformat.cpp
source/vertexformat.h

index 135ed1098de2981c14899441485386f6cd6d0b63..3da09f9ab92d99cc918cf7375ed692e3f12aeb63 100644 (file)
@@ -294,7 +294,7 @@ class MeshExporter:
                                else:
                                        fmt.append("TEXCOORD2_%d"%u.unit)
                        if self.tbn_vecs:
-                               fmt += ["ATTRIB3_3", "ATTRIB3_4"]
+                               fmt += ["TANGENT3", "BINORMAL3"]
                if self.export_groups:
                        fmt.append("ATTRIB%d_5"%(self.max_groups*2))
                fmt.append("VERTEX3")
@@ -317,10 +317,10 @@ class MeshExporter:
                                        uvs[i] = v.uvs[i]
                        if self.tbn_vecs:
                                if v.tan!=tan:
-                                       out_file.write("attrib3", 3, *v.tan)
+                                       out_file.write("tangent3", *v.tan)
                                        tan = v.tan
                                if v.bino!=bino:
-                                       out_file.write("attrib3", 4, *v.bino)
+                                       out_file.write("binormal3", *v.bino)
                                        bino = v.bino
                        if self.export_groups:
                                group_attr = [(group_index_map[g.group], g.weight*v.group_weight_scale) for g in v.groups[:self.max_groups]]
index 73ae1b721321696ddc3114bfbb97676df16e00bd..872c3c160a746ed6aad39a4a76b266274577b749 100644 (file)
@@ -56,10 +56,10 @@ int main()
        tex2.image(0, GL::RGB, GL::UNSIGNED_BYTE, data);
        delete[] data;
 
-       GL::Mesh mesh((GL::VERTEX3, GL::NORMAL3, GL::TEXCOORD2, GL::COLOR4_UBYTE, GL::ATTRIB3,4, GL::ATTRIB3,5));
+       GL::Mesh mesh((GL::VERTEX3, GL::NORMAL3, GL::TEXCOORD2, GL::COLOR4_UBYTE, GL::TANGENT3, GL::BINORMAL3));
        GL::MeshBuilder bld(mesh);
        bld.color(0.5f, 1.0f, 0.0f);
-       GL::CapsuleBuilder(1, 0.72498, 32, 17).texture_fit(GL::GeometryBuilder::WRAP).tangent(4).binormal(5).build(bld);
+       GL::CapsuleBuilder(1, 0.72498, 32, 17).texture_fit(GL::GeometryBuilder::WRAP).tbn().build(bld);
        GL::Material mat;
        mat.set_diffuse(GL::Color(0.5, 1.0, 0.0));
        mat.set_specular(GL::Color(0.45, 0.5, 0.4));
@@ -74,12 +74,6 @@ int main()
                feat.normalmap = i%4>1;
                feat.specular = i%4>2;
                programs.push_back(new GL::Program(feat));
-               if(feat.normalmap)
-               {
-                       programs.back()->bind_attribute(4, "tangent");
-                       programs.back()->bind_attribute(5, "binormal");
-                       programs.back()->link();
-               }
        }
 
        GL::ProgramData progdata;
index 0958d1b0930daa8d187e6dc430b4a8ed0886bc1a..b20f0d04e98c237d6c96a1f99844f1898149d0e9 100644 (file)
@@ -36,15 +36,17 @@ void BoxBuilder::build(PrimitiveBuilder &builder) const
 void BoxBuilder::build_face(PrimitiveBuilder &builder, const Vector3 &o, const Vector3 &s1, const Vector3 &s2) const
 {
        float l1 = 1, l2 = 1;
-       if(tangent_attr>=0 || tex_fit!=STRETCH)
+       if(generate_tbn || tex_fit!=STRETCH)
+       {
                l1 = sqrt(s1.x*s1.x+s1.y*s1.y+s1.z*s1.z);
-       if(binormal_attr>=0 || tex_fit!=STRETCH)
                l2 = sqrt(s2.x*s2.x+s2.y*s2.y+s2.z*s2.z);
+       }
 
-       if(tangent_attr>=0)
-               builder.attrib(tangent_attr, s1.x/l1, s1.y/l1, s1.z/l1);
-       if(binormal_attr>=0)
-               builder.attrib(binormal_attr, s2.x/l2, s2.y/l2, s2.z/l2);
+       if(generate_tbn)
+       {
+               builder.tangent(s1.x/l1, s1.y/l1, s1.z/l1);
+               builder.binormal(s2.x/l2, s2.y/l2, s2.z/l2);
+       }
 
        float u_size = 1;
        float v_size = 1;
index 9553edd36cd3e907449d52425fb0342c07584d8c..f00f6ca2dc146bb661adf5b03697b880e0d81824 100644 (file)
@@ -42,10 +42,11 @@ void CapsuleBuilder::build(PrimitiveBuilder &builder) const
                        float sc = cos(sa);
                        float ss = sin(sa);
                        builder.normal(rs*sc, rs*ss, -rc);
-                       if(tangent_attr>=0)
-                               builder.attrib(tangent_attr, -ss, sc, 0);
-                       if(binormal_attr>=0)
-                               builder.attrib(binormal_attr, rc*sc, rc*ss, rs);
+                       if(generate_tbn)
+                       {
+                               builder.tangent(-ss, sc, 0);
+                               builder.binormal(rc*sc, rc*ss, rs);
+                       }
                        builder.texcoord(j*u_scale, v);
                        builder.vertex(rs*sc*radius, rs*ss*radius, cz-rc*radius);
                }
index bbc536d7696d484e426f7d016b10847786de261f..5ea99723e92793e5fdae052ce7df98fa7c5a84e0 100644 (file)
@@ -18,15 +18,15 @@ CylinderBuilder::CylinderBuilder(float r, float l, unsigned s):
 
 void CylinderBuilder::build(PrimitiveBuilder &builder) const
 {
-       if(binormal_attr>=0)
-               builder.attrib(binormal_attr, 0, 1, 0);
+       if(generate_tbn)
+               builder.binormal(0, 1, 0);
        for(unsigned i=0; i<2; ++i)
        {
                float z = (i-0.5)*length;
                builder.normal(0, 0, i*2.0-1.0);
                builder.texcoord(0.5, 0.5);
-               if(tangent_attr>=0)
-                       builder.attrib(tangent_attr, (i ? 1 : -1), 0, 0);
+               if(generate_tbn)
+                       builder.tangent((i ? 1 : -1), 0, 0);
                builder.vertex(0, 0, z);
                for(unsigned j=0; j<segments; ++j)
                {
@@ -42,8 +42,8 @@ void CylinderBuilder::build(PrimitiveBuilder &builder) const
        float v_scale = 1;
        adjust_texture_scale(u_scale, v_scale, radius*M_PI*2, length);
 
-       if(binormal_attr>=0)
-               builder.attrib(binormal_attr, 0, 0, 1);
+       if(generate_tbn)
+               builder.binormal(0, 0, 1);
        for(unsigned i=0; i<2; ++i)
        {
                float z = (i-0.5)*length;
@@ -54,8 +54,8 @@ void CylinderBuilder::build(PrimitiveBuilder &builder) const
                        float s = sin(a);
                        builder.normal(c, s, 0);
                        builder.texcoord(j*u_scale, i*v_scale);
-                       if(tangent_attr>=0)
-                               builder.attrib(tangent_attr, -s, c, 0);
+                       if(generate_tbn)
+                               builder.tangent(-s, c, 0);
                        builder.vertex(radius*c, radius*s, z);
                }
        }
index ba3e86004c5813dbe1649bc66cba5f475c6de61b..729b40facc1709ddecc794aa2637c65ac1bdd391 100644 (file)
@@ -5,20 +5,13 @@ namespace Msp {
 namespace GL {
 
 GeometryBuilder::GeometryBuilder():
-       tangent_attr(-1),
-       binormal_attr(-1),
+       generate_tbn(false),
        tex_fit(STRETCH)
 { }
 
-GeometryBuilder &GeometryBuilder::tangent(unsigned t)
+GeometryBuilder &GeometryBuilder::tbn(bool t)
 {
-       tangent_attr = t;
-       return *this;
-}
-
-GeometryBuilder &GeometryBuilder::binormal(unsigned b)
-{
-       binormal_attr = b;
+       generate_tbn = t;
        return *this;
 }
 
index 76c1ba2f603a670861768ebf9b4ff37be1352cc3..40bcd13e6b37b504d3c22ad3780ccce7a9b521b1 100644 (file)
@@ -18,15 +18,13 @@ public:
        };
 
 protected:
-       int tangent_attr;
-       int binormal_attr;
+       bool generate_tbn;
        TextureFit tex_fit;
 
        GeometryBuilder();
 
 public:
-       GeometryBuilder &tangent(unsigned);
-       GeometryBuilder &binormal(unsigned);
+       GeometryBuilder &tbn(bool = true);
        GeometryBuilder &texture_fit(TextureFit);
 protected:
        void adjust_texture_scale(float &, float &, float, float) const;
index 2f1a2a1ca6225a680f24227b2c2fdc0c96098fe2..aaeada8a73130e2ae2dccd4fb53c3da608731def 100644 (file)
@@ -88,10 +88,11 @@ void GridBuilder::build(PrimitiveBuilder &builder) const
        adjust_texture_scale(u_scale, v_scale, sqrt(l1_sq), l2);
 
        builder.normal(norm.x, norm.y, norm.z);
-       if(tangent_attr>=0)
-               builder.attrib(tangent_attr, side1.x, side1.y, side1.z);
-       if(binormal_attr>=0)
-               builder.attrib(tangent_attr, binorm.x, binorm.y, binorm.z);
+       if(generate_tbn)
+       {
+               builder.tangent(side1.x, side1.y, side1.z);
+               builder.binormal(binorm.x, binorm.y, binorm.z);
+       }
 
        for(unsigned j=0; j<=v_div; ++j)
        {
index a24b5d565c6687dc3a614c1834fb1026d262d681..4043fc4471648f6dec62d611c7cf07479548c545 100644 (file)
@@ -3,6 +3,7 @@
 #include "program.h"
 #include "programbuilder.h"
 #include "shader.h"
+#include "vertexformat.h"
 
 using namespace std;
 
@@ -182,6 +183,12 @@ void ProgramBuilder::add_shaders(Program &prog) const
 
        prog.attach_shader_owned(new VertexShader(create_source(resolved_vars, VERTEX)));
        prog.attach_shader_owned(new FragmentShader(create_source(resolved_vars, FRAGMENT)));
+
+       if(features.normalmap)
+       {
+               prog.bind_attribute(get_component_type(TANGENT3), "tangent");
+               prog.bind_attribute(get_component_type(BINORMAL3), "binormal");
+       }
 }
 
 string ProgramBuilder::create_source(const list<ShaderVariable *> &variables, VariableScope scope) const
index e91062bbda60b0f309f06c98effda44f6065eccd..79d6823135c75fe038f8dd7039a32edae6df7d46 100644 (file)
@@ -34,7 +34,7 @@ void VertexArray::reset(const VertexFormat &f)
        {
                if(*c>=TEXCOORD1+4 && *c<=TEXCOORD4+12)
                        has_multitex = true;
-               if(*c>=ATTRIB1)
+               if(*c==TANGENT3 || *c==BINORMAL3 || *c>=ATTRIB1)
                        has_gen_attrs = true;
        }
        if(has_multitex)
@@ -235,6 +235,8 @@ VertexArray::Loader::Loader(VertexArray &a):
        add("attrib2",   static_cast<void (Loader::*)(unsigned, float, float)>(&Loader::attrib));
        add("attrib3",   static_cast<void (Loader::*)(unsigned, float, float, float)>(&Loader::attrib));
        add("attrib4",   static_cast<void (Loader::*)(unsigned, float, float, float, float)>(&Loader::attrib));
+       add("tangent3",  static_cast<void (Loader::*)(float, float, float)>(&Loader::tangent));
+       add("binormal3", static_cast<void (Loader::*)(float, float, float)>(&Loader::binormal));
 }
 
 } // namespace GL
index 25eb0e76e57170151c0fdffcb43c4468a085ab0b..7a1c943c9ed18b7f6f2330cdc67b0ebb76bc4197 100644 (file)
@@ -5,6 +5,7 @@
 #include "color.h"
 #include "matrix.h"
 #include "vector.h"
+#include "vertexformat.h"
 
 namespace Msp {
 namespace GL {
@@ -60,6 +61,24 @@ public:
                nor = Vector3(tn.x, tn.y, tn.z);
        }
 
+       void tangent(float x, float y, float z)
+       { tangent(Vector3(x, y, z)); }
+
+       void tangent(const Vector3 &t)
+       {
+               Vector4 tt = mtx.top()*Vector4(t.x, t.y, t.z, 0);
+               attrib(get_component_type(TANGENT3), tt);
+       }
+
+       void binormal(float x, float y, float z)
+       { binormal(Vector3(x, y, z)); }
+
+       void binormal(const Vector3 &b)
+       {
+               Vector4 tb = mtx.top()*Vector4(b.x, b.y, b.z, 0);
+               attrib(get_component_type(BINORMAL3), tb);
+       }
+
        void texcoord(float s)
        { texcoord(s, 0, 0, 1); }
 
index 1de430870d6a328d363b169f0fb53125bde2614a..8cc0cec990157719b87ffe70e640b4c579829f77 100644 (file)
@@ -139,6 +139,10 @@ void operator>>(const LexicalConverter &conv, VertexComponent &c)
                c = static_cast<VertexComponent>(COLOR3_FLOAT+(str[5]-'3'));
        else if(str=="COLOR4_UBYTE")
                c = COLOR4_UBYTE;
+       else if(str=="TANGENT3")
+               c = TANGENT3;
+       else if(str=="BINORMAL3")
+               c = BINORMAL3;
        else if(str.size()>=9 && !str.compare(0, 8, "TEXCOORD") && str[8]>='1' && str[8]<='4')
        {
                if(str.size()==9)
index 9be98160b0bb0d23ef62358d150aa6e670d254d2..4c343c99e60f2def0d13571213d71da5ddef132b 100644 (file)
@@ -18,6 +18,8 @@ enum VertexComponent
        COLOR4_UBYTE = 12,
        COLOR3_FLOAT = 14,
        COLOR4_FLOAT,
+       TANGENT3 = 18,
+       BINORMAL3 = 22,
        TEXCOORD1 = 32,
        TEXCOORD2,
        TEXCOORD3,