]> git.tdb.fi Git - libs/gl.git/commitdiff
Add a tool to convert a mesh into C code
authorMikko Rasa <tdb@tdb.fi>
Thu, 4 Feb 2010 07:43:30 +0000 (07:43 +0000)
committerMikko Rasa <tdb@tdb.fi>
Thu, 4 Feb 2010 07:43:30 +0000 (07:43 +0000)
Add Batch::get_type() accessor
Make get_stride a member of VertexFormat
Add a #define GLX_GLXEXT_PROTOTYPES to allow compilation against Mesa

Build
mesh2c.cpp [new file with mode: 0644]
source/batch.h
source/extension.cpp
source/vertexformat.cpp
source/vertexformat.h

diff --git a/Build b/Build
index 7e98f4c724343e4cad002181e5f4ffcb4ae02976..715969236ad3c787f34602b0d997ff9ba57bcddb 100644 (file)
--- a/Build
+++ b/Build
@@ -21,6 +21,15 @@ package "mspgl"
                install true;
        };
 
+       program "mesh2c"
+       {
+               source "mesh2c.cpp";
+               build_info
+               {
+                       library "mspgl";
+               };
+       };
+
        tarball "@src"
        {
                source "License.txt";
diff --git a/mesh2c.cpp b/mesh2c.cpp
new file mode 100644 (file)
index 0000000..be72fd4
--- /dev/null
@@ -0,0 +1,139 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2010  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <msp/core/getopt.h>
+#include <msp/gl/mesh.h>
+#include <msp/io/print.h>
+#include <msp/strings/formatter.h>
+
+using namespace std;
+using namespace Msp;
+
+const char *types[] =
+{
+       "unsigned char", "GL_UNSIGNED_BYTE",
+       "unsigned short", "GL_UNSIGNED_SHORT",
+       "unsigned", "GL_UNSIGNED_INT"
+};
+
+int main(int argc, char **argv)
+{
+       string prefix;
+       bool render_func = false;
+       GetOpt getopt;
+       getopt.add_option('p', "prefix",      prefix,      GetOpt::REQUIRED_ARG);
+       getopt.add_option('r', "render-func", render_func, GetOpt::NO_ARG);
+       getopt(argc, argv);
+
+       const vector<string> &args = getopt.get_args();
+       if(args.empty())
+       {
+               IO::print(IO::cerr, "Usage: %s [options] <meshfile>\n", argv[0]);
+               return 1;
+       }
+
+       GL::Mesh mesh;
+       DataFile::load(mesh, args[0]);
+
+       IO::print("/* Exported from %s */\n", args[0]);
+
+       const GL::VertexArray &array = mesh.get_vertices();
+       const GL::VertexFormat &fmt = array.get_format();
+       IO::print("float %svertex_data[] =\n{", prefix);
+       unsigned stride = fmt.stride();
+       for(unsigned i=0; i<array.size(); ++i)
+       {
+               const float *ptr = array[i];
+               IO::print("\n\t");
+               for(unsigned j=0; j<stride; ++j)
+                       IO::print("%g, ", ptr[j]);
+       }
+       IO::print("\n};\n\n");
+
+       const char **type = 0;
+       if(array.size()<0x100)
+               type = types;
+       else if(array.size()<0x10000)
+               type = types+2;
+       else
+               type = types+4;
+
+       IO::print("%s %sindices[] =\n{", type[0], prefix);
+       for(list<GL::Batch>::const_iterator i=mesh.get_batches().begin(); i!=mesh.get_batches().end(); ++i)
+       {
+               const vector<unsigned> &indices = i->get_indices();
+               for(unsigned j=0; j<indices.size(); ++j)
+               {
+                       if(j%16==0)
+                               IO::print("\n\t");
+                       IO::print("%d, ", indices[j]);
+               }
+       }
+       IO::print("\n};\n\n");
+
+       if(render_func)
+               IO::print("void %srender()\n{\n", prefix);
+       else
+               IO::print("/*\nTo render the object, #include this file and add the following code:\n");
+       unsigned offset = 0;
+       for(const unsigned char *i=fmt.begin(); i!=fmt.end(); ++i)
+       {
+               unsigned kind = (*i)>>2;
+               unsigned size = ((*i)&3)+1;
+               switch((*i)>>2)
+               {
+               case 0:
+                       IO::print("\tglVertexPointer(%d, GL_FLOAT, %d*sizeof(float), %svertex_data+%d);\n",
+                               size, stride, prefix, offset);
+                       IO::print("\tglEnableClientState(GL_VERTEX_ARRAY);\n");
+                       break;
+               case 1:
+                       IO::print("\tglNormalPointer(GL_FLOAT, %d*sizeof(float), %svertex_data+%d);\n",
+                               stride, prefix, offset);
+                       IO::print("\tglEnableClientState(GL_NORMAL_ARRAY);\n");
+                       break;
+               case 2:
+                       IO::print("\tglTexCoordPointer(%d, GL_FLOAT, %d*sizeof(float), %svertex_data+%d);\n",
+                               size, stride, prefix, offset);
+                       IO::print("\tglEnableClientState(GL_TEXTURE_COORD_ARRAY);\n");
+                       break;
+               case 3:
+                       IO::print("\tglColorPointer(%d, GL_FLOAT, %d*sizeof(float), %svertex_data+%d);\n",
+                               size, stride, prefix, offset);
+                       IO::print("\tglEnableClientState(GL_COLOR_ARRAY);\n");
+                       break;
+               default:
+                       IO::print("\tglVertexAttribPointer(%d, %d, GL_FLOAT, GL_FALSE, %d*sizeof(float), %svertex_data+%d);\n",
+                               kind-4, size, stride, prefix, offset);
+                       IO::print("\tglEnableVertexAttribArray(%d);\n", kind-4);
+                       break;
+               }
+               offset += size;
+       }
+       offset = 0;
+       for(list<GL::Batch>::const_iterator i=mesh.get_batches().begin(); i!=mesh.get_batches().end(); ++i)
+       {
+               string mode;
+               switch(i->get_type())
+               {
+               case GL_TRIANGLE_STRIP: mode = "GL_TRIANGLE_STRIP"; break;
+               case GL_TRIANGLES: mode = "GL_TRIANGLES"; break;
+               default: mode = format("%d", i->get_type()); break;
+               }
+               IO::print("\tglDrawElements(%s, %d, %s, %sindices+%d);\n", mode, i->get_indices().size(), type[1], prefix, offset);
+               offset += i->get_indices().size();
+       }
+       if(render_func)
+       {
+               IO::print("}\n\n");
+               IO::print("/* To render this object, #include this file and call %srender() */\n", prefix);
+       }
+       else
+               IO::print("*/\n");
+
+       return 0;
+}
index 9b2072de1f13d6f56e819a759fa3a1f6b3623491..6950af894898b93bc576df783a7c9cb857635ac4 100644 (file)
@@ -1,7 +1,7 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007, 2009-2010 Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
@@ -39,6 +39,7 @@ public:
        Batch(PrimitiveType t);
        Batch &append(uint);
        void append(const std::vector<uint> &);
+       PrimitiveType get_type() const { return type; }
        unsigned size() const { return indices.size(); }
        const std::vector<uint> &get_indices() const { return indices; }
        void draw() const;
index 6383cd3cee75a524853c1646f193e6795677a2f4..cd8c6297759d57494d8f372276e8a467a6d12d85 100644 (file)
@@ -1,12 +1,13 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Copyright © 2007, 2009-2010  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
 #include <set>
 #ifndef WIN32
+#define GLX_GLXEXT_PROTOTYPES
 #include <GL/glx.h>
 #endif
 #include <msp/strings/formatter.h>
index b9bd7b9402414f16ad3b0c70d11a835b12ef9c3f..457cffad2724548cc31577fc0267e2c368ec421b 100644 (file)
@@ -1,7 +1,7 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2007-2009  Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2010  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
@@ -55,6 +55,14 @@ VertexFormat::~VertexFormat()
        delete[] data;
 }
 
+unsigned VertexFormat::stride() const
+{
+       uint s=0;
+       for(const unsigned char *i=begin(); i!=end(); ++i)
+               s+=(*i&3)+1;
+       return s;
+}
+
 VertexFormat operator,(const VertexFormat &f, VertexComponent c)
 {
        VertexFormat r=f;
@@ -96,14 +104,6 @@ VertexFormat operator,(const VertexFormat &f, unsigned i)
        return r;
 }
 
-uint get_stride(const VertexFormat &f)
-{
-       uint stride=0;
-       for(const unsigned char *i=f.begin(); i!=f.end(); ++i)
-               stride+=(*i&3)+1;
-       return stride;
-}
-
 istream &operator>>(istream &in, VertexFormat &f)
 {
        string str;
index 2432d7b60d54aec2fbf8e478cdfec5ff8971f90f..75e33473227f542f9b856027349c6503d4361e96 100644 (file)
@@ -1,7 +1,7 @@
 /* $Id$
 
 This file is part of libmspgl
-Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Copyright © 2007, 2009-2010  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
@@ -46,6 +46,7 @@ struct 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; }
+       unsigned stride() const;
 };
 
 VertexFormat operator,(const VertexFormat &f, VertexComponent c);
@@ -56,7 +57,9 @@ VertexFormat operator,(const VertexFormat &f, unsigned i);
 inline VertexFormat operator,(VertexComponent c, unsigned i)
 { return (VertexFormat(c), i); }
 
-uint get_stride(const VertexFormat &);
+inline uint get_stride(const VertexFormat &f)
+{ return f.stride(); }
+
 std::istream &operator>>(std::istream &, VertexFormat &);
 
 } // namespace GL