X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=tools%2Fmesh2c.cpp;fp=tools%2Fmesh2c.cpp;h=864fa936c26a74030cb8c230e20128055db7d594;hp=0000000000000000000000000000000000000000;hb=c6a6dd3d7dced09e84d6e51bb5db32aa7c6f2c56;hpb=a5bf02196c301faea88d54933d0586da0aadb614 diff --git a/tools/mesh2c.cpp b/tools/mesh2c.cpp new file mode 100644 index 00000000..864fa936 --- /dev/null +++ b/tools/mesh2c.cpp @@ -0,0 +1,204 @@ +#include +#include +#include +#include + +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; + bool separate_arrays = false; + GetOpt getopt; + getopt.add_option('p', "prefix", prefix, GetOpt::REQUIRED_ARG); + getopt.add_option('r', "render-func", render_func, GetOpt::NO_ARG); + getopt.add_option('s', "separate-arrays", separate_arrays, GetOpt::NO_ARG); + getopt(argc, argv); + + const vector &args = getopt.get_args(); + if(args.empty()) + { + IO::print(IO::cerr, "Usage: %s [options] \n", argv[0]); + return 1; + } + + GL::Mesh mesh; + mesh.use_buffers(false); + 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(); + unsigned stride = fmt.stride(); + if(separate_arrays) + { + unsigned offset = 0; + for(const unsigned char *i=fmt.begin(); i!=fmt.end(); ++i) + { + unsigned kind = (*i)>>2; + unsigned size = ((*i)&3)+1; + string name; + switch(kind) + { + case 0: + name = "vertex"; + break; + case 1: + name = "normal"; + break; + case 2: + name = "color"; + break; + case 3: + name = "texcoord"; + break; + default: + if(kind<11) + name = format("texcoord%d", kind-3); + else + name = format("attrib%d", kind-11); + break; + } + + IO::print("float %s%s_data[] =\n{", prefix, name); + for(unsigned j=0; j::const_iterator i=mesh.get_batches().begin(); i!=mesh.get_batches().end(); ++i) + { + unsigned count = i->size(); + for(unsigned j=0; jget_index(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; + string source = format("%svertex_data+%d", prefix, offset); + switch((*i)>>2) + { + case 0: + if(separate_arrays) + source = prefix+"vertex_data"; + IO::print("\tglVertexPointer(%d, GL_FLOAT, %d*sizeof(float), %s);\n", + size, stride, source); + IO::print("\tglEnableClientState(GL_VERTEX_ARRAY);\n"); + break; + case 1: + if(separate_arrays) + source = prefix+"normal_data"; + IO::print("\tglNormalPointer(GL_FLOAT, %d*sizeof(float), %s);\n", + stride, source); + IO::print("\tglEnableClientState(GL_NORMAL_ARRAY);\n"); + break; + case 2: + if(separate_arrays) + source = prefix+"color_data"; + IO::print("\tglColorPointer(%d, GL_FLOAT, %d*sizeof(float), %s);\n", + size, stride, source); + IO::print("\tglEnableClientState(GL_COLOR_ARRAY);\n"); + break; + case 3: + if(separate_arrays) + source = prefix+"texcoord_data"; + IO::print("\tglTexCoordPointer(%d, GL_FLOAT, %d*sizeof(float), %s);\n", + size, stride, source); + IO::print("\tglEnableClientState(GL_TEXTURE_COORD_ARRAY);\n"); + break; + default: + if(kind<11) + { + if(separate_arrays) + source = format("%stexcoord%d_data", prefix, kind-3); + IO::print("\tglClientActiveTexture(GL_TEXTURE%d);\n", kind-3); + IO::print("\tglTexCoordPointer(%d, GL_FLOAT, %d*sizeof(float), %s);\n", + size, stride, source); + IO::print("\tglEnableClientState(GL_TEXTURE_COORD_ARRAY);\n"); + } + else + { + if(separate_arrays) + source = format("%sattrib%d_data", prefix, kind-11); + IO::print("\tglVertexAttribPointer(%d, %d, GL_FLOAT, GL_FALSE, %d*sizeof(float), %s);\n", + kind-11, size, stride, source); + IO::print("\tglEnableVertexAttribArray(%d);\n", kind-11); + } + break; + } + offset += size; + } + offset = 0; + for(list::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->size(), type[1], prefix, offset); + offset += i->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; +}