From 3f285d3f4fd0a6790bf1efa780284dc7ba2287a2 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 1 Oct 2007 10:45:30 +0000 Subject: [PATCH] Add mult_matrix functions Finish shader classes Blender exporter: Fix triangle strip generation --- mesh_export.py | 65 ++++++++++++++--------- source/matrix.cpp | 10 ++++ source/matrix.h | 2 + source/mesh.cpp | 4 +- source/program.cpp | 109 ++++++++++++++++++++++++++++++++++++++- source/program.h | 42 ++++++++++++--- source/projection.cpp | 2 +- source/shader.cpp | 12 ++++- source/shader.h | 1 + source/simpleprogram.cpp | 33 ------------ source/simpleprogram.h | 30 ----------- 11 files changed, 211 insertions(+), 99 deletions(-) delete mode 100644 source/simpleprogram.cpp delete mode 100644 source/simpleprogram.h diff --git a/mesh_export.py b/mesh_export.py index 6b50a4ec..d7531b36 100644 --- a/mesh_export.py +++ b/mesh_export.py @@ -61,19 +61,13 @@ class Face: def __getattr__(self, attr): return getattr(self._mface, attr) - def get_following_vertex(self, *vt): - seen=False - indices=[v.index for v in vt] - for v in self.verts: - if v.index in indices: - seen=True - elif seen: - return v - - if seen: - return self.verts[0] - - return None + def get_vertices_from(self, *vt): + indices=[u.index for u in vt] + flags=[(v.index in indices) for v in self.verts] + l=len(self.verts) + for i in range(l): + if flags[i] and not flags[(i+l-1)%l]: + return self.verts[i:]+self.verts[:i] class SmoothGroup: @@ -107,6 +101,7 @@ class Exporter: self.out_file=file(fn, "w") self.use_strips=True self.use_degen_tris=True + self.debug=False def find_smooth_group(self, face, sg): face.smooth_group=sg @@ -133,18 +128,24 @@ class Exporter: if not edge: return None - v1=face.get_following_vertex(edge.v1, edge.v2) - v2=face.get_following_vertex(v1) - if len(face.verts)==4: - result=[v2, v1] - else: - result=[v1, v2] + if self.debug: + print "Starting strip from %s"%[v.index for v in face.verts] + + verts=face.get_vertices_from(edge.v1, edge.v2) + result=[verts[-2], verts[-1]] while 1: + verts=face.get_vertices_from(*result[-2:]) + k=len(result)%2 + if self.debug: + print " %d %s"%(len(result), [v.index for v in verts]) + face.flag=True - for i in range(2, len(face.verts)): - v=face.get_following_vertex(result[-2], result[-1]) - result.append(v) + if len(verts)==4 and not k: + result.append(verts[3]) + result.append(verts[2]) + if len(verts)==4 and k: + result.append(verts[3]) i1=result[-2].index i2=result[-1].index @@ -155,10 +156,13 @@ class Exporter: break next=edge.other_face(face) - if next.smooth_group.index!=face.smooth_group.index or next.flag: + if not next or next.smooth_group.index!=face.smooth_group.index or next.flag: break face=next + if self.debug: + print " %s"%[v.index for v in result] + return result def export(self): @@ -182,6 +186,9 @@ class Exporter: for e in edges.itervalues(): e.check_smooth(smooth_limit) + if self.debug: + print "%d faces, %d edges"%(len(faces), len(edges)) + smooth_groups=[] for f in faces: if not f.smooth_group: @@ -192,6 +199,12 @@ class Exporter: for sg in smooth_groups: sg.find_vertices() + if self.debug: + print "%d smooth groups:" + for i in range(len(smooth_groups)): + sg=smooth_groups[i] + print " %d: %d faces, %d vertices"%(i, len(sg.faces), len(sg.verts)) + strips=[] if self.use_strips: for sg in smooth_groups: @@ -226,8 +239,11 @@ class Exporter: verts.append(v) self.out_file.write("vertices NORMAL3_VERTEX3\n{\n") + norm=None for v in verts: - self.out_file.write("\tnormal3 %f %f %f;\n"%tuple(v.no)) + if v.no!=norm: + self.out_file.write("\tnormal3 %f %f %f;\n"%tuple(v.no)) + norm=v.no self.out_file.write("\tvertex3 %f %f %f;\n"%tuple(v.co)) self.out_file.write("};\n") for s in strips: @@ -259,6 +275,7 @@ class FrontEnd: def export(self, fn): exp=Exporter(fn) + #exp.use_degen_tris=False exp.export() diff --git a/source/matrix.cpp b/source/matrix.cpp index 925961b4..dc855d2b 100644 --- a/source/matrix.cpp +++ b/source/matrix.cpp @@ -13,6 +13,16 @@ void load_identity() glLoadIdentity(); } +void mult_matrix(const float *matrix) +{ + glMultMatrixf(matrix); +} + +void mult_matrix(const double *matrix) +{ + glMultMatrixd(matrix); +} + void push_matrix() { glPushMatrix(); diff --git a/source/matrix.h b/source/matrix.h index 7dd08f23..b4cc339c 100644 --- a/source/matrix.h +++ b/source/matrix.h @@ -22,6 +22,8 @@ enum MatrixMode void matrix_mode(MatrixMode); void load_identity(); +void mult_matrix(const float *); +void mult_matrix(const double *); void push_matrix(); void pop_matrix(); diff --git a/source/mesh.cpp b/source/mesh.cpp index 2f2a29b1..4e671e03 100644 --- a/source/mesh.cpp +++ b/source/mesh.cpp @@ -14,7 +14,9 @@ namespace GL { Mesh::Mesh(): vertices(NODATA) -{ } +{ + vertices.use_vertex_buffer(); +} void Mesh::draw() const { diff --git a/source/program.cpp b/source/program.cpp index 1d08270f..e0a685f1 100644 --- a/source/program.cpp +++ b/source/program.cpp @@ -6,6 +6,7 @@ Distributed under the LGPL */ #define GL_GLEXT_PROTOTYPES +#include "error.h" #include "program.h" #include "shader.h" @@ -14,13 +15,29 @@ using namespace std; namespace Msp { namespace GL { -Program::Program() +Program::Program(): + id(glCreateProgram()), + del_shaders(false), + linked(false) +{ } + +Program::Program(const string &vert, const string &frag): + id(glCreateProgram()), + del_shaders(true), + linked(false) { - id=glCreateProgram(); + attach_shader(*new Shader(VERTEX_SHADER, vert)); + attach_shader(*new Shader(FRAGMENT_SHADER, frag)); + link(); } Program::~Program() { + if(del_shaders) + { + for(list::iterator i=shaders.begin(); i!=shaders.end(); ++i) + delete *i; + } glDeleteProgram(id); } @@ -43,6 +60,11 @@ void Program::detach_shader(Shader &shader) } } +void Program::set_del_shaders(bool ds) +{ + del_shaders=ds; +} + void Program::bind_attribute(int index, const string &name) { glBindAttribLocation(id, index, name.c_str()); @@ -74,5 +96,88 @@ string Program::get_info_log() const return string(log, len); } +void Program::bind() +{ + if(!linked) + throw InvalidState("Program is not linked"); + + glUseProgram(id); + cur_prog=this; +} + +int Program::get_uniform_location(const string &n) const +{ + return glGetUniformLocation(id, n.c_str()); +} + +void Program::uniform(int i, int v) +{ + glUniform1i(i, v); +} + +void Program::uniform(int i, float x) +{ + glUniform1f(i, x); +} + +void Program::uniform(int i, float x, float y) +{ + glUniform2f(i, x, y); +} + +void Program::uniform(int i, float x, float y, float z) +{ + glUniform3f(i, x, y, z); +} + +void Program::uniform(int i, float x, float y, float z, float w) +{ + glUniform4f(i, x, y, z, w); +} + +void Program::uniform_matrix4(int i, const float *v) +{ + glUniformMatrix4fv(i, 1, false, v); +} + +void Program::unbind() +{ + glUseProgram(0); + cur_prog=0; +} + +void Program::maybe_bind() +{ + if(cur_prog!=this) + bind(); +} + +Program *Program::cur_prog=0; + + +Program::Loader::Loader(Program &p): + prog(p) +{ + prog.set_del_shaders(true); + + add("vertex_shader", &Loader::vertex_shader); + add("fragment_shader", &Loader::fragment_shader); +} + +Program::Loader::~Loader() +{ + prog.link(); +} + +void Program::Loader::vertex_shader(const string &src) +{ + prog.attach_shader(*new Shader(VERTEX_SHADER, src)); +} + +void Program::Loader::fragment_shader(const string &src) +{ + prog.attach_shader(*new Shader(FRAGMENT_SHADER, src)); +} + } // namespace GL } // namespace Msp diff --git a/source/program.h b/source/program.h index a77a70d7..f007fb3a 100644 --- a/source/program.h +++ b/source/program.h @@ -11,7 +11,7 @@ Distributed under the LGPL #include #include #include -#include "shader.h" +#include #include "types.h" namespace Msp { @@ -21,25 +21,55 @@ class Shader; class Program { +private: + uint id; + std::list shaders; + bool del_shaders; + bool linked; + + static Program *cur_prog; + public: + class Loader: public DataFile::Loader + { + private: + Program &prog; + + public: + Loader(Program &); + ~Loader(); + + private: + void vertex_shader(const std::string &); + void fragment_shader(const std::string &); + }; + Program(); + Program(const std::string &, const std::string &); virtual ~Program(); void attach_shader(Shader &shader); void detach_shader(Shader &shader); + const std::list &get_shaders() const { return shaders; } + void set_del_shaders(bool); void bind_attribute(int, const std::string &); bool link(); int get_param(GLenum param) const; + bool get_linked() const { return linked; } std::string get_info_log() const; void bind(); + int get_uniform_location(const std::string &) const; + void uniform(int, int); + void uniform(int, float); + void uniform(int, float, float); + void uniform(int, float, float, float); + void uniform(int, float, float, float, float); + void uniform_matrix4(int, const float *); static void unbind(); -private: - uint id; - std::list shaders; - bool linked; - static Program *cur_prog; +private: + void maybe_bind(); }; } // namespace GL diff --git a/source/projection.cpp b/source/projection.cpp index 1b7fa61f..3a8baf84 100644 --- a/source/projection.cpp +++ b/source/projection.cpp @@ -29,7 +29,7 @@ void ortho_bottomleft(double width, double height) void ortho_topleft(double width, double height) { - ortho(0, width, -height, 0, 0, 1); + ortho(0, width, height, 0, 0, 1); } void frustum(double left, double right, double bottom, double top, double near, double far) diff --git a/source/shader.cpp b/source/shader.cpp index ac604630..61c2f0e5 100644 --- a/source/shader.cpp +++ b/source/shader.cpp @@ -13,9 +13,17 @@ using namespace std; namespace Msp { namespace GL { -Shader::Shader(ShaderType t) +Shader::Shader(ShaderType t): + id(glCreateShader(t)), + compiled(false) +{ } + +Shader::Shader(ShaderType t, const string &src): + id(glCreateShader(t)), + compiled(false) { - id=glCreateShader(t); + source(src); + compile(); } Shader::~Shader() diff --git a/source/shader.h b/source/shader.h index 4e02b084..43d03ce1 100644 --- a/source/shader.h +++ b/source/shader.h @@ -25,6 +25,7 @@ class Shader { public: Shader(ShaderType t); + Shader(ShaderType t, const std::string &); ~Shader(); void source(sizei count, const char **str, const int *len); diff --git a/source/simpleprogram.cpp b/source/simpleprogram.cpp deleted file mode 100644 index b7bc5edc..00000000 --- a/source/simpleprogram.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* $Id$ - -This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - -#include "simpleprogram.h" - -using namespace std; - -namespace Msp { -namespace GL { - -SimpleProgram::SimpleProgram(const string &vert_src, const string &frag_src): - vert_shader(VERTEX_SHADER), - frag_shader(FRAGMENT_SHADER) -{ - vert_shader.source(vert_src); - frag_shader.source(frag_src); - attach_shader(vert_shader); - attach_shader(frag_shader); - link(); -} - -SimpleProgram::~SimpleProgram() -{ - detach_shader(vert_shader); - detach_shader(frag_shader); -} - -} // namespace GL -} // namespace Msp diff --git a/source/simpleprogram.h b/source/simpleprogram.h deleted file mode 100644 index aeebb88f..00000000 --- a/source/simpleprogram.h +++ /dev/null @@ -1,30 +0,0 @@ -/* $Id$ - -This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - -#ifndef MSP_GL_SIMPLEPROGRAM_H_ -#define MSP_GL_SIMPLEPROGRAM_H_ - -#include "program.h" -#include "shader.h" - -namespace Msp { -namespace GL { - -class SimpleProgram: public Program -{ -public: - SimpleProgram(const std::string &vert_src, const std::string &frag_src); - ~SimpleProgram(); -private: - Shader vert_shader; - Shader frag_shader; -}; - -} // namespace GL -} // namespace Msp - -#endif -- 2.45.2