From bc3c82a86eeadde54be9fe32a8a8a76872ca99c3 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 14 Jan 2009 19:19:18 +0000 Subject: [PATCH] Allow generic vertex attribute 0, since OpenGL 3.0 does not support any fixed-function attributes Blender exporter: support exporting tangent/binormal vectors for bump mapping --- mesh_export.py | 53 +++++++++++++++++++++++++++++++---- source/vertexarray.cpp | 4 +-- source/vertexarraybuilder.cpp | 7 +++-- source/vertexformat.cpp | 6 ++-- 4 files changed, 57 insertions(+), 13 deletions(-) diff --git a/mesh_export.py b/mesh_export.py index 7d21956a..41ceb90a 100644 --- a/mesh_export.py +++ b/mesh_export.py @@ -20,6 +20,8 @@ class Edge: def __init__(self, me): if me.__class__==Edge: self._medge=me._medge + self.v1=me.v1 + self.v2=me.v2 self.smooth=me.smooth else: self._medge=me @@ -54,6 +56,7 @@ class Vertex: def __init__(self, mv): if mv.__class__==Vertex: self._mvert=mv._mvert + self.no=mv.no self.uv=mv.uv else: self._mvert=mv @@ -61,6 +64,8 @@ class Vertex: self.orig_index=self._mvert.index self.flag=False self.faces=[] + self.tan=None + self.bino=None def __getattr__(self, attr): return getattr(self._mvert, attr) @@ -96,7 +101,7 @@ class Face: __repr__=__str__ - def get_vertices_from(self, reverse, *vt): + def pivot_vertices(self, reverse, *vt): verts=self.verts[:] if reverse: verts.reverse() @@ -111,6 +116,7 @@ class Face: for e in self.edges: if e.key==key: return e + raise KeyError, "No edge %s"%(key,) class Line: @@ -180,7 +186,7 @@ class Mesh: self.verts.append(v) if debug: - print " -> %d"%v.index + print " -> %d %s"%(v.index, [f.index for f in g]) for f in g: for j in range(len(f.edges)): @@ -263,6 +269,26 @@ class Mesh: if v.faces: v.uv=v.faces[0].uv[v.faces[0].verts.index(v)] + def compute_tbn(self): + for v in self.verts: + v.tan=Blender.Mathutils.Vector() + v.bino=Blender.Mathutils.Vector() + for f in v.faces: + fverts=f.pivot_vertices(False, v) + v1=fverts[1] + v2=fverts[-1] + du1=v1.uv[0]-v.uv[0] + du2=v2.uv[0]-v.uv[0] + dv1=v1.uv[1]-v.uv[1] + dv2=v2.uv[1]-v.uv[1] + div=du1*dv2-du2*dv1 + edge1=fverts[1].co-fverts[0].co + edge2=fverts[-1].co-fverts[0].co + v.tan+=(edge1*dv2-edge2*dv1)/div + v.bino+=(edge2*du1-edge1*du2)/div + v.tan.normalize() + v.bino.normalize() + def create_strip(self, face, reverse, debug): edge=None for e in face.edges: @@ -277,14 +303,14 @@ class Mesh: if debug: print "Starting strip from %s, edge %s, reverse=%s"%([v.index for v in face.verts], (edge.v1.index, edge.v2.index), reverse) - verts=face.get_vertices_from(reverse, edge.v1, edge.v2) + verts=face.pivot_vertices(reverse, edge.v1, edge.v2) if len(verts)==3: result=[verts[-1], verts[0]] else: result=[verts[-2], verts[-1]] while 1: - verts=face.get_vertices_from(reverse, *result[-2:]) + verts=face.pivot_vertices(reverse, *result[-2:]) k=len(result)%2 if debug: print " Adding %s"%face @@ -323,6 +349,7 @@ class Exporter: self.use_degen_tris=True self.optimize_locality=True self.export_lines=True + self.tbn_vecs=False self.debug=False self.strip_debug=False self.split_debug=False @@ -374,6 +401,8 @@ class Exporter: print "After UV splitting %d vertices and %d edges"%(len(mesh.verts), len(mesh.edges)) mesh.compute_uv() + if self.tbn_vecs: + mesh.compute_tbn() strips=[] if self.use_strips: @@ -479,9 +508,13 @@ class Exporter: self.out_file.write("vertices NORMAL3") if mesh.faceUV: self.out_file.write("_TEXCOORD2") + if self.tbn_vecs: + self.out_file.write("_ATTRIB33_ATTRIB34") self.out_file.write("_VERTEX3\n{\n") norm=None uv=None + tan=None + bino=None for v in mesh.verts: if v.no!=norm: self.out_file.write("\tnormal3 %f %f %f;\n"%tuple(v.no)) @@ -489,6 +522,12 @@ class Exporter: if v.uv!=uv: self.out_file.write("\ttexcoord2 %f %f;\n"%tuple(v.uv)) uv=v.uv + if v.tan!=tan: + self.out_file.write("\tattrib3 3 %f %f %f;\n"%tuple(v.tan)) + tan=v.tan + if v.bino!=bino: + self.out_file.write("\tattrib3 4 %f %f %f;\n"%tuple(v.bino)) + bino=v.bino self.out_file.write("\tvertex3 %f %f %f;\n"%tuple(v.co)) self.out_file.write("};\n") for s in strips: @@ -529,6 +568,7 @@ class FrontEnd: self.use_degen_tris=Blender.Draw.Create(self.config.get('use_degen_tris', True)) self.optimize_locality=Blender.Draw.Create(self.config.get('optimize_locality', True)) self.export_lines=Blender.Draw.Create(self.config.get('export_lines', False)) + self.tbn_vecs=Blender.Draw.Create(self.config.get('tbn_vecs', False)) self.debug=Blender.Draw.Create(self.config.get('debug', False)) self.strip_debug=Blender.Draw.Create(self.config.get('strip_debug', False)) self.split_debug=Blender.Draw.Create(self.config.get('split_debug', False)) @@ -536,7 +576,8 @@ class FrontEnd: [("Use strips", self.use_strips, "Generage OpenGL triangle strips"), ("Use degen tris", self.use_degen_tris, "Use degenerate triangles to combine triangle strips"), ("Optimize locality", self.optimize_locality), - ("Export lines", self.export_lines), + ("Export lines", self.export_lines, "Export lone edges as lines"), + ("Compute T/B vecs", self.tbn_vecs, "Compute tangent/binormal vectors for bumpmapping"), ("Debugging options"), ("Debug", self.debug), ("Debug strips", self.strip_debug), @@ -554,6 +595,7 @@ class FrontEnd: self.config['use_degen_tris']=self.use_degen_tris.val self.config['optimize_locality']=self.optimize_locality.val self.config['export_lines']=self.export_lines.val + self.config['tbn_vecs']=self.tbn_vecs.val self.config['debug']=self.debug.val self.config['strip_debug']=self.strip_debug.val self.config['split_debug']=self.split_debug.val @@ -568,6 +610,7 @@ class FrontEnd: exp.use_degen_tris=self.use_degen_tris.val exp.optimize_locality=self.optimize_locality.val exp.export_lines=self.export_lines.val + exp.tbn_vecs=self.tbn_vecs.val exp.debug=self.debug.val exp.strip_debug=self.strip_debug.val exp.split_debug=self.split_debug.val diff --git a/source/vertexarray.cpp b/source/vertexarray.cpp index de343bf7..ef118444 100644 --- a/source/vertexarray.cpp +++ b/source/vertexarray.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -108,7 +108,7 @@ void VertexArray::apply() const glColorPointer(sz, GL_FLOAT, bpv, base+offset); break; default: - glVertexAttribPointerARB(t-3, sz, GL_FLOAT, false, bpv, base+offset); + glVertexAttribPointerARB(t-4, sz, GL_FLOAT, false, bpv, base+offset); break; } found|=1<>2) + uint type=*c>>2; + switch(type) { case 0: *ptr++=x; @@ -64,7 +65,7 @@ void VertexArrayBuilder::vertex_(float x, float y, float z, float w) } break; default: - const Attrib &a=av[(*c>>2)-4]; + const Attrib &a=av[type-4]; *ptr++=a.x; if(size>=2) *ptr++=a.y; if(size>=3) *ptr++=a.z; diff --git a/source/vertexformat.cpp b/source/vertexformat.cpp index 232690ed..91084bcc 100644 --- a/source/vertexformat.cpp +++ b/source/vertexformat.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -87,9 +87,9 @@ VertexFormat operator,(const VertexFormat &f, unsigned i) if(*c28) + if(i>=28) throw InvalidParameterValue("Generic attribute index out of range"); - *c+=(i-1)*4; + *c+=i*4; return r; } -- 2.45.2