From b8fef9be469eb16e54068bac7e275ea225efc71c Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 10 Jan 2009 10:07:36 +0000 Subject: [PATCH] Rewrite VertexFormat to support an arbitary amount of components Add support for generic vertex attributes to VertexFormat and VertexArray Check for proper extensions in Shader constructor Blender exporter: Export texture coordinates --- mesh_export.py | 79 +++++++++++++------- source/arb_vertex_program.cpp | 137 ++++++++++++++++++++++++++++++++++ source/arb_vertex_program.h | 78 +++++++++++++++++++ source/extension.cpp | 3 + source/mesh.cpp | 2 +- source/shader.cpp | 4 +- source/vertexarray.cpp | 65 ++++++++++------ source/vertexarray.h | 8 +- source/vertexarraybuilder.cpp | 41 +++++----- source/vertexbuilder.cpp | 9 +++ source/vertexbuilder.h | 12 +++ source/vertexformat.cpp | 117 ++++++++++++++++++++++++++++- source/vertexformat.h | 33 +++++++- 13 files changed, 506 insertions(+), 82 deletions(-) create mode 100644 source/arb_vertex_program.cpp create mode 100644 source/arb_vertex_program.h diff --git a/mesh_export.py b/mesh_export.py index fbb28228..7d21956a 100644 --- a/mesh_export.py +++ b/mesh_export.py @@ -66,6 +66,8 @@ class Vertex: return getattr(self._mvert, attr) def __cmp__(self, other): + if other is None: + return 1 return cmp(self.index, other.index) def __str__(self): @@ -85,6 +87,8 @@ class Face: return getattr(self._mface, attr) def __cmp__(self, other): + if other is None: + return 1 return cmp(self.index, other.index) def __str__(self): @@ -96,8 +100,7 @@ class Face: verts=self.verts[:] if reverse: verts.reverse() - indices=[u.index for u in vt] - flags=[(v.index in indices) for v in verts] + flags=[(v in vt) for v in verts] l=len(verts) for i in range(l): if flags[i] and not flags[(i+l-1)%l]: @@ -151,7 +154,7 @@ class Mesh: def __getattr__(self, attr): return getattr(self._mesh, attr) - def split_vertices(self, debug=False): + def split_vertices(self, find_group_func, debug): groups=[] for v in self.verts: for f in v.faces: @@ -160,7 +163,7 @@ class Mesh: vg=[] for f in v.faces: if not f.flag: - vg.append(self.find_group(v, f)) + vg.append(find_group_func(v, f)) groups.append(vg) @@ -189,15 +192,14 @@ class Mesh: if debug: print " Splitting edge %s with faces %s"%(e.key, e.faces) - if not e.smooth: - if len(e.faces)>=2: - k=e.faces.index(f) - e.faces.remove(f) - e=Edge(e) - f.edges[j]=e - e.faces.append(f) - else: - del self.edges[e.key] + if e.other_face(f) not in g and len(e.faces)>=2: + k=e.faces.index(f) + e.faces.remove(f) + e=Edge(e) + f.edges[j]=e + e.faces.append(f) + else: + del self.edges[e.key] if e.v1==self.verts[i]: e.v1=v @@ -205,23 +207,27 @@ class Mesh: e.v2=v e.key=make_edge_key(e.v1.index, e.v2.index) - if not e.smooth: - self.edges[e.key]=e + self.edges[e.key]=e self.verts[i].faces.remove(f) f.verts[f.verts.index(self.verts[i])]=v v.faces.append(f) - def find_group(self, vert, face): - face_indices=[f.index for f in vert.faces] + def split_smooth(self, debug=False): + self.split_vertices(self.find_smooth_group, debug) + + def split_uv(self, debug=False): + self.split_vertices(self.find_uv_group, debug) + def find_smooth_group(self, vert, face): face.flag=True queue=[face] for f in queue: for e in f.edges: other=e.other_face(f) - if not other or other.index not in face_indices: + #if not other or other.index not in face_indices: + if other not in vert.faces: continue if e.smooth: @@ -231,6 +237,16 @@ class Mesh: return queue + def find_uv_group(self, vert, face): + uv=face.uv[face.verts.index(vert)] + face.flag=True + group=[face] + for f in vert.faces: + if not f.flag and f.uv[f.verts.index(vert)]==uv: + f.flag=True + group.append(f) + return group + def compute_normals(self): for v in self.verts: if v.faces: @@ -242,6 +258,11 @@ class Mesh: # XXX Should use edges to compute normal v.no=Blender.Mathutils.Vector(0, 0, 1) + def compute_uv(self): + for v in self.verts: + if v.faces: + v.uv=v.faces[0].uv[v.faces[0].verts.index(v)] + def create_strip(self, face, reverse, debug): edge=None for e in face.edges: @@ -304,7 +325,7 @@ class Exporter: self.export_lines=True self.debug=False self.strip_debug=False - self.smooth_debug=False + self.split_debug=False def get_locality(self, strip): total=0 @@ -340,14 +361,20 @@ class Exporter: ntris=sum([len(f.verts)-2 for f in mesh.faces]) print "Starting with %d vertices, %d faces (%d triangles) and %d edges"%(len(mesh.verts), len(mesh.faces), ntris, len(mesh.edges)) - mesh.split_vertices(self.smooth_debug) + mesh.split_smooth(self.split_debug) if self.debug: - ntris=sum([len(f.verts)-2 for f in mesh.faces]) - print "After splitting %d vertices, %d faces (%d triangles) and %d edges"%(len(mesh.verts), len(mesh.faces), ntris, len(mesh.edges)) + print "After smooth splitting %d vertices and %d edges"%(len(mesh.verts), len(mesh.edges)) mesh.compute_normals() + if mesh.faceUV: + mesh.split_uv(self.split_debug) + if self.debug: + print "After UV splitting %d vertices and %d edges"%(len(mesh.verts), len(mesh.edges)) + + mesh.compute_uv() + strips=[] if self.use_strips: for f in mesh.faces: @@ -504,7 +531,7 @@ class FrontEnd: self.export_lines=Blender.Draw.Create(self.config.get('export_lines', False)) self.debug=Blender.Draw.Create(self.config.get('debug', False)) self.strip_debug=Blender.Draw.Create(self.config.get('strip_debug', False)) - self.smooth_debug=Blender.Draw.Create(self.config.get('smooth_debug', False)) + self.split_debug=Blender.Draw.Create(self.config.get('split_debug', False)) ret=Blender.Draw.PupBlock("Export MSP GL mesh", [("Use strips", self.use_strips, "Generage OpenGL triangle strips"), ("Use degen tris", self.use_degen_tris, "Use degenerate triangles to combine triangle strips"), @@ -513,7 +540,7 @@ class FrontEnd: ("Debugging options"), ("Debug", self.debug), ("Debug strips", self.strip_debug), - ("Debug smoothing", self.smooth_debug)]) + ("Debug splitting", self.split_debug)]) if ret: dirname=self.temp_config.get("dirname", Blender.sys.dirname(Blender.Get("filename"))) obj=bpy.data.scenes.active.objects.active @@ -529,7 +556,7 @@ class FrontEnd: self.config['export_lines']=self.export_lines.val self.config['debug']=self.debug.val self.config['strip_debug']=self.strip_debug.val - self.config['smooth_debug']=self.smooth_debug.val + self.config['split_debug']=self.split_debug.val Blender.Registry.SetKey('mspgl_export', self.config, True) import os @@ -543,7 +570,7 @@ class FrontEnd: exp.export_lines=self.export_lines.val exp.debug=self.debug.val exp.strip_debug=self.strip_debug.val - exp.smooth_debug=self.smooth_debug.val + exp.split_debug=self.split_debug.val exp.export() diff --git a/source/arb_vertex_program.cpp b/source/arb_vertex_program.cpp new file mode 100644 index 00000000..c68da2b9 --- /dev/null +++ b/source/arb_vertex_program.cpp @@ -0,0 +1,137 @@ +#include "extension.h" +#include "arb_vertex_program.h" + +namespace Msp { +namespace GL { + +PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB=0; +PFNGLVERTEXATTRIB1DVARBPROC glVertexAttrib1dvARB=0; +PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB=0; +PFNGLVERTEXATTRIB1FVARBPROC glVertexAttrib1fvARB=0; +PFNGLVERTEXATTRIB1SARBPROC glVertexAttrib1sARB=0; +PFNGLVERTEXATTRIB1SVARBPROC glVertexAttrib1svARB=0; +PFNGLVERTEXATTRIB2DARBPROC glVertexAttrib2dARB=0; +PFNGLVERTEXATTRIB2DVARBPROC glVertexAttrib2dvARB=0; +PFNGLVERTEXATTRIB2FARBPROC glVertexAttrib2fARB=0; +PFNGLVERTEXATTRIB2FVARBPROC glVertexAttrib2fvARB=0; +PFNGLVERTEXATTRIB2SARBPROC glVertexAttrib2sARB=0; +PFNGLVERTEXATTRIB2SVARBPROC glVertexAttrib2svARB=0; +PFNGLVERTEXATTRIB3DARBPROC glVertexAttrib3dARB=0; +PFNGLVERTEXATTRIB3DVARBPROC glVertexAttrib3dvARB=0; +PFNGLVERTEXATTRIB3FARBPROC glVertexAttrib3fARB=0; +PFNGLVERTEXATTRIB3FVARBPROC glVertexAttrib3fvARB=0; +PFNGLVERTEXATTRIB3SARBPROC glVertexAttrib3sARB=0; +PFNGLVERTEXATTRIB3SVARBPROC glVertexAttrib3svARB=0; +PFNGLVERTEXATTRIB4NBVARBPROC glVertexAttrib4NbvARB=0; +PFNGLVERTEXATTRIB4NIVARBPROC glVertexAttrib4NivARB=0; +PFNGLVERTEXATTRIB4NSVARBPROC glVertexAttrib4NsvARB=0; +PFNGLVERTEXATTRIB4NUBARBPROC glVertexAttrib4NubARB=0; +PFNGLVERTEXATTRIB4NUBVARBPROC glVertexAttrib4NubvARB=0; +PFNGLVERTEXATTRIB4NUIVARBPROC glVertexAttrib4NuivARB=0; +PFNGLVERTEXATTRIB4NUSVARBPROC glVertexAttrib4NusvARB=0; +PFNGLVERTEXATTRIB4BVARBPROC glVertexAttrib4bvARB=0; +PFNGLVERTEXATTRIB4DARBPROC glVertexAttrib4dARB=0; +PFNGLVERTEXATTRIB4DVARBPROC glVertexAttrib4dvARB=0; +PFNGLVERTEXATTRIB4FARBPROC glVertexAttrib4fARB=0; +PFNGLVERTEXATTRIB4FVARBPROC glVertexAttrib4fvARB=0; +PFNGLVERTEXATTRIB4IVARBPROC glVertexAttrib4ivARB=0; +PFNGLVERTEXATTRIB4SARBPROC glVertexAttrib4sARB=0; +PFNGLVERTEXATTRIB4SVARBPROC glVertexAttrib4svARB=0; +PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB=0; +PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB=0; +PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB=0; +PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB=0; +PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB=0; +PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB=0; +PFNGLPROGRAMSTRINGARBPROC glProgramStringARB=0; +PFNGLBINDPROGRAMARBPROC glBindProgramARB=0; +PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB=0; +PFNGLGENPROGRAMSARBPROC glGenProgramsARB=0; +PFNGLPROGRAMENVPARAMETER4DARBPROC glProgramEnvParameter4dARB=0; +PFNGLPROGRAMENVPARAMETER4DVARBPROC glProgramEnvParameter4dvARB=0; +PFNGLPROGRAMENVPARAMETER4FARBPROC glProgramEnvParameter4fARB=0; +PFNGLPROGRAMENVPARAMETER4FVARBPROC glProgramEnvParameter4fvARB=0; +PFNGLPROGRAMLOCALPARAMETER4DARBPROC glProgramLocalParameter4dARB=0; +PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glProgramLocalParameter4dvARB=0; +PFNGLPROGRAMLOCALPARAMETER4FARBPROC glProgramLocalParameter4fARB=0; +PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB=0; +PFNGLGETPROGRAMENVPARAMETERDVARBPROC glGetProgramEnvParameterdvARB=0; +PFNGLGETPROGRAMENVPARAMETERFVARBPROC glGetProgramEnvParameterfvARB=0; +PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glGetProgramLocalParameterdvARB=0; +PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glGetProgramLocalParameterfvARB=0; +PFNGLGETPROGRAMIVARBPROC glGetProgramivARB=0; +PFNGLGETPROGRAMSTRINGARBPROC glGetProgramStringARB=0; +PFNGLGETVERTEXATTRIBDVARBPROC glGetVertexAttribdvARB=0; +PFNGLGETVERTEXATTRIBFVARBPROC glGetVertexAttribfvARB=0; +PFNGLGETVERTEXATTRIBIVARBPROC glGetVertexAttribivARB=0; +PFNGLGETVERTEXATTRIBPOINTERVARBPROC glGetVertexAttribPointervARB=0; +PFNGLISPROGRAMARBPROC glIsProgramARB=0; + +void init_arb_vertex_program() +{ + glVertexAttrib1dARB=reinterpret_cast(get_proc_address("glVertexAttrib1dARB")); + glVertexAttrib1dvARB=reinterpret_cast(get_proc_address("glVertexAttrib1dvARB")); + glVertexAttrib1fARB=reinterpret_cast(get_proc_address("glVertexAttrib1fARB")); + glVertexAttrib1fvARB=reinterpret_cast(get_proc_address("glVertexAttrib1fvARB")); + glVertexAttrib1sARB=reinterpret_cast(get_proc_address("glVertexAttrib1sARB")); + glVertexAttrib1svARB=reinterpret_cast(get_proc_address("glVertexAttrib1svARB")); + glVertexAttrib2dARB=reinterpret_cast(get_proc_address("glVertexAttrib2dARB")); + glVertexAttrib2dvARB=reinterpret_cast(get_proc_address("glVertexAttrib2dvARB")); + glVertexAttrib2fARB=reinterpret_cast(get_proc_address("glVertexAttrib2fARB")); + glVertexAttrib2fvARB=reinterpret_cast(get_proc_address("glVertexAttrib2fvARB")); + glVertexAttrib2sARB=reinterpret_cast(get_proc_address("glVertexAttrib2sARB")); + glVertexAttrib2svARB=reinterpret_cast(get_proc_address("glVertexAttrib2svARB")); + glVertexAttrib3dARB=reinterpret_cast(get_proc_address("glVertexAttrib3dARB")); + glVertexAttrib3dvARB=reinterpret_cast(get_proc_address("glVertexAttrib3dvARB")); + glVertexAttrib3fARB=reinterpret_cast(get_proc_address("glVertexAttrib3fARB")); + glVertexAttrib3fvARB=reinterpret_cast(get_proc_address("glVertexAttrib3fvARB")); + glVertexAttrib3sARB=reinterpret_cast(get_proc_address("glVertexAttrib3sARB")); + glVertexAttrib3svARB=reinterpret_cast(get_proc_address("glVertexAttrib3svARB")); + glVertexAttrib4NbvARB=reinterpret_cast(get_proc_address("glVertexAttrib4NbvARB")); + glVertexAttrib4NivARB=reinterpret_cast(get_proc_address("glVertexAttrib4NivARB")); + glVertexAttrib4NsvARB=reinterpret_cast(get_proc_address("glVertexAttrib4NsvARB")); + glVertexAttrib4NubARB=reinterpret_cast(get_proc_address("glVertexAttrib4NubARB")); + glVertexAttrib4NubvARB=reinterpret_cast(get_proc_address("glVertexAttrib4NubvARB")); + glVertexAttrib4NuivARB=reinterpret_cast(get_proc_address("glVertexAttrib4NuivARB")); + glVertexAttrib4NusvARB=reinterpret_cast(get_proc_address("glVertexAttrib4NusvARB")); + glVertexAttrib4bvARB=reinterpret_cast(get_proc_address("glVertexAttrib4bvARB")); + glVertexAttrib4dARB=reinterpret_cast(get_proc_address("glVertexAttrib4dARB")); + glVertexAttrib4dvARB=reinterpret_cast(get_proc_address("glVertexAttrib4dvARB")); + glVertexAttrib4fARB=reinterpret_cast(get_proc_address("glVertexAttrib4fARB")); + glVertexAttrib4fvARB=reinterpret_cast(get_proc_address("glVertexAttrib4fvARB")); + glVertexAttrib4ivARB=reinterpret_cast(get_proc_address("glVertexAttrib4ivARB")); + glVertexAttrib4sARB=reinterpret_cast(get_proc_address("glVertexAttrib4sARB")); + glVertexAttrib4svARB=reinterpret_cast(get_proc_address("glVertexAttrib4svARB")); + glVertexAttrib4ubvARB=reinterpret_cast(get_proc_address("glVertexAttrib4ubvARB")); + glVertexAttrib4uivARB=reinterpret_cast(get_proc_address("glVertexAttrib4uivARB")); + glVertexAttrib4usvARB=reinterpret_cast(get_proc_address("glVertexAttrib4usvARB")); + glVertexAttribPointerARB=reinterpret_cast(get_proc_address("glVertexAttribPointerARB")); + glEnableVertexAttribArrayARB=reinterpret_cast(get_proc_address("glEnableVertexAttribArrayARB")); + glDisableVertexAttribArrayARB=reinterpret_cast(get_proc_address("glDisableVertexAttribArrayARB")); + glProgramStringARB=reinterpret_cast(get_proc_address("glProgramStringARB")); + glBindProgramARB=reinterpret_cast(get_proc_address("glBindProgramARB")); + glDeleteProgramsARB=reinterpret_cast(get_proc_address("glDeleteProgramsARB")); + glGenProgramsARB=reinterpret_cast(get_proc_address("glGenProgramsARB")); + glProgramEnvParameter4dARB=reinterpret_cast(get_proc_address("glProgramEnvParameter4dARB")); + glProgramEnvParameter4dvARB=reinterpret_cast(get_proc_address("glProgramEnvParameter4dvARB")); + glProgramEnvParameter4fARB=reinterpret_cast(get_proc_address("glProgramEnvParameter4fARB")); + glProgramEnvParameter4fvARB=reinterpret_cast(get_proc_address("glProgramEnvParameter4fvARB")); + glProgramLocalParameter4dARB=reinterpret_cast(get_proc_address("glProgramLocalParameter4dARB")); + glProgramLocalParameter4dvARB=reinterpret_cast(get_proc_address("glProgramLocalParameter4dvARB")); + glProgramLocalParameter4fARB=reinterpret_cast(get_proc_address("glProgramLocalParameter4fARB")); + glProgramLocalParameter4fvARB=reinterpret_cast(get_proc_address("glProgramLocalParameter4fvARB")); + glGetProgramEnvParameterdvARB=reinterpret_cast(get_proc_address("glGetProgramEnvParameterdvARB")); + glGetProgramEnvParameterfvARB=reinterpret_cast(get_proc_address("glGetProgramEnvParameterfvARB")); + glGetProgramLocalParameterdvARB=reinterpret_cast(get_proc_address("glGetProgramLocalParameterdvARB")); + glGetProgramLocalParameterfvARB=reinterpret_cast(get_proc_address("glGetProgramLocalParameterfvARB")); + glGetProgramivARB=reinterpret_cast(get_proc_address("glGetProgramivARB")); + glGetProgramStringARB=reinterpret_cast(get_proc_address("glGetProgramStringARB")); + glGetVertexAttribdvARB=reinterpret_cast(get_proc_address("glGetVertexAttribdvARB")); + glGetVertexAttribfvARB=reinterpret_cast(get_proc_address("glGetVertexAttribfvARB")); + glGetVertexAttribivARB=reinterpret_cast(get_proc_address("glGetVertexAttribivARB")); + glGetVertexAttribPointervARB=reinterpret_cast(get_proc_address("glGetVertexAttribPointervARB")); + glIsProgramARB=reinterpret_cast(get_proc_address("glIsProgramARB")); +} + +} // namespace GL +} // namespace Msp diff --git a/source/arb_vertex_program.h b/source/arb_vertex_program.h new file mode 100644 index 00000000..a4c8dd0d --- /dev/null +++ b/source/arb_vertex_program.h @@ -0,0 +1,78 @@ +#ifndef MSP_GL_ARB_VERTEX_PROGRAM_ +#define MSP_GL_ARB_VERTEX_PROGRAM_ + +#include "gl.h" +#include + +namespace Msp { +namespace GL { + +extern PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB; +extern PFNGLVERTEXATTRIB1DVARBPROC glVertexAttrib1dvARB; +extern PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB; +extern PFNGLVERTEXATTRIB1FVARBPROC glVertexAttrib1fvARB; +extern PFNGLVERTEXATTRIB1SARBPROC glVertexAttrib1sARB; +extern PFNGLVERTEXATTRIB1SVARBPROC glVertexAttrib1svARB; +extern PFNGLVERTEXATTRIB2DARBPROC glVertexAttrib2dARB; +extern PFNGLVERTEXATTRIB2DVARBPROC glVertexAttrib2dvARB; +extern PFNGLVERTEXATTRIB2FARBPROC glVertexAttrib2fARB; +extern PFNGLVERTEXATTRIB2FVARBPROC glVertexAttrib2fvARB; +extern PFNGLVERTEXATTRIB2SARBPROC glVertexAttrib2sARB; +extern PFNGLVERTEXATTRIB2SVARBPROC glVertexAttrib2svARB; +extern PFNGLVERTEXATTRIB3DARBPROC glVertexAttrib3dARB; +extern PFNGLVERTEXATTRIB3DVARBPROC glVertexAttrib3dvARB; +extern PFNGLVERTEXATTRIB3FARBPROC glVertexAttrib3fARB; +extern PFNGLVERTEXATTRIB3FVARBPROC glVertexAttrib3fvARB; +extern PFNGLVERTEXATTRIB3SARBPROC glVertexAttrib3sARB; +extern PFNGLVERTEXATTRIB3SVARBPROC glVertexAttrib3svARB; +extern PFNGLVERTEXATTRIB4NBVARBPROC glVertexAttrib4NbvARB; +extern PFNGLVERTEXATTRIB4NIVARBPROC glVertexAttrib4NivARB; +extern PFNGLVERTEXATTRIB4NSVARBPROC glVertexAttrib4NsvARB; +extern PFNGLVERTEXATTRIB4NUBARBPROC glVertexAttrib4NubARB; +extern PFNGLVERTEXATTRIB4NUBVARBPROC glVertexAttrib4NubvARB; +extern PFNGLVERTEXATTRIB4NUIVARBPROC glVertexAttrib4NuivARB; +extern PFNGLVERTEXATTRIB4NUSVARBPROC glVertexAttrib4NusvARB; +extern PFNGLVERTEXATTRIB4BVARBPROC glVertexAttrib4bvARB; +extern PFNGLVERTEXATTRIB4DARBPROC glVertexAttrib4dARB; +extern PFNGLVERTEXATTRIB4DVARBPROC glVertexAttrib4dvARB; +extern PFNGLVERTEXATTRIB4FARBPROC glVertexAttrib4fARB; +extern PFNGLVERTEXATTRIB4FVARBPROC glVertexAttrib4fvARB; +extern PFNGLVERTEXATTRIB4IVARBPROC glVertexAttrib4ivARB; +extern PFNGLVERTEXATTRIB4SARBPROC glVertexAttrib4sARB; +extern PFNGLVERTEXATTRIB4SVARBPROC glVertexAttrib4svARB; +extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB; +extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB; +extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB; +extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB; +extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB; +extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB; +extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB; +extern PFNGLBINDPROGRAMARBPROC glBindProgramARB; +extern PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB; +extern PFNGLGENPROGRAMSARBPROC glGenProgramsARB; +extern PFNGLPROGRAMENVPARAMETER4DARBPROC glProgramEnvParameter4dARB; +extern PFNGLPROGRAMENVPARAMETER4DVARBPROC glProgramEnvParameter4dvARB; +extern PFNGLPROGRAMENVPARAMETER4FARBPROC glProgramEnvParameter4fARB; +extern PFNGLPROGRAMENVPARAMETER4FVARBPROC glProgramEnvParameter4fvARB; +extern PFNGLPROGRAMLOCALPARAMETER4DARBPROC glProgramLocalParameter4dARB; +extern PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glProgramLocalParameter4dvARB; +extern PFNGLPROGRAMLOCALPARAMETER4FARBPROC glProgramLocalParameter4fARB; +extern PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB; +extern PFNGLGETPROGRAMENVPARAMETERDVARBPROC glGetProgramEnvParameterdvARB; +extern PFNGLGETPROGRAMENVPARAMETERFVARBPROC glGetProgramEnvParameterfvARB; +extern PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glGetProgramLocalParameterdvARB; +extern PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glGetProgramLocalParameterfvARB; +extern PFNGLGETPROGRAMIVARBPROC glGetProgramivARB; +extern PFNGLGETPROGRAMSTRINGARBPROC glGetProgramStringARB; +extern PFNGLGETVERTEXATTRIBDVARBPROC glGetVertexAttribdvARB; +extern PFNGLGETVERTEXATTRIBFVARBPROC glGetVertexAttribfvARB; +extern PFNGLGETVERTEXATTRIBIVARBPROC glGetVertexAttribivARB; +extern PFNGLGETVERTEXATTRIBPOINTERVARBPROC glGetVertexAttribPointervARB; +extern PFNGLISPROGRAMARBPROC glIsProgramARB; + +void init_arb_vertex_program(); + +} // namespace GL +} // namespace Msp + +#endif diff --git a/source/extension.cpp b/source/extension.cpp index a5ad3191..ba7dd402 100644 --- a/source/extension.cpp +++ b/source/extension.cpp @@ -13,6 +13,7 @@ Distributed under the LGPL #include #include "arb_shader_objects.h" #include "arb_vertex_buffer_object.h" +#include "arb_vertex_program.h" #include "arb_vertex_shader.h" #include "ext_framebuffer_object.h" #include "except.h" @@ -45,6 +46,8 @@ bool is_supported(const string &ext) init_arb_shader_objects(); if(extensions.count("GL_ARB_vertex_shader")) init_arb_vertex_shader(); + if(extensions.count("GL_ARB_vertex_program")) + init_arb_vertex_program(); if(extensions.count("GL_EXT_framebuffer_object")) init_ext_framebuffer_object(); if(extensions.count("GL_ARB_vertex_buffer_object")) diff --git a/source/mesh.cpp b/source/mesh.cpp index fec753d0..7f50beb7 100644 --- a/source/mesh.cpp +++ b/source/mesh.cpp @@ -13,7 +13,7 @@ namespace Msp { namespace GL { Mesh::Mesh(): - vertices(NODATA) + vertices(VERTEX3) { } Mesh::Mesh(VertexFormat f): diff --git a/source/shader.cpp b/source/shader.cpp index 93edafb4..85451527 100644 --- a/source/shader.cpp +++ b/source/shader.cpp @@ -33,9 +33,9 @@ void Shader::init(ShaderType t) compiled=false; if(t==FRAGMENT_SHADER) - static RequireExtension _ext("GL_ARB_fragment_program"); + static RequireExtension _ext("GL_ARB_fragment_shader"); else if(t==VERTEX_SHADER) - static RequireExtension _ext("GL_ARB_vertex_program"); + static RequireExtension _ext("GL_ARB_vertex_shader"); id=glCreateShaderObjectARB(t); } diff --git a/source/vertexarray.cpp b/source/vertexarray.cpp index 3c17141c..de343bf7 100644 --- a/source/vertexarray.cpp +++ b/source/vertexarray.cpp @@ -5,6 +5,7 @@ Copyright © 2007 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ +#include "arb_vertex_program.h" #include "extension.h" #include "gl.h" #include "version_1_2.h" @@ -16,15 +17,11 @@ using namespace std; namespace Msp { namespace GL { -VertexArray::VertexArray(VertexFormat f): - format(NODATA), - stride(get_stride(f)), +VertexArray::VertexArray(const VertexFormat &f): vbuf(0), own_vbuf(false) { - // Reverse the format so the first item is in lowest bits. This makes handling in bind() easier. - for(uint fmt=f; fmt; fmt>>=4) - format=(format, static_cast(fmt&15)); + reset(f); } VertexArray::~VertexArray() @@ -64,19 +61,23 @@ void VertexArray::clear() data.clear(); } -void VertexArray::reset(VertexFormat f) +void VertexArray::reset(const VertexFormat &f) { clear(); - format=NODATA; - for(uint fmt=f; fmt; fmt>>=4) - format=(format, static_cast(fmt&15)); + format=f; stride=get_stride(format); + + bool has_gen_attrs=false; + for(const unsigned char *c=format.begin(); (!has_gen_attrs && c!=format.end()); ++c) + has_gen_attrs=(*c>=ATTRIB1); + if(has_gen_attrs) + static RequireExtension _ext("GL_ARB_vertex_program"); } void VertexArray::apply() const { - if(format==NODATA) - throw InvalidState("Trying to apply a vertex apply of format NODATA"); + if(format.empty()) + throw InvalidState("Trying to apply a vertex array with no data"); if(vbuf) vbuf->bind(); @@ -85,28 +86,32 @@ void VertexArray::apply() const uint offset=0; uint found=0; uint bpv=stride*sizeof(float); - for(uint fmt=format; fmt; fmt>>=4) + for(const unsigned char *c=format.begin(); c!=format.end(); ++c) { - uint sz=(fmt&3)+1; - switch(fmt&12) + uint sz=(*c&3)+1; + uint t=*c>>2; + switch(t) { case 0: glVertexPointer(sz, GL_FLOAT, bpv, base+offset); break; - case 4: + case 1: glNormalPointer(GL_FLOAT, bpv, base+offset); break; - case 8: + case 2: glTexCoordPointer(sz, GL_FLOAT, bpv, base+offset); break; - case 12: + case 3: if(sz==1) glColorPointer(4, GL_UNSIGNED_BYTE, bpv, base+offset); else glColorPointer(sz, GL_FLOAT, bpv, base+offset); break; + default: + glVertexAttribPointerARB(t-3, sz, GL_FLOAT, false, bpv, base+offset); + break; } - found|=1<<((fmt&12)>>2); + found|=1<>i)&1, 1<(&Loader::texcoord)); 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)); } diff --git a/source/vertexarray.h b/source/vertexarray.h index 02fa64f7..ef7f6a24 100644 --- a/source/vertexarray.h +++ b/source/vertexarray.h @@ -40,24 +40,24 @@ private: VertexArray(const VertexArray &); VertexArray &operator=(const VertexArray &); public: - VertexArray(VertexFormat); + VertexArray(const VertexFormat &); ~VertexArray(); - VertexFormat get_format() const { return format; } + const VertexFormat &get_format() const { return format; } const std::vector &get_data() const { return data; } void use_vertex_buffer(); void use_vertex_buffer(VertexBuffer *); void reserve(unsigned); unsigned size() const { return data.size()/stride; } void clear(); - void reset(VertexFormat); + void reset(const VertexFormat &); void apply() const; void update_data(); float *append(); float *operator[](unsigned i) { return &data[0]+i*stride; } const float *operator[](unsigned i) const { return &data[0]+i*stride; } private: - void set_array(unsigned, unsigned, unsigned) const; + void set_array(unsigned, bool, unsigned) const; static unsigned enabled_arrays; }; diff --git a/source/vertexarraybuilder.cpp b/source/vertexarraybuilder.cpp index f251632e..8e7e2cb5 100644 --- a/source/vertexarraybuilder.cpp +++ b/source/vertexarraybuilder.cpp @@ -23,10 +23,10 @@ VertexArrayBuilder::~VertexArrayBuilder() void VertexArrayBuilder::vertex_(float x, float y, float z, float w) { float *ptr=array.append(); - for(uint fmt=array.get_format(); fmt; fmt>>=4) + for(const unsigned char *c=array.get_format().begin(); c!=array.get_format().end(); ++c) { - uint size=(fmt&3)+1; - switch(fmt&12) + uint size=(*c&3)+1; + switch(*c>>2) { case 0: *ptr++=x; @@ -34,18 +34,18 @@ void VertexArrayBuilder::vertex_(float x, float y, float z, float w) if(size>=3) *ptr++=z; if(size>=4) *ptr++=w; break; - case 4: - *+ptr++=nx; - *+ptr++=ny; - *+ptr++=nz; + case 1: + *ptr++=nx; + *ptr++=ny; + *ptr++=nz; break; - case 8: - *+ptr++=ts; - if(size>=2) *+ptr++=tt; - if(size>=3) *+ptr++=tr; - if(size>=4) *+ptr++=tq; + case 2: + *ptr++=ts; + if(size>=2) *ptr++=tt; + if(size>=3) *ptr++=tr; + if(size>=4) *ptr++=tq; break; - case 12: + case 3: if(size==1) { union { ubyte c[4]; float f; } u; @@ -53,16 +53,23 @@ void VertexArrayBuilder::vertex_(float x, float y, float z, float w) u.c[1]=static_cast(cg*255); u.c[2]=static_cast(cb*255); u.c[3]=static_cast(ca*255); - *+ptr++=u.f; + *ptr++=u.f; } else { - *+ptr++=cr; - *+ptr++=cg; - *+ptr++=cb; + *ptr++=cr; + *ptr++=cg; + *ptr++=cb; if(size>=4) *+ptr++=ca; } break; + default: + const Attrib &a=av[(*c>>2)-4]; + *ptr++=a.x; + if(size>=2) *ptr++=a.y; + if(size>=3) *ptr++=a.z; + if(size>=4) *ptr++=a.w; + break; } } } diff --git a/source/vertexbuilder.cpp b/source/vertexbuilder.cpp index 0b1d3f30..d6759d7e 100644 --- a/source/vertexbuilder.cpp +++ b/source/vertexbuilder.cpp @@ -16,5 +16,14 @@ VertexBuilder::VertexBuilder(): nx(0), ny(0), nz(1) { } +void VertexBuilder::attrib(unsigned i, float x, float y, float z, float w) +{ + Attrib &a=av[i]; + a.x=x; + a.y=y; + a.z=z; + a.w=w; +} + } // namespace GL } // namespace Msp diff --git a/source/vertexbuilder.h b/source/vertexbuilder.h index 1b2d02d1..3e02e1d4 100644 --- a/source/vertexbuilder.h +++ b/source/vertexbuilder.h @@ -8,6 +8,7 @@ Distributed under the LGPL #ifndef MSP_GL_VERTEXBUILDER_H_ #define MSP_GL_VERTEXBUILDER_H_ +#include #include "types.h" namespace Msp { @@ -24,6 +25,12 @@ data. Attributes can be read from protected member variables. */ class VertexBuilder { +protected: + struct Attrib + { + float x, y, z, w; + }; + public: VertexBuilder(); virtual ~VertexBuilder() { } @@ -40,10 +47,15 @@ public: void color(ubyte r, ubyte g, ubyte b, ubyte a) { color(r/255.f, g/255.f, b/255.f, a/255.f); } void color(float r, float g, float b) { color(r, g, b, 1); } void color(float r, float g, float b, float a) { cr=r; cg=g; cb=b; ca=a; } + void attrib(unsigned i, float x) { attrib(i, x, 0, 0, 1); } + void attrib(unsigned i, float x, float y) { attrib(i, x, y, 0, 1); } + void attrib(unsigned i, float x, float y, float z) { attrib(i, x, y, z, 1); } + void attrib(unsigned i, float x, float y, float z, float w); protected: float cr, cg, cb, ca; // Color float ts, tt, tr, tq; // TexCoord float nx, ny, nz; // Normal + std::map av; virtual void vertex_(float, float, float, float) =0; }; diff --git a/source/vertexformat.cpp b/source/vertexformat.cpp index bf2d9095..232690ed 100644 --- a/source/vertexformat.cpp +++ b/source/vertexformat.cpp @@ -5,16 +5,100 @@ Copyright © 2007 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ +#include +#include +#include "except.h" #include "vertexformat.h" namespace Msp { namespace GL { -uint get_stride(VertexFormat f) +VertexFormat::VertexFormat(): + data(0) +{ } + +VertexFormat::VertexFormat(VertexComponent c): + data(new unsigned char[8]) +{ + data[0]=1; + data[1]=c; +} + +VertexFormat::VertexFormat(const VertexFormat &f): + data(0) +{ + if(f.data) + { + data=new unsigned char[f.data[0]/8+8]; + memcpy(data, f.data, f.data[0]+1); + } +} + +VertexFormat &VertexFormat::operator=(const VertexFormat &f) +{ + delete[] data; + if(f.data) + { + data=new unsigned char[f.data[0]/8+8]; + memcpy(data, f.data, f.data[0]+1); + } + else + data=0; + + return *this; +} + +VertexFormat::~VertexFormat() +{ + delete[] data; +} + +VertexFormat operator,(const VertexFormat &f, VertexComponent c) +{ + VertexFormat r=f; + if(r.data) + { + const unsigned char n=++r.data[0]; + if((n&7)==7) + { + unsigned char *newdt=new unsigned char[n+9]; + memcpy(newdt, r.data, n); + delete r.data; + r.data=newdt; + } + r.data[n]=c; + } + else + { + r.data=new unsigned char[8]; + r.data[0]=1; + r.data[1]=c; + } + + return r; +} + +VertexFormat operator,(const VertexFormat &f, unsigned i) +{ + if(!f.data) + throw InvalidState("VertexFormat has no components"); + VertexFormat r=f; + unsigned char *c=r.data+r.data[0]; + if(*c28) + throw InvalidParameterValue("Generic attribute index out of range"); + *c+=(i-1)*4; + + return r; +} + +uint get_stride(const VertexFormat &f) { uint stride=0; - for(uint fmt=f; fmt; fmt>>=4) - stride+=(fmt&3)+1; + for(const unsigned char *i=f.begin(); i!=f.end(); ++i) + stride+=(*i&3)+1; return stride; } @@ -24,11 +108,11 @@ std::istream &operator>>(std::istream &in, VertexFormat &f) in>>str; unsigned start=0; - f=NODATA; while(1) { unsigned underscore=str.find('_', start); + bool fail=false; if(!str.compare(start, underscore-start, "VERTEX2")) f=(f,VERTEX2); else if(!str.compare(start, underscore-start, "VERTEX3")) @@ -51,7 +135,32 @@ std::istream &operator>>(std::istream &in, VertexFormat &f) f=(f,COLOR3_FLOAT); else if(!str.compare(start, underscore-start, "COLOR4F")) f=(f,COLOR4_FLOAT); + else if(underscore>=start+8 && !str.compare(start, 6, "ATTRIB")) + { + try + { + char n=str[start+6]; + unsigned i=lexical_cast(str.substr(start+7, underscore-start-7)); + if(n=='1') + f=(f,ATTRIB1,i); + else if(n=='2') + f=(f,ATTRIB2,i); + else if(n=='3') + f=(f,ATTRIB3,i); + else if(n=='4') + f=(f,ATTRIB4,i); + else + fail=true; + } + catch(const LexicalError &) + { + fail=true; + } + } else + fail=true; + + if(fail) { in.setstate(std::ios_base::failbit); break; diff --git a/source/vertexformat.h b/source/vertexformat.h index 3a0eb718..2432d7b6 100644 --- a/source/vertexformat.h +++ b/source/vertexformat.h @@ -14,9 +14,8 @@ Distributed under the LGPL namespace Msp { namespace GL { -enum VertexFormat +enum VertexComponent { - NODATA=0, VERTEX2=1, VERTEX3, VERTEX4, @@ -28,10 +27,36 @@ enum VertexFormat COLOR4_UBYTE=12, COLOR3_FLOAT=14, COLOR4_FLOAT, + ATTRIB1=16, + ATTRIB2, + ATTRIB3, + ATTRIB4 }; -inline VertexFormat operator,(VertexFormat a, VertexFormat b) { return VertexFormat(a<<4 | b); } -uint get_stride(VertexFormat); +struct VertexFormat +{ + unsigned char *data; + + VertexFormat(); + VertexFormat(VertexComponent); + VertexFormat(const VertexFormat &); + VertexFormat &operator=(const VertexFormat &); + ~VertexFormat(); + + bool empty() const { return !data || !data[0]; } + const unsigned char *begin() const { return data ? data+1 : 0; } + const unsigned char *end() const { return data ? data+1+data[0] : 0; } +}; + +VertexFormat operator,(const VertexFormat &f, VertexComponent c); +inline VertexFormat operator,(VertexComponent c1, VertexComponent c2) +{ return (VertexFormat(c1), c2); } + +VertexFormat operator,(const VertexFormat &f, unsigned i); +inline VertexFormat operator,(VertexComponent c, unsigned i) +{ return (VertexFormat(c), i); } + +uint get_stride(const VertexFormat &); std::istream &operator>>(std::istream &, VertexFormat &); } // namespace GL -- 2.45.2