]> git.tdb.fi Git - libs/gl.git/blob - mesh2c.cpp
Support different data types in Batch
[libs/gl.git] / mesh2c.cpp
1 /* $Id$
2
3 This file is part of libmspgl
4 Copyright © 2010  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <msp/core/getopt.h>
9 #include <msp/gl/mesh.h>
10 #include <msp/io/print.h>
11 #include <msp/strings/formatter.h>
12
13 using namespace std;
14 using namespace Msp;
15
16 const char *types[] =
17 {
18         "unsigned char", "GL_UNSIGNED_BYTE",
19         "unsigned short", "GL_UNSIGNED_SHORT",
20         "unsigned", "GL_UNSIGNED_INT"
21 };
22
23 int main(int argc, char **argv)
24 {
25         string prefix;
26         bool render_func = false;
27         GetOpt getopt;
28         getopt.add_option('p', "prefix",      prefix,      GetOpt::REQUIRED_ARG);
29         getopt.add_option('r', "render-func", render_func, GetOpt::NO_ARG);
30         getopt(argc, argv);
31
32         const vector<string> &args = getopt.get_args();
33         if(args.empty())
34         {
35                 IO::print(IO::cerr, "Usage: %s [options] <meshfile>\n", argv[0]);
36                 return 1;
37         }
38
39         GL::Mesh mesh;
40         DataFile::load(mesh, args[0]);
41
42         IO::print("/* Exported from %s */\n", args[0]);
43
44         const GL::VertexArray &array = mesh.get_vertices();
45         const GL::VertexFormat &fmt = array.get_format();
46         IO::print("float %svertex_data[] =\n{", prefix);
47         unsigned stride = fmt.stride();
48         for(unsigned i=0; i<array.size(); ++i)
49         {
50                 const float *ptr = array[i];
51                 IO::print("\n\t");
52                 for(unsigned j=0; j<stride; ++j)
53                         IO::print("%g, ", ptr[j]);
54         }
55         IO::print("\n};\n\n");
56
57         const char **type = 0;
58         if(array.size()<0x100)
59                 type = types;
60         else if(array.size()<0x10000)
61                 type = types+2;
62         else
63                 type = types+4;
64
65         IO::print("%s %sindices[] =\n{", type[0], prefix);
66         for(list<GL::Batch>::const_iterator i=mesh.get_batches().begin(); i!=mesh.get_batches().end(); ++i)
67         {
68                 unsigned count = i->size();
69                 for(unsigned j=0; j<count; ++j)
70                 {
71                         if(j%16==0)
72                                 IO::print("\n\t");
73                         IO::print("%d, ", i->get_index(j));
74                 }
75         }
76         IO::print("\n};\n\n");
77
78         if(render_func)
79                 IO::print("void %srender()\n{\n", prefix);
80         else
81                 IO::print("/*\nTo render the object, #include this file and add the following code:\n");
82         unsigned offset = 0;
83         for(const unsigned char *i=fmt.begin(); i!=fmt.end(); ++i)
84         {
85                 unsigned kind = (*i)>>2;
86                 unsigned size = ((*i)&3)+1;
87                 switch((*i)>>2)
88                 {
89                 case 0:
90                         IO::print("\tglVertexPointer(%d, GL_FLOAT, %d*sizeof(float), %svertex_data+%d);\n",
91                                 size, stride, prefix, offset);
92                         IO::print("\tglEnableClientState(GL_VERTEX_ARRAY);\n");
93                         break;
94                 case 1:
95                         IO::print("\tglNormalPointer(GL_FLOAT, %d*sizeof(float), %svertex_data+%d);\n",
96                                 stride, prefix, offset);
97                         IO::print("\tglEnableClientState(GL_NORMAL_ARRAY);\n");
98                         break;
99                 case 2:
100                         IO::print("\tglTexCoordPointer(%d, GL_FLOAT, %d*sizeof(float), %svertex_data+%d);\n",
101                                 size, stride, prefix, offset);
102                         IO::print("\tglEnableClientState(GL_TEXTURE_COORD_ARRAY);\n");
103                         break;
104                 case 3:
105                         IO::print("\tglColorPointer(%d, GL_FLOAT, %d*sizeof(float), %svertex_data+%d);\n",
106                                 size, stride, prefix, offset);
107                         IO::print("\tglEnableClientState(GL_COLOR_ARRAY);\n");
108                         break;
109                 default:
110                         IO::print("\tglVertexAttribPointer(%d, %d, GL_FLOAT, GL_FALSE, %d*sizeof(float), %svertex_data+%d);\n",
111                                 kind-4, size, stride, prefix, offset);
112                         IO::print("\tglEnableVertexAttribArray(%d);\n", kind-4);
113                         break;
114                 }
115                 offset += size;
116         }
117         offset = 0;
118         for(list<GL::Batch>::const_iterator i=mesh.get_batches().begin(); i!=mesh.get_batches().end(); ++i)
119         {
120                 string mode;
121                 switch(i->get_type())
122                 {
123                 case GL_TRIANGLE_STRIP: mode = "GL_TRIANGLE_STRIP"; break;
124                 case GL_TRIANGLES: mode = "GL_TRIANGLES"; break;
125                 default: mode = format("%d", i->get_type()); break;
126                 }
127                 IO::print("\tglDrawElements(%s, %d, %s, %sindices+%d);\n", mode, i->size(), type[1], prefix, offset);
128                 offset += i->size();
129         }
130         if(render_func)
131         {
132                 IO::print("}\n\n");
133                 IO::print("/* To render this object, #include this file and call %srender() */\n", prefix);
134         }
135         else
136                 IO::print("*/\n");
137
138         return 0;
139 }