return getattr(self._mvert, attr)
def __cmp__(self, other):
+ if other is None:
+ return 1
return cmp(self.index, other.index)
def __str__(self):
return getattr(self._mface, attr)
def __cmp__(self, other):
+ if other is None:
+ return 1
return cmp(self.index, other.index)
def __str__(self):
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]:
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:
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)
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
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:
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:
# 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:
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
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:
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"),
("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
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
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()
--- /dev/null
+#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<PFNGLVERTEXATTRIB1DARBPROC>(get_proc_address("glVertexAttrib1dARB"));
+ glVertexAttrib1dvARB=reinterpret_cast<PFNGLVERTEXATTRIB1DVARBPROC>(get_proc_address("glVertexAttrib1dvARB"));
+ glVertexAttrib1fARB=reinterpret_cast<PFNGLVERTEXATTRIB1FARBPROC>(get_proc_address("glVertexAttrib1fARB"));
+ glVertexAttrib1fvARB=reinterpret_cast<PFNGLVERTEXATTRIB1FVARBPROC>(get_proc_address("glVertexAttrib1fvARB"));
+ glVertexAttrib1sARB=reinterpret_cast<PFNGLVERTEXATTRIB1SARBPROC>(get_proc_address("glVertexAttrib1sARB"));
+ glVertexAttrib1svARB=reinterpret_cast<PFNGLVERTEXATTRIB1SVARBPROC>(get_proc_address("glVertexAttrib1svARB"));
+ glVertexAttrib2dARB=reinterpret_cast<PFNGLVERTEXATTRIB2DARBPROC>(get_proc_address("glVertexAttrib2dARB"));
+ glVertexAttrib2dvARB=reinterpret_cast<PFNGLVERTEXATTRIB2DVARBPROC>(get_proc_address("glVertexAttrib2dvARB"));
+ glVertexAttrib2fARB=reinterpret_cast<PFNGLVERTEXATTRIB2FARBPROC>(get_proc_address("glVertexAttrib2fARB"));
+ glVertexAttrib2fvARB=reinterpret_cast<PFNGLVERTEXATTRIB2FVARBPROC>(get_proc_address("glVertexAttrib2fvARB"));
+ glVertexAttrib2sARB=reinterpret_cast<PFNGLVERTEXATTRIB2SARBPROC>(get_proc_address("glVertexAttrib2sARB"));
+ glVertexAttrib2svARB=reinterpret_cast<PFNGLVERTEXATTRIB2SVARBPROC>(get_proc_address("glVertexAttrib2svARB"));
+ glVertexAttrib3dARB=reinterpret_cast<PFNGLVERTEXATTRIB3DARBPROC>(get_proc_address("glVertexAttrib3dARB"));
+ glVertexAttrib3dvARB=reinterpret_cast<PFNGLVERTEXATTRIB3DVARBPROC>(get_proc_address("glVertexAttrib3dvARB"));
+ glVertexAttrib3fARB=reinterpret_cast<PFNGLVERTEXATTRIB3FARBPROC>(get_proc_address("glVertexAttrib3fARB"));
+ glVertexAttrib3fvARB=reinterpret_cast<PFNGLVERTEXATTRIB3FVARBPROC>(get_proc_address("glVertexAttrib3fvARB"));
+ glVertexAttrib3sARB=reinterpret_cast<PFNGLVERTEXATTRIB3SARBPROC>(get_proc_address("glVertexAttrib3sARB"));
+ glVertexAttrib3svARB=reinterpret_cast<PFNGLVERTEXATTRIB3SVARBPROC>(get_proc_address("glVertexAttrib3svARB"));
+ glVertexAttrib4NbvARB=reinterpret_cast<PFNGLVERTEXATTRIB4NBVARBPROC>(get_proc_address("glVertexAttrib4NbvARB"));
+ glVertexAttrib4NivARB=reinterpret_cast<PFNGLVERTEXATTRIB4NIVARBPROC>(get_proc_address("glVertexAttrib4NivARB"));
+ glVertexAttrib4NsvARB=reinterpret_cast<PFNGLVERTEXATTRIB4NSVARBPROC>(get_proc_address("glVertexAttrib4NsvARB"));
+ glVertexAttrib4NubARB=reinterpret_cast<PFNGLVERTEXATTRIB4NUBARBPROC>(get_proc_address("glVertexAttrib4NubARB"));
+ glVertexAttrib4NubvARB=reinterpret_cast<PFNGLVERTEXATTRIB4NUBVARBPROC>(get_proc_address("glVertexAttrib4NubvARB"));
+ glVertexAttrib4NuivARB=reinterpret_cast<PFNGLVERTEXATTRIB4NUIVARBPROC>(get_proc_address("glVertexAttrib4NuivARB"));
+ glVertexAttrib4NusvARB=reinterpret_cast<PFNGLVERTEXATTRIB4NUSVARBPROC>(get_proc_address("glVertexAttrib4NusvARB"));
+ glVertexAttrib4bvARB=reinterpret_cast<PFNGLVERTEXATTRIB4BVARBPROC>(get_proc_address("glVertexAttrib4bvARB"));
+ glVertexAttrib4dARB=reinterpret_cast<PFNGLVERTEXATTRIB4DARBPROC>(get_proc_address("glVertexAttrib4dARB"));
+ glVertexAttrib4dvARB=reinterpret_cast<PFNGLVERTEXATTRIB4DVARBPROC>(get_proc_address("glVertexAttrib4dvARB"));
+ glVertexAttrib4fARB=reinterpret_cast<PFNGLVERTEXATTRIB4FARBPROC>(get_proc_address("glVertexAttrib4fARB"));
+ glVertexAttrib4fvARB=reinterpret_cast<PFNGLVERTEXATTRIB4FVARBPROC>(get_proc_address("glVertexAttrib4fvARB"));
+ glVertexAttrib4ivARB=reinterpret_cast<PFNGLVERTEXATTRIB4IVARBPROC>(get_proc_address("glVertexAttrib4ivARB"));
+ glVertexAttrib4sARB=reinterpret_cast<PFNGLVERTEXATTRIB4SARBPROC>(get_proc_address("glVertexAttrib4sARB"));
+ glVertexAttrib4svARB=reinterpret_cast<PFNGLVERTEXATTRIB4SVARBPROC>(get_proc_address("glVertexAttrib4svARB"));
+ glVertexAttrib4ubvARB=reinterpret_cast<PFNGLVERTEXATTRIB4UBVARBPROC>(get_proc_address("glVertexAttrib4ubvARB"));
+ glVertexAttrib4uivARB=reinterpret_cast<PFNGLVERTEXATTRIB4UIVARBPROC>(get_proc_address("glVertexAttrib4uivARB"));
+ glVertexAttrib4usvARB=reinterpret_cast<PFNGLVERTEXATTRIB4USVARBPROC>(get_proc_address("glVertexAttrib4usvARB"));
+ glVertexAttribPointerARB=reinterpret_cast<PFNGLVERTEXATTRIBPOINTERARBPROC>(get_proc_address("glVertexAttribPointerARB"));
+ glEnableVertexAttribArrayARB=reinterpret_cast<PFNGLENABLEVERTEXATTRIBARRAYARBPROC>(get_proc_address("glEnableVertexAttribArrayARB"));
+ glDisableVertexAttribArrayARB=reinterpret_cast<PFNGLDISABLEVERTEXATTRIBARRAYARBPROC>(get_proc_address("glDisableVertexAttribArrayARB"));
+ glProgramStringARB=reinterpret_cast<PFNGLPROGRAMSTRINGARBPROC>(get_proc_address("glProgramStringARB"));
+ glBindProgramARB=reinterpret_cast<PFNGLBINDPROGRAMARBPROC>(get_proc_address("glBindProgramARB"));
+ glDeleteProgramsARB=reinterpret_cast<PFNGLDELETEPROGRAMSARBPROC>(get_proc_address("glDeleteProgramsARB"));
+ glGenProgramsARB=reinterpret_cast<PFNGLGENPROGRAMSARBPROC>(get_proc_address("glGenProgramsARB"));
+ glProgramEnvParameter4dARB=reinterpret_cast<PFNGLPROGRAMENVPARAMETER4DARBPROC>(get_proc_address("glProgramEnvParameter4dARB"));
+ glProgramEnvParameter4dvARB=reinterpret_cast<PFNGLPROGRAMENVPARAMETER4DVARBPROC>(get_proc_address("glProgramEnvParameter4dvARB"));
+ glProgramEnvParameter4fARB=reinterpret_cast<PFNGLPROGRAMENVPARAMETER4FARBPROC>(get_proc_address("glProgramEnvParameter4fARB"));
+ glProgramEnvParameter4fvARB=reinterpret_cast<PFNGLPROGRAMENVPARAMETER4FVARBPROC>(get_proc_address("glProgramEnvParameter4fvARB"));
+ glProgramLocalParameter4dARB=reinterpret_cast<PFNGLPROGRAMLOCALPARAMETER4DARBPROC>(get_proc_address("glProgramLocalParameter4dARB"));
+ glProgramLocalParameter4dvARB=reinterpret_cast<PFNGLPROGRAMLOCALPARAMETER4DVARBPROC>(get_proc_address("glProgramLocalParameter4dvARB"));
+ glProgramLocalParameter4fARB=reinterpret_cast<PFNGLPROGRAMLOCALPARAMETER4FARBPROC>(get_proc_address("glProgramLocalParameter4fARB"));
+ glProgramLocalParameter4fvARB=reinterpret_cast<PFNGLPROGRAMLOCALPARAMETER4FVARBPROC>(get_proc_address("glProgramLocalParameter4fvARB"));
+ glGetProgramEnvParameterdvARB=reinterpret_cast<PFNGLGETPROGRAMENVPARAMETERDVARBPROC>(get_proc_address("glGetProgramEnvParameterdvARB"));
+ glGetProgramEnvParameterfvARB=reinterpret_cast<PFNGLGETPROGRAMENVPARAMETERFVARBPROC>(get_proc_address("glGetProgramEnvParameterfvARB"));
+ glGetProgramLocalParameterdvARB=reinterpret_cast<PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC>(get_proc_address("glGetProgramLocalParameterdvARB"));
+ glGetProgramLocalParameterfvARB=reinterpret_cast<PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC>(get_proc_address("glGetProgramLocalParameterfvARB"));
+ glGetProgramivARB=reinterpret_cast<PFNGLGETPROGRAMIVARBPROC>(get_proc_address("glGetProgramivARB"));
+ glGetProgramStringARB=reinterpret_cast<PFNGLGETPROGRAMSTRINGARBPROC>(get_proc_address("glGetProgramStringARB"));
+ glGetVertexAttribdvARB=reinterpret_cast<PFNGLGETVERTEXATTRIBDVARBPROC>(get_proc_address("glGetVertexAttribdvARB"));
+ glGetVertexAttribfvARB=reinterpret_cast<PFNGLGETVERTEXATTRIBFVARBPROC>(get_proc_address("glGetVertexAttribfvARB"));
+ glGetVertexAttribivARB=reinterpret_cast<PFNGLGETVERTEXATTRIBIVARBPROC>(get_proc_address("glGetVertexAttribivARB"));
+ glGetVertexAttribPointervARB=reinterpret_cast<PFNGLGETVERTEXATTRIBPOINTERVARBPROC>(get_proc_address("glGetVertexAttribPointervARB"));
+ glIsProgramARB=reinterpret_cast<PFNGLISPROGRAMARBPROC>(get_proc_address("glIsProgramARB"));
+}
+
+} // namespace GL
+} // namespace Msp
--- /dev/null
+#ifndef MSP_GL_ARB_VERTEX_PROGRAM_
+#define MSP_GL_ARB_VERTEX_PROGRAM_
+
+#include "gl.h"
+#include <GL/glext.h>
+
+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
#include <msp/strings/utils.h>
#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"
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"))
namespace GL {
Mesh::Mesh():
- vertices(NODATA)
+ vertices(VERTEX3)
{ }
Mesh::Mesh(VertexFormat f):
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);
}
Distributed under the LGPL
*/
+#include "arb_vertex_program.h"
#include "extension.h"
#include "gl.h"
#include "version_1_2.h"
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<VertexFormat>(fmt&15));
+ reset(f);
}
VertexArray::~VertexArray()
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<VertexFormat>(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();
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<<t;
offset+=sz;
}
set_array(GL_NORMAL_ARRAY, found&2, 2);
set_array(GL_TEXTURE_COORD_ARRAY, found&4, 4);
set_array(GL_COLOR_ARRAY, found&8, 8);
+ for(unsigned i=4; i<32; ++i)
+ set_array(i-3, (found>>i)&1, 1<<i);
if(vbuf)
VertexBuffer::unbind();
return &*data.end()-stride;
}
-void VertexArray::set_array(unsigned array, unsigned bit, unsigned mask) const
+void VertexArray::set_array(unsigned array, bool en, unsigned mask) const
{
- if((enabled_arrays&mask) && !bit)
+ if((enabled_arrays&mask) && !en)
{
- glDisableClientState(array);
+ if(mask<16)
+ glDisableClientState(array);
+ else
+ glDisableVertexAttribArrayARB(array);
enabled_arrays&=~mask;
}
- else if(!(enabled_arrays&mask) && bit)
+ else if(!(enabled_arrays&mask) && en)
{
- glEnableClientState(array);
+ if(mask<16)
+ glEnableClientState(array);
+ else
+ glEnableVertexAttribArrayARB(array);
enabled_arrays|=mask;
}
}
add("texcoord4", static_cast<void (Loader::*)(float, float, float, float)>(&Loader::texcoord));
add("color3", static_cast<void (Loader::*)(float, float, float)>(&Loader::color));
add("color4", static_cast<void (Loader::*)(float, float, float, float)>(&Loader::color));
+ add("attrib1", static_cast<void (Loader::*)(unsigned, float)>(&Loader::attrib));
+ 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));
}
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<float> &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;
};
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;
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;
u.c[1]=static_cast<ubyte>(cg*255);
u.c[2]=static_cast<ubyte>(cb*255);
u.c[3]=static_cast<ubyte>(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;
}
}
}
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
#ifndef MSP_GL_VERTEXBUILDER_H_
#define MSP_GL_VERTEXBUILDER_H_
+#include <map>
#include "types.h"
namespace Msp {
*/
class VertexBuilder
{
+protected:
+ struct Attrib
+ {
+ float x, y, z, w;
+ };
+
public:
VertexBuilder();
virtual ~VertexBuilder() { }
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<unsigned, Attrib> av;
virtual void vertex_(float, float, float, float) =0;
};
Distributed under the LGPL
*/
+#include <cstring>
+#include <msp/strings/lexicalcast.h>
+#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(*c<ATTRIB1)
+ throw InvalidState("Last component is not a generic attribute");
+ // VertexArray uses an unsigned to store flags for enabled arrays
+ if(i<1 || i>28)
+ 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;
}
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"))
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<unsigned>(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;
namespace Msp {
namespace GL {
-enum VertexFormat
+enum VertexComponent
{
- NODATA=0,
VERTEX2=1,
VERTEX3,
VERTEX4,
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