diff options
-rw-r--r-- | opengl/GNUmakefile | 9 | ||||
-rw-r--r-- | opengl/config.cpp | 6 | ||||
-rw-r--r-- | opengl/config.h | 4 | ||||
-rw-r--r-- | opengl/dialog.h | 1 | ||||
-rw-r--r-- | opengl/dialog.rc | 42 | ||||
-rw-r--r-- | opengl/generate.cpp | 496 | ||||
-rw-r--r-- | opengl/generate.h | 20 | ||||
-rw-r--r-- | opengl/gldialog.cpp | 6 | ||||
-rw-r--r-- | opengl/gldialog.h | 1 | ||||
-rw-r--r-- | opengl/main.cpp | 4 |
10 files changed, 329 insertions, 260 deletions
diff --git a/opengl/GNUmakefile b/opengl/GNUmakefile index 700fb6d..5b9b2c9 100644 --- a/opengl/GNUmakefile +++ b/opengl/GNUmakefile @@ -18,7 +18,7 @@ # # ------------------------------------------------------------------------- # -# $Id: GNUmakefile,v 1.3 2005-04-18 01:01:56 ianc Exp $ +# $Id: GNUmakefile,v 1.4 2005-04-24 01:44:48 ianc Exp $ # include ../make.conf @@ -56,11 +56,8 @@ $(OUTDLL): $(OBJECTS) # Unfortunately the windres resource compiler doesn't like my RC, so you # need RC.EXE from the Platform SDK to compile it to a RES first. # -$(RES).o: $(RES).res - windres -i $(RES).res -o $(RES).o - -$(RES).res: $(RES).rc $(RES).h - rc $(RES).rc +$(RES).o: $(RES).rc + windres -i $(RES).rc -o $(RES).o %.o: %.cpp $(CXX) -c $(FLAGS) $< -o $@ diff --git a/opengl/config.cpp b/opengl/config.cpp index 0cbb488..3f9dcee 100644 --- a/opengl/config.cpp +++ b/opengl/config.cpp @@ -31,6 +31,7 @@ bool Config::m_useTexture=false; bool Config::m_useInfo=false; bool Config::m_forceCOG=false; bool Config::m_blitzMax=false; +bool Config::m_normals=false; void Config::Load() { @@ -57,6 +58,7 @@ void Config::Load() r.Read("info",m_useInfo); r.Read("cog",m_forceCOG); r.Read("bmx",m_blitzMax); + r.Read("normals",m_normals); #endif @@ -74,6 +76,7 @@ void Config::Save() r.Write("info",m_useInfo); r.Write("cog",m_forceCOG); r.Write("bmx",m_blitzMax); + r.Write("normals",m_normals); #endif } @@ -92,3 +95,6 @@ void Config::ForceCOG(bool flag) {m_forceCOG=flag;} bool Config::BlitzMax() {return m_blitzMax;} void Config::BlitzMax(bool flag) {m_blitzMax=flag;} + +bool Config::OutputNormals() {return m_normals;} +void Config::OutputNormals(bool flag) {m_normals=flag;} diff --git a/opengl/config.h b/opengl/config.h index 812b79a..1a707ce 100644 --- a/opengl/config.h +++ b/opengl/config.h @@ -48,6 +48,9 @@ public: static bool BlitzMax(); static void BlitzMax(bool flag); + static bool OutputNormals(); + static void OutputNormals(bool flag); + private: Config(); @@ -58,6 +61,7 @@ private: static bool m_useInfo; static bool m_forceCOG; static bool m_blitzMax; + static bool m_normals; }; #endif // CONFIG_H diff --git a/opengl/dialog.h b/opengl/dialog.h index 964de0b..85674c4 100644 --- a/opengl/dialog.h +++ b/opengl/dialog.h @@ -34,3 +34,4 @@ #define IDC_CHK_FORCECOG 3011 #define IDC_CHK_BLITZMAX 3012 #define IDC_LBL_FUNCNAME 3013 +#define IDC_CHK_VERTNORM 3014 diff --git a/opengl/dialog.rc b/opengl/dialog.rc index 731a865..f0b6995 100644 --- a/opengl/dialog.rc +++ b/opengl/dialog.rc @@ -1,23 +1,29 @@ #include <windows.h> #include "dialog.h" -GL_DIALOG DIALOG 100, 100, 337, 181 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION -CAPTION "OpenGL Export" -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -FONT 8, "MS Sans Serif" +GL_DIALOG DIALOG 100, 100, 340, 185 + STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION + CAPTION "OpenGL Export" + FONT 8, "MS Shell Dlg" { - CONTROL "...", IDC_BUT_SELECTDIR, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 240, 90, 25, 15 - CONTROL "", IDC_TXT_FUNCNAME, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 65, 110, 145, 12 - CONTROL "Use Textures", IDC_CHK_TEXTURE, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 5, 135, 60, 10 - CONTROL "Generate info", IDC_CHK_DEFINE, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 75, 135, 85, 10 - CONTROL "Cancel", IDC_BUT_CANCEL, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 170, 160, 75, 15 - CONTROL "Generate", IDC_BUT_GENERATE, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_TABSTOP, 255, 160, 75, 15 - CONTROL "", IDC_TXT_INFO, EDIT, ES_LEFT | ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_HSCROLL, 5, 15, 325, 70 - CONTROL "", IDC_TXT_DIR, EDIT, ES_LEFT | ES_AUTOHSCROLL | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER, 65, 90, 170, 12 - CONTROL "Directory", -1, STATIC, SS_LEFT | SS_CENTERIMAGE | WS_CHILD | WS_VISIBLE | WS_GROUP, 5, 90, 30, 10 - CONTROL "FUNC", IDC_LBL_FUNCNAME, STATIC, SS_LEFT | SS_CENTERIMAGE | WS_CHILD | WS_VISIBLE | WS_GROUP, 5, 110, 55, 10 - CONTROL "Force COG to 0,0,0", IDC_CHK_FORCECOG, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 165, 135, 75, 10 - CONTROL "Generate for Blitz MAX", IDC_CHK_BLITZMAX, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 248, 135, 85, 10 - CONTROL "Info:", -1, STATIC, SS_LEFT | SS_CENTERIMAGE | WS_CHILD | WS_VISIBLE | WS_GROUP, 5, 5, 15, 10 + PUSHBUTTON "...", IDC_BUT_SELECTDIR, 240,90,25,12 + + EDITTEXT "", IDC_TXT_FUNCNAME, 65,110,145,12, ES_AUTOHSCROLL + + AUTOCHECKBOX "Use Textures", IDC_CHK_TEXTURE, 5,130,60,10 + AUTOCHECKBOX "Generate Info", IDC_CHK_DEFINE, 110,130,85,10 + AUTOCHECKBOX "Force COG to 0,0,0", IDC_CHK_FORCECOG, 215,130,75,10 + AUTOCHECKBOX "Generate for Blitz MAX", IDC_CHK_BLITZMAX, 5,145,85,10 + AUTOCHECKBOX "Generate for lit scenes", IDC_CHK_VERTNORM, 110,145,85,10 + + PUSHBUTTON "Cancel", IDC_BUT_CANCEL, 170,165,75,15 + PUSHBUTTON "Generate", IDC_BUT_GENERATE, 255,165,75,15 + + EDITTEXT "", IDC_TXT_INFO, 5,15,325,70, ES_AUTOHSCROLL|ES_READONLY|WS_VSCROLL|WS_HSCROLL|ES_MULTILINE + + EDITTEXT "", IDC_TXT_DIR, 65,90,170,12, ES_AUTOHSCROLL|ES_READONLY + + LTEXT "Directory", -1, 5,92,30,10 + LTEXT "FUNC", IDC_LBL_FUNCNAME, 5,112,55,10 + LTEXT "Info:", -1, 5,5,15,10 } diff --git a/opengl/generate.cpp b/opengl/generate.cpp index 33d2f13..960fd7c 100644 --- a/opengl/generate.cpp +++ b/opengl/generate.cpp @@ -5,7 +5,7 @@ #include <sstream> #include <algorithm> #include <cctype> -#include <cstdio> +#include <stdarg.h> #include <w32dlib/w32dlib.h> #include "generate.h" #include "msLib.h" @@ -38,7 +38,9 @@ Generate::Generate(msModel *model) : m_model(model), m_max_z(FLT_MIN), m_min_z(FLT_MAX), - m_blitzMax(false) + m_blitzMax(false), + m_normals(false), + m_indent(0) { CalcModelBounds(); } @@ -83,6 +85,23 @@ std::string Generate::Info() void Generate::MakeFiles(HWND parent) { + if (m_normals) + { + for(int m=0;m<m_model->nNumMeshes;m++) + { + msMesh *mesh=m_model->pMeshes+m; + + if (mesh->nMaterialIndex<0) + { + W32DLib::Common::Error + (parent,0, + "Materials must be assigned if the object is to be lit"); + + return; + } + } + } + if (m_blitzMax) { GenerateBlitzMax(parent); @@ -99,7 +118,8 @@ void Generate::Setup(const std::string& dir, bool texture, bool info, bool forceCOG, - bool blitzMax) + bool blitzMax, + bool vertex_normals) { m_dir=dir; m_funcName=funcname; @@ -107,6 +127,7 @@ void Generate::Setup(const std::string& dir, m_useInfo=info; m_forceCOG=forceCOG; m_blitzMax=blitzMax; + m_normals=vertex_normals; if (m_forceCOG) { @@ -134,7 +155,7 @@ std::string Generate::GenerateFuncname() for(int f=0;name[f];f++) { - if (std::isalpha(name[f]) || (f && name[f]=='_')) + if (std::isalnum(name[f]) || (f && name[f]=='_')) { fn+=name[f]; } @@ -172,6 +193,29 @@ const char *Generate::Space(int len) } +void Generate::Output(const char *fmt, ...) +{ + if (m_fp==0) + { + return; + } + + if (*fmt!='\n') + { + for(int f=0;f<m_indent;f++) + { + std::fprintf(m_fp,"%s",INDENT); + } + } + + va_list va; + + va_start(va,fmt); + std::vfprintf(m_fp,fmt,va); + va_end(va); +} + + void Generate::CalcModelBounds() { for(int m=0;m<m_model->nNumMeshes;m++) @@ -213,13 +257,14 @@ void Generate::CalcModelBounds() void Generate::GenerateC(HWND parent) { - std::FILE *fp; int len; std::string fname_c; std::string fname_h; std::string def; std::string missing; + m_indent=0; + len=m_funcName.length()+6; fname_c=m_dir+"\\"+m_funcName; @@ -234,179 +279,113 @@ void Generate::GenerateC(HWND parent) // Generate header // - if (!(fp=fopen(fname_h.c_str(),"w"))) + if (!(m_fp=fopen(fname_h.c_str(),"w"))) { W32DLib::Common::Error(parent,0,"Couldn't create header file"); return; } - std::fprintf(fp,"%s","/* Code generated with Milkshape " - "Export OpenGL plugin\n*/\n"); - std::fprintf(fp,"\n"); + Output("%s","/* Code generated with Milkshape Export OpenGL plugin\n*/\n"); + Output("\n"); - std::fprintf(fp,"#ifndef %s_H\n#define %s_H\n\n", + Output("#ifndef %s_H\n#define %s_H\n\n", def.c_str(),def.c_str()); - std::fprintf(fp,"%s","#ifdef _cplusplus\nextern \"C\" {\n#endif\n\n"); + Output("%s","#ifdef _cplusplus\nextern \"C\" {\n#endif\n\n"); - std::fprintf(fp,"void %s(GLfloat x, GLfloat y, GLfloat z,\n", + Output("void %s(GLfloat x, GLfloat y, GLfloat z,\n", m_funcName.c_str()); - std::fprintf(fp,"%sGLfloat rot_x, GLfloat rot_y, GLfloat rot_z", + Output("%sGLfloat rot_x, GLfloat rot_y, GLfloat rot_z", Space(len)); if (m_useTexture) { - std::fprintf(fp,",\n%sGLint tid);\n\n", Space(len)); + Output(",\n%sGLint texture_id);\n\n", Space(len)); } else { - std::fprintf(fp,");\n\n"); + Output(");\n\n"); } if (m_useInfo) { - std::fprintf(fp,"#define %s_COG_X %f\n",def.c_str(),m_cogx-m_appcogx); - std::fprintf(fp,"#define %s_COG_Y %f\n",def.c_str(),m_cogy-m_appcogy); - std::fprintf(fp,"#define %s_COG_Z %f\n\n",def.c_str(),m_cogz-m_appcogz); + Output("#define %s_COG_X %f\n",def.c_str(),m_cogx-m_appcogx); + Output("#define %s_COG_Y %f\n",def.c_str(),m_cogy-m_appcogy); + Output("#define %s_COG_Z %f\n\n",def.c_str(),m_cogz-m_appcogz); - std::fprintf(fp,"#define %s_MIN_X %f\n",def.c_str(),m_min_x-m_appcogx); - std::fprintf(fp,"#define %s_MAX_X %f\n",def.c_str(),m_max_x-m_appcogx); - std::fprintf(fp,"#define %s_MIN_Y %f\n",def.c_str(),m_min_y-m_appcogy); - std::fprintf(fp,"#define %s_MAX_Y %f\n",def.c_str(),m_max_y-m_appcogy); - std::fprintf(fp,"#define %s_MIN_Z %f\n",def.c_str(),m_min_z-m_appcogz); - std::fprintf(fp,"#define %s_MAX_Z %f\n\n",def.c_str(), - m_max_z-m_appcogz); + Output("#define %s_MIN_X %f\n",def.c_str(),m_min_x-m_appcogx); + Output("#define %s_MAX_X %f\n",def.c_str(),m_max_x-m_appcogx); + Output("#define %s_MIN_Y %f\n",def.c_str(),m_min_y-m_appcogy); + Output("#define %s_MAX_Y %f\n",def.c_str(),m_max_y-m_appcogy); + Output("#define %s_MIN_Z %f\n",def.c_str(),m_min_z-m_appcogz); + Output("#define %s_MAX_Z %f\n\n",def.c_str(),m_max_z-m_appcogz); float sx=m_max_x-m_min_x; float sy=m_max_y-m_min_y; float sz=m_max_z-m_min_z; - std::fprintf(fp,"#define %s_SIZE_X %f\n",def.c_str(),sx); - std::fprintf(fp,"#define %s_SIZE_Y %f\n",def.c_str(),sy); - std::fprintf(fp,"#define %s_SIZE_Z %f\n\n",def.c_str(),sz); + Output("#define %s_SIZE_X %f\n",def.c_str(),sx); + Output("#define %s_SIZE_Y %f\n",def.c_str(),sy); + Output("#define %s_SIZE_Z %f\n\n",def.c_str(),sz); } - std::fprintf(fp,"#define %s_TEXTURED %d\n\n",def.c_str(),m_useTexture?1:0); + Output("#define %s_TEXTURED %d\n\n",def.c_str(),m_useTexture?1:0); - std::fprintf(fp,"%s","#ifdef _cplusplus\n}\n#endif\n\n"); + Output("%s","#ifdef _cplusplus\n}\n#endif\n\n"); - std::fprintf(fp,"#endif /* %s_H */\n\n",def.c_str()); + Output("#endif /* %s_H */\n\n",def.c_str()); - std::fprintf(fp,"%s","/* END OF FILE */\n"); + Output("%s","/* END OF FILE */\n"); - std::fclose(fp); + std::fclose(m_fp); // Generate C source // - if (!(fp=fopen(fname_c.c_str(),"w"))) + if (!(m_fp=fopen(fname_c.c_str(),"w"))) { W32DLib::Common::Error(parent,0,"Couldn't create source file"); return; } - std::fprintf(fp,"%s","/* Code generated with Milkshape " - "Export OpenGL plugin\n*/\n"); + Output("%s","/* Code generated with Milkshape Export OpenGL plugin\n*/\n"); - std::fprintf(fp,"%s","#include <GL/gl.h>\n\n"); + Output("%s","#include <GL/gl.h>\n\n"); - std::fprintf(fp,"void %s(GLfloat x, GLfloat y, GLfloat z,\n", + Output("void %s(GLfloat x, GLfloat y, GLfloat z,\n", m_funcName.c_str()); - std::fprintf(fp,"%sGLfloat rot_x, GLfloat rot_y, GLfloat rot_z", + Output("%sGLfloat rot_x, GLfloat rot_y, GLfloat rot_z", Space(len)); if (m_useTexture) { - std::fprintf(fp,",\n%sGLint tid)\n", Space(len)); + Output(",\n%sGLint texture_id)\n", Space(len)); } else { - std::fprintf(fp,")\n"); + Output(")\n"); } - std::fprintf(fp,"{\n"); + Output("{\n"); - std::fprintf(fp,INDENT "glPushMatrix();\n"); - std::fprintf(fp,INDENT "glLoadIdentity();\n"); - std::fprintf(fp,INDENT "glTranslatef(x,y,z);\n"); - std::fprintf(fp,INDENT "glRotatef(rot_x,1.0f,0.0f,0.0f);\n"), - std::fprintf(fp,INDENT "glRotatef(rot_y,0.0f,1.0f,0.0f);\n"), - std::fprintf(fp,INDENT "glRotatef(rot_z,0.0f,0.0f,1.0f);\n"), - std::fprintf(fp,"\n"); + m_indent++; - std::fprintf(fp,INDENT "glBegin(GL_TRIANGLES);\n"); - - if (m_useTexture) + if (m_normals) { - std::fprintf(fp,INDENT "glBindTexture(GL_TEXTURE_2D,tid);\n"); + Output("GLfloat ambient[4];\n"); + Output("GLfloat diffuse[4];\n"); + Output("GLfloat specular[4];\n"); + Output("GLfloat emission[4];\n"); + Output("\n"); } - std::fprintf(fp,"\n"); - - for(int m=0;m<m_model->nNumMeshes;m++) - { - msMesh *mesh=m_model->pMeshes+m; - - std::fprintf(fp,INDENT "/* Mesh %d - %s\n",m+1,mesh->szName); - std::fprintf(fp,INDENT "*/\n"); - - if (mesh->nMaterialIndex<0) - { - missing+=mesh->szName; - missing+="\n"; - - std::fprintf(fp,INDENT "glColor3f(1.0f,1.0f,1.0f);\n"); - } - else - { - msMaterial *mat=m_model->pMaterials+mesh->nMaterialIndex; - - std::fprintf(fp,INDENT "glColor3f(%f,%f,%f);\n", - mat->Diffuse[0], - mat->Diffuse[1], - mat->Diffuse[2]); - } - - for(int t=0;t<mesh->nNumTriangles;t++) - { - msTriangle *tri; - - tri=mesh->pTriangles+t; + GenerateCommon(missing,";","/*","*/"); - if (!(tri->nFlags&eHidden)) - { - // To allow vertex order to be tweaked... - // - static int order[3]={0,1,2}; + m_indent--; - for(int i=0;i<3;i++) - { - msVertex *v=mesh->pVertices+tri->nVertexIndices[order[i]]; + Output("}\n"); - std::fprintf(fp,INDENT "glVertex3f(%f,%f,%f);\n", - v->Vertex[0]-m_appcogx, - v->Vertex[1]-m_appcogy, - v->Vertex[2]-m_appcogz); - - if (m_useTexture) - { - std::fprintf(fp,INDENT "glTexCoord2f(%f,%f);\n", - v->u, - v->v); - } - } - } - } - - std::fprintf(fp,"\n"); - } - - std::fprintf(fp,INDENT "glEnd();\n"); - std::fprintf(fp,INDENT "glPopMatrix();\n"); - - std::fprintf(fp,"}\n"); - - std::fclose(fp); + std::fclose(m_fp); if (missing.length()>0) { @@ -420,158 +399,177 @@ void Generate::GenerateC(HWND parent) void Generate::GenerateBlitzMax(HWND parent) { - std::FILE *fp; - int len; - std::string fname_c; - std::string fname_h; - std::string def; + std::string fname_bmx; std::string missing; - len=m_funcName.length()+6; + fname_bmx=m_dir+"\\"+m_funcName+".bmx"; - fname_c=m_dir+"\\"+m_funcName; - fname_h=fname_c+".h"; - fname_c+=".c"; + m_indent=0; - for(std::string::const_iterator i=m_funcName.begin(); - i!=m_funcName.end();++i) - { - def+=std::toupper(*i); - } - - // Generate header + // Generate class // - if (!(fp=fopen(fname_h.c_str(),"w"))) + if (!(m_fp=fopen(fname_bmx.c_str(),"w"))) { - W32DLib::Common::Error(parent,0,"Couldn't create header file"); + W32DLib::Common::Error(parent,0,"Couldn't create source file"); return; } - std::fprintf(fp,"%s","/* Code generated with Milkshape " - "Export OpenGL plugin\n*/\n"); - std::fprintf(fp,"\n"); - - std::fprintf(fp,"#ifndef %s_H\n#define %s_H\n\n", - def.c_str(),def.c_str()); - - std::fprintf(fp,"%s","#ifdef _cplusplus\nextern \"C\" {\n#endif\n\n"); + Output("%s","' Code generated with Milkshape Export OpenGL plugin\n'\n"); + Output("\n"); + Output("Type %s\n",m_funcName.c_str()); + Output("\n"); - std::fprintf(fp,"void %s(GLfloat x, GLfloat y, GLfloat z,\n", - m_funcName.c_str()); - std::fprintf(fp,"%sGLfloat rot_x, GLfloat rot_y, GLfloat rot_z", - Space(len)); - - if (m_useTexture) - { - std::fprintf(fp,",\n%sGLint tid);\n\n", Space(len)); - } - else - { - std::fprintf(fp,");\n\n"); - } + m_indent++; if (m_useInfo) { - std::fprintf(fp,"#define %s_COG_X %f\n",def.c_str(),m_cogx-m_appcogx); - std::fprintf(fp,"#define %s_COG_Y %f\n",def.c_str(),m_cogy-m_appcogy); - std::fprintf(fp,"#define %s_COG_Z %f\n\n",def.c_str(),m_cogz-m_appcogz); + Output("' Consts relating to the model's size and centre of gravity\n"); + Output("'\n"); + Output("Const COG_X:Float=%f\n",m_cogx-m_appcogx); + Output("Const COG_Y:Float=%f\n",m_cogy-m_appcogy); + Output("Const COG_Z:Float=%f\n\n",m_cogz-m_appcogz); - std::fprintf(fp,"#define %s_MIN_X %f\n",def.c_str(),m_min_x-m_appcogx); - std::fprintf(fp,"#define %s_MAX_X %f\n",def.c_str(),m_max_x-m_appcogx); - std::fprintf(fp,"#define %s_MIN_Y %f\n",def.c_str(),m_min_y-m_appcogy); - std::fprintf(fp,"#define %s_MAX_Y %f\n",def.c_str(),m_max_y-m_appcogy); - std::fprintf(fp,"#define %s_MIN_Z %f\n",def.c_str(),m_min_z-m_appcogz); - std::fprintf(fp,"#define %s_MAX_Z %f\n\n",def.c_str(), - m_max_z-m_appcogz); + Output("Const MIN_X:Float=%f\n",m_min_x-m_appcogx); + Output("Const MAX_X:Float=%f\n",m_max_x-m_appcogx); + Output("Const MIN_Y:Float=%f\n",m_min_y-m_appcogy); + Output("Const MAX_Y:Float=%f\n",m_max_y-m_appcogy); + Output("Const MIN_Z:Float=%f\n",m_min_z-m_appcogz); + Output("Const MAX_Z:Float=%f\n\n",m_max_z-m_appcogz); float sx=m_max_x-m_min_x; float sy=m_max_y-m_min_y; float sz=m_max_z-m_min_z; - std::fprintf(fp,"#define %s_SIZE_X %f\n",def.c_str(),sx); - std::fprintf(fp,"#define %s_SIZE_Y %f\n",def.c_str(),sy); - std::fprintf(fp,"#define %s_SIZE_Z %f\n\n",def.c_str(),sz); - } + Output("Const SIZE_X:Float=%f\n",sx); + Output("Const SIZE_Y:Float=%f\n",sy); + Output("Const SIZE_Z:Float=%f\n\n",sz); - std::fprintf(fp,"#define %s_TEXTURED %d\n\n",def.c_str(),m_useTexture?1:0); + Output("const TEXTURED:Int=%s\n",m_useTexture ? "true":"false"); - std::fprintf(fp,"%s","#ifdef _cplusplus\n}\n#endif\n\n"); + Output("\n"); + } - std::fprintf(fp,"#endif /* %s_H */\n\n",def.c_str()); + Output("' These fields control the position/orientation of the object\n"); + Output("'\n"); + Output("Field x:Float\n"); + Output("Field y:Float\n"); + Output("Field z:Float\n"); + Output("Field rot_x:Float\n"); + Output("Field rot_y:Float\n"); + Output("Field rot_z:Float\n"); + Output("\n"); + + Output("' Use this function to create an instance\n"); + Output("'\n"); + Output("Function Create:%s()\n",m_funcName.c_str()); + m_indent++; + Output("Local o:%s = New %s\n",m_funcName.c_str(),m_funcName.c_str()); + Output("o.x=0\n"); + Output("o.y=0\n"); + Output("o.z=0\n"); + Output("o.rot_x=0\n"); + Output("o.rot_y=0\n"); + Output("o.rot_z=0\n"); + Output("return o\n"); + m_indent--; + Output("End Function\n"); + Output("\n"); + + Output("' Use this member to draw the object\n"); + Output("'\n"); - std::fprintf(fp,"%s","/* END OF FILE */\n"); + if (m_useTexture) + { + Output("Method Render(texture_id:Int)\n"); + } + else + { + Output("Method Render()\n"); + } - std::fclose(fp); + m_indent++; - // Generate C source - // - if (!(fp=fopen(fname_c.c_str(),"w"))) + if (m_normals) { - W32DLib::Common::Error(parent,0,"Couldn't create source file"); - return; + Output("Local ambient:Float[4]\n"); + Output("Local diffuse:Float[4]\n"); + Output("Local specular:Float[4]\n"); + Output("Local emission:Float[4]\n"); + Output("\n"); } - std::fprintf(fp,"%s","/* Code generated with Milkshape " - "Export OpenGL plugin\n*/\n"); + GenerateCommon(missing,"","'",""); - std::fprintf(fp,"%s","#include <GL/gl.h>\n\n"); + m_indent--; - std::fprintf(fp,"void %s(GLfloat x, GLfloat y, GLfloat z,\n", - m_funcName.c_str()); - std::fprintf(fp,"%sGLfloat rot_x, GLfloat rot_y, GLfloat rot_z", - Space(len)); + Output("End Method\n"); - if (m_useTexture) - { - std::fprintf(fp,",\n%sGLint tid)\n", Space(len)); - } - else + m_indent--; + + Output("End Type\n"); + + std::fclose(m_fp); + + if (missing.length()>0) { - std::fprintf(fp,")\n"); + missing="The following meshes had no material:\n\n"+missing; + missing+="\n\nThey were given the colour white."; + + W32DLib::Common::Message(parent,0,missing); } +} - std::fprintf(fp,"{\n"); - std::fprintf(fp,INDENT "glPushMatrix();\n"); - std::fprintf(fp,INDENT "glLoadIdentity();\n"); - std::fprintf(fp,INDENT "glTranslatef(x,y,z);\n"); - std::fprintf(fp,INDENT "glRotatef(rot_x,1.0f,0.0f,0.0f);\n"), - std::fprintf(fp,INDENT "glRotatef(rot_y,0.0f,1.0f,0.0f);\n"), - std::fprintf(fp,INDENT "glRotatef(rot_z,0.0f,0.0f,1.0f);\n"), - std::fprintf(fp,"\n"); +void Generate::GenerateCommon(std::string& missing, + const char *term, + const char *start_comment, + const char *end_comment) +{ + int last_mat=-1; - std::fprintf(fp,INDENT "glBegin(GL_TRIANGLES);\n"); + Output("glPushMatrix()%s\n",term); + Output("glLoadIdentity()%s\n",term); + Output("glTranslatef(x,y,z)%s\n",term); + Output("glRotatef(rot_x,1,0,0)%s\n",term); + Output("glRotatef(rot_y,0,1,0)%s\n",term); + Output("glRotatef(rot_z,0,0,1)%s\n",term); if (m_useTexture) { - std::fprintf(fp,INDENT "glBindTexture(GL_TEXTURE_2D,tid);\n"); + Output("glBindTexture(GL_TEXTURE_2D,texture_id)%s\n",term); } - std::fprintf(fp,"\n"); + Output("\n"); + Output("glBegin(GL_TRIANGLES)%s\n",term); + Output("\n"); for(int m=0;m<m_model->nNumMeshes;m++) { msMesh *mesh=m_model->pMeshes+m; - std::fprintf(fp,INDENT "/* Mesh %d - %s\n",m+1,mesh->szName); - std::fprintf(fp,INDENT "*/\n"); + Output("%s Mesh %d - %s %s\n", + start_comment,m+1,mesh->szName,end_comment); + Output("\n"); if (mesh->nMaterialIndex<0) { missing+=mesh->szName; missing+="\n"; - std::fprintf(fp,INDENT "glColor3f(1.0f,1.0f,1.0f);\n"); + Output("glColor3f(1.0f,1.0f,1.0f)%s\n",term); + last_mat=-1; } else { - msMaterial *mat=m_model->pMaterials+mesh->nMaterialIndex; + if (mesh->nMaterialIndex!=last_mat) + { + msMaterial *mat=m_model->pMaterials+mesh->nMaterialIndex; - std::fprintf(fp,INDENT "glColor3f(%f,%f,%f);\n", - mat->Diffuse[0], - mat->Diffuse[1], - mat->Diffuse[2]); + GenerateMaterial(mat,missing,term); + + last_mat=mesh->nMaterialIndex; + } } for(int t=0;t<mesh->nNumTriangles;t++) @@ -590,39 +588,75 @@ void Generate::GenerateBlitzMax(HWND parent) { msVertex *v=mesh->pVertices+tri->nVertexIndices[order[i]]; - std::fprintf(fp,INDENT "glVertex3f(%f,%f,%f);\n", - v->Vertex[0]-m_appcogx, - v->Vertex[1]-m_appcogy, - v->Vertex[2]-m_appcogz); - if (m_useTexture) { - std::fprintf(fp,INDENT "glTexCoord2f(%f,%f);\n", - v->u, - v->v); + Output("glTexCoord2f(%f,%f)%s\n",v->u,v->v,term); } + + if (m_normals) + { + msVec3 n; + + msMesh_GetVertexNormalAt(mesh, + tri->nNormalIndices[order[i]], + n); + + Output("glNormal3f(%f,%f,%f)%s\n", + n[0], + n[1], + n[2], + term); + } + + Output("glVertex3f(%f,%f,%f)%s\n", + v->Vertex[0]-m_appcogx, + v->Vertex[1]-m_appcogy, + v->Vertex[2]-m_appcogz, + term); } } } - std::fprintf(fp,"\n"); - } - - std::fprintf(fp,INDENT "glEnd();\n"); - std::fprintf(fp,INDENT "glPopMatrix();\n"); + Output("\n"); + } - std::fprintf(fp,"}\n"); + Output("glEnd()%s\n",term); + Output("glPopMatrix()%s\n",term); +} - std::fclose(fp); - if (missing.length()>0) +void Generate::GenerateMaterial(msMaterial *mat, + std::string& missing, + const char *term) +{ + if (m_normals) { - missing="The following meshes had no material:\n\n"+missing; - missing+="\n\nThey were given the colour white."; + int f; - W32DLib::Common::Message(parent,0,missing); + for(f=0;f<4;f++) + { + Output("ambient[%d]=%f%s\n",f,mat->Ambient[f],term); + Output("diffuse[%d]=%f%s\n",f,mat->Diffuse[f],term); + Output("specular[%d]=%f%s\n",f,mat->Specular[f],term); + Output("emission[%d]=%f%s\n",f,mat->Emissive[f],term); + } + + Output("glMaterialf(GL_FRONT,GL_SHININESS,%f)%s\n", + mat->fShininess,term); + + Output("glMaterialfv(GL_FRONT,GL_AMBIENT,ambient)%s\n",term); + Output("glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuse)%s\n",term); + Output("glMaterialfv(GL_FRONT,GL_SPECULAR,specular)%s\n",term); + Output("glMaterialfv(GL_FRONT,GL_EMISSION,emission)%s\n",term); + } + else + { + Output("glColor3f(%f,%f,%f)%s\n", + mat->Diffuse[0], + mat->Diffuse[1], + mat->Diffuse[2], + term); } } - // END OF FILE diff --git a/opengl/generate.h b/opengl/generate.h index c8127a8..8191400 100644 --- a/opengl/generate.h +++ b/opengl/generate.h @@ -26,6 +26,7 @@ #include <windows.h> #include <string> #include <msLib.h> +#include <cstdio> class Generate { @@ -41,7 +42,8 @@ public: bool texture, bool info, bool forceCOG, - bool blitzMax); + bool blitzMax, + bool vertex_normals); void MakeFiles(HWND parent); @@ -51,6 +53,7 @@ private: msModel *m_model; std::string m_funcName; std::string m_dir; + bool m_useTexture; bool m_useInfo; bool m_forceCOG; @@ -71,13 +74,28 @@ private: float m_min_z; bool m_blitzMax; + bool m_normals; + + int m_indent; + + std::FILE *m_fp; const char *Space(int len); + void Output(const char *fmt, ...); void CalcModelBounds(); void GenerateC(HWND parent); void GenerateBlitzMax(HWND parent); + + void GenerateCommon(std::string& missing, + const char *term, + const char *start_comment, + const char *end_comment); + + void GenerateMaterial(msMaterial *mat, + std::string& missing, + const char *term); }; #endif // GENERATE_H diff --git a/opengl/gldialog.cpp b/opengl/gldialog.cpp index ae3ef45..f31f2c8 100644 --- a/opengl/gldialog.cpp +++ b/opengl/gldialog.cpp @@ -41,6 +41,7 @@ GLDialog::GLDialog(Generate& gen) , m_dir(this,IDC_TXT_DIR,0) , m_forceCOG(this,IDC_CHK_FORCECOG,0) , m_blitzMax(this,IDC_CHK_BLITZMAX,0) + , m_normals(this,IDC_CHK_VERTNORM,0) , m_funcLabel(this,IDC_LBL_FUNCNAME,0) { Config::Load(); @@ -92,6 +93,7 @@ void GLDialog::OnInit() m_useTexture.SetState(Config::UseTexture()); m_forceCOG.SetState(Config::ForceCOG()); m_blitzMax.SetState(Config::BlitzMax()); + m_normals.SetState(Config::OutputNormals()); Preview(); } @@ -108,6 +110,7 @@ BOOL GLDialog::OnGenerate(UINT msg, WPARAM wp, LPARAM lp) Config::UseTexture(m_useTexture.GetState()); Config::ForceCOG(m_forceCOG.GetState()); Config::BlitzMax(m_blitzMax.GetState()); + Config::OutputNormals(m_normals.GetState()); Config::Save(); Close(IDOK); @@ -152,7 +155,8 @@ void GLDialog::Preview() m_useTexture.GetState(), m_useInfo.GetState(), m_forceCOG.GetState(), - m_blitzMax.GetState()); + m_blitzMax.GetState(), + m_normals.GetState()); if (m_blitzMax.GetState()) { diff --git a/opengl/gldialog.h b/opengl/gldialog.h index aa5d6e7..7df26e0 100644 --- a/opengl/gldialog.h +++ b/opengl/gldialog.h @@ -49,6 +49,7 @@ private: W32DLib::Text m_dir; W32DLib::AutoCheck m_forceCOG; W32DLib::AutoCheck m_blitzMax; + W32DLib::AutoCheck m_normals; W32DLib::StaticText m_funcLabel; std::string m_path; diff --git a/opengl/main.cpp b/opengl/main.cpp index 7ded832..9fb5a3b 100644 --- a/opengl/main.cpp +++ b/opengl/main.cpp @@ -41,8 +41,6 @@ static int Execute(msModel* model) W32DLib::Common::Initialise(); W32DLib::Common::MessageTitle("Simple OpenGL"); - // Unfortunately this is the best you can hope for with Milkshape... - // HWND parent=GetForegroundWindow(); if (!model) @@ -66,7 +64,7 @@ static int Execute(msModel* model) SetCursor(LoadCursor(NULL,IDC_ARROW)); } - return 1; + return MS_MODEL_UNCHANGED; } PLUGIN_SPEC void* CreatePlugIn() |