1 #include <msp/core/getopt.h>
2 #include <msp/gl/mesh.h>
3 #include <msp/io/print.h>
4 #include <msp/strings/format.h>
11 "unsigned char", "GL_UNSIGNED_BYTE",
12 "unsigned short", "GL_UNSIGNED_SHORT",
13 "unsigned", "GL_UNSIGNED_INT"
16 int main(int argc, char **argv)
19 bool render_func = false;
20 bool separate_arrays = false;
22 getopt.add_option('p', "prefix", prefix, GetOpt::REQUIRED_ARG);
23 getopt.add_option('r', "render-func", render_func, GetOpt::NO_ARG);
24 getopt.add_option('s', "separate-arrays", separate_arrays, GetOpt::NO_ARG);
27 const vector<string> &args = getopt.get_args();
30 IO::print(IO::cerr, "Usage: %s [options] <meshfile>\n", argv[0]);
35 mesh.use_buffers(false);
36 DataFile::load(mesh, args[0]);
38 IO::print("/* Exported from %s */\n", args[0]);
40 const GL::VertexArray &array = mesh.get_vertices();
41 const GL::VertexFormat &fmt = array.get_format();
42 unsigned stride = fmt.stride();
46 for(const unsigned char *i=fmt.begin(); i!=fmt.end(); ++i)
48 unsigned kind = (*i)>>2;
49 unsigned size = ((*i)&3)+1;
67 name = format("texcoord%d", kind-3);
69 name = format("attrib%d", kind-11);
73 IO::print("float %s%s_data[] =\n{", prefix, name);
74 for(unsigned j=0; j<array.size(); ++j)
76 const float *ptr = array[j]+offset;
78 for(unsigned k=0; k<size; ++k)
79 IO::print("%g, ", ptr[k]);
81 IO::print("\n};\n\n");
88 IO::print("float %svertex_data[] =\n{", prefix);
89 for(unsigned i=0; i<array.size(); ++i)
91 const float *ptr = array[i];
93 for(unsigned j=0; j<stride; ++j)
94 IO::print("%g, ", ptr[j]);
96 IO::print("\n};\n\n");
99 const char **type = 0;
100 if(array.size()<0x100)
102 else if(array.size()<0x10000)
107 IO::print("%s %sindices[] =\n{", type[0], prefix);
108 for(list<GL::Batch>::const_iterator i=mesh.get_batches().begin(); i!=mesh.get_batches().end(); ++i)
110 unsigned count = i->size();
111 for(unsigned j=0; j<count; ++j)
115 IO::print("%d, ", i->get_index(j));
118 IO::print("\n};\n\n");
121 IO::print("void %srender()\n{\n", prefix);
123 IO::print("/*\nTo render the object, #include this file and add the following code:\n");
125 for(const unsigned char *i=fmt.begin(); i!=fmt.end(); ++i)
127 unsigned kind = (*i)>>2;
128 unsigned size = ((*i)&3)+1;
129 string source = format("%svertex_data+%d", prefix, offset);
134 source = prefix+"vertex_data";
135 IO::print("\tglVertexPointer(%d, GL_FLOAT, %d*sizeof(float), %s);\n",
136 size, stride, source);
137 IO::print("\tglEnableClientState(GL_VERTEX_ARRAY);\n");
141 source = prefix+"normal_data";
142 IO::print("\tglNormalPointer(GL_FLOAT, %d*sizeof(float), %s);\n",
144 IO::print("\tglEnableClientState(GL_NORMAL_ARRAY);\n");
148 source = prefix+"color_data";
149 IO::print("\tglColorPointer(%d, GL_FLOAT, %d*sizeof(float), %s);\n",
150 size, stride, source);
151 IO::print("\tglEnableClientState(GL_COLOR_ARRAY);\n");
155 source = prefix+"texcoord_data";
156 IO::print("\tglTexCoordPointer(%d, GL_FLOAT, %d*sizeof(float), %s);\n",
157 size, stride, source);
158 IO::print("\tglEnableClientState(GL_TEXTURE_COORD_ARRAY);\n");
164 source = format("%stexcoord%d_data", prefix, kind-3);
165 IO::print("\tglClientActiveTexture(GL_TEXTURE%d);\n", kind-3);
166 IO::print("\tglTexCoordPointer(%d, GL_FLOAT, %d*sizeof(float), %s);\n",
167 size, stride, source);
168 IO::print("\tglEnableClientState(GL_TEXTURE_COORD_ARRAY);\n");
173 source = format("%sattrib%d_data", prefix, kind-11);
174 IO::print("\tglVertexAttribPointer(%d, %d, GL_FLOAT, GL_FALSE, %d*sizeof(float), %s);\n",
175 kind-11, size, stride, source);
176 IO::print("\tglEnableVertexAttribArray(%d);\n", kind-11);
183 for(list<GL::Batch>::const_iterator i=mesh.get_batches().begin(); i!=mesh.get_batches().end(); ++i)
186 switch(i->get_type())
188 case GL_TRIANGLE_STRIP: mode = "GL_TRIANGLE_STRIP"; break;
189 case GL_TRIANGLES: mode = "GL_TRIANGLES"; break;
190 default: mode = format("%d", i->get_type()); break;
192 IO::print("\tglDrawElements(%s, %d, %s, %sindices+%d);\n", mode, i->size(), type[1], prefix, offset);
198 IO::print("/* To render this object, #include this file and call %srender() */\n", prefix);