diff --git a/examples/examples/OpenGL/Md2Model/.src/FMain.class b/examples/examples/OpenGL/Md2Model/.src/FMain.class index a4fe07f2d..da873908e 100644 --- a/examples/examples/OpenGL/Md2Model/.src/FMain.class +++ b/examples/examples/OpenGL/Md2Model/.src/FMain.class @@ -1,6 +1,7 @@ ' Gambas class file Private $aModel As Md2Model[] +Private $aObject As Md2Object[] Private $iFrames As Integer Private $fTime As Single Private $fFramerate As Float @@ -27,7 +28,7 @@ Public Sub glaScreen_Resize() Gl.MatrixMode(Gl.PROJECTION) Gl.LoadIdentity() 'Reset The Projection Matrix Glu.Perspective(45.0, glaScreen.Width / glaScreen.Height, 0.1, 3000.0) 'Calculate The Aspect Ratio Of The Window - Glu.Lookat(0, 100, 120, 0, 0, -300, 0, 100, 0) + Glu.LookAt(0, 100, 120, 0, 0, -300, 0, 100, 0) Gl.MatrixMode(Gl.MODELVIEW) End @@ -36,10 +37,18 @@ Public Sub Init() Dim X, D, Z As Float Dim sModel As String + Dim hModel As Md2Model Dim I As Integer Dim aModel As String[] = ["bauul", "goblin", "knight", "ogro", "rat", "rhino"] + Dim hObject As Md2Object $aModel = New Md2Model[] + $aObject = New Md2Object[] + + For Each sModel In aModel + $aModel.Add(Md2Model.Load(sModel & ".md2")) + $aModel[$aModel.Max].Texture = LoadTexture(sModel & ".jpg") + Next D = 100 @@ -48,12 +57,10 @@ Public Sub Init() For I = 1 To 189 - sModel = aModel[Int(Rnd(0, aModel.Count))] - - $aModel.Add(Md2Model.Load(sModel & ".md2")) - $aModel[$aModel.Max].Texture = LoadTexture(sModel & ".jpg") - 'Print "Model #"; $aModel.Max; ": "; $aModel[$aModel.Max].Count; " frames" - $aModel[$aModel.Max].Move(X, -10, Z) + hModel = $aModel[Int(Rnd(0, aModel.Count))] + hObject = New Md2Object(hModel) + $aObject.Add(hObject) + $aObject[$aObject.Max].Move(X, -10, Z) X += 50 If X > D Then D += 100 @@ -89,20 +96,18 @@ Public Sub glaScreen_Draw() Gl.Vertex3f(- $iEndWidth, -34.2, $iEndZ) Gl.End - 'Drawing model is as easy as this - frame number, interpolation between frames (0-1), texture identificator) - ' Gl.Color3f(1, 1, 1) - For I = 0 To $aModel.Max - $aModel[I].Draw + For I = 0 To $aObject.Max + $aObject[I].Draw Next - For I = 0 To $aModel.Max + For I = 0 To $aObject.Max Glu.Color(Color.Lighter(&HD96800&)) hQuadric = Glu.NewQuadric() Gl.PushMatrix() - Gl.Translatef($aModel[I].X, -34, $aModel[I].Z) + Gl.Translatef($aObject[I].X, -34, $aObject[I].Z) Gl.Rotatef(90, 1, 0, 0) - Glu.Disk(hQuadric, 0, 20, 20, 8) + Glu.Disk(hQuadric, 0, 20, 30, 1) Gl.PopMatrix() Next @@ -115,7 +120,7 @@ Public Sub glaScreen_Draw() Inc $fTime Endif - lblInfo.Text = Format($aModel[0].Pos, "0.00") & " / " & $aModel[0].Count & " ( " & CInt($fFramerate) & " FPS )" + lblInfo.Text = Format($aObject[0].Frame, "0.00") & " / " & $aObject[0].Model.Count & " ( " & CInt($fFramerate) & " FPS )" Gl.PopMatrix @@ -145,13 +150,13 @@ Public Sub timAnim_Timer() Dim I As Integer - For I = 0 To $aModel.Max - $aModel[I].Pos += 0.1 - If $aModel[I].Pos >= $aModel[I].Count Then $aModel[I].Pos = 0 + For I = 0 To $aObject.Max + $aObject[I].Frame += 0.1 + If $aObject[I].Frame >= $aObject[I].Model.Count Then $aObject[I].Frame = 0 Next Object.Lock(sldFrame) - sldFrame.Value = CInt($aModel[0].Pos) + sldFrame.Value = CInt($aObject[0].Frame) Object.Unlock(sldFrame) glaScreen.Refresh diff --git a/gb.opengl/src/sge/Makefile.am b/gb.opengl/src/sge/Makefile.am index 3b77edbc6..4aa679ec9 100644 --- a/gb.opengl/src/sge/Makefile.am +++ b/gb.opengl/src/sge/Makefile.am @@ -9,4 +9,5 @@ gb_opengl_sge_la_CPPFLAGS = @SGE_INC@ gb_opengl_sge_la_SOURCES = \ main.c main.h \ - cmd2model.c cmd2model.h + cmd2model.c cmd2model.h \ + cmd2object.c cmd2object.h diff --git a/gb.opengl/src/sge/cmd2model.c b/gb.opengl/src/sge/cmd2model.c index db170797f..2df572625 100644 --- a/gb.opengl/src/sge/cmd2model.c +++ b/gb.opengl/src/sge/cmd2model.c @@ -202,9 +202,11 @@ CMD2MODEL *MD2MODEL_create(void) return (CMD2MODEL*)GB.New(GB.FindClass("Md2Model"), NULL, NULL); }; -static void draw_frame_inter(CMD2MODEL *_object, int n, float interp, int texture) +void MD2MODEL_draw(CMD2MODEL *_object, double frame, int texture, float *pos, float *scale, float *rotate) { int i, j; + int n; + double interp; GLfloat s, t, v_curr[3], v_next[3], v[3], norm[3]; float *n_curr, *n_next; framemd2 *pframe1, *pframe2; @@ -219,9 +221,12 @@ static void draw_frame_inter(CMD2MODEL *_object, int n, float interp, int textur if (texture < 0) return; + n = (int)frame; + interp = frame - n; + if ((n < 0) || (n >= THIS->num_frames-1)) { - n=0; + n = 0; interp = 0; } @@ -230,10 +235,21 @@ static void draw_frame_inter(CMD2MODEL *_object, int n, float interp, int textur glEnable(GL_TEXTURE_2D); glPushMatrix(); - glTranslatef(THIS->position[0], THIS->position[1], THIS->position[2]); + + if (pos) + glTranslatef(pos[0], pos[1], pos[2]); + glRotatef(-90, 1, 0, 0); glRotatef(-90, 0, 0, 1); + + if (rotate && rotate[0] != 0) + glRotatef(rotate[0], rotate[1], rotate[2], rotate[3]); + glScalef(THIS->scale[0], THIS->scale[1], THIS->scale[2]); + + if (scale) + glScalef(scale[0], scale[1], scale[2]); + glBindTexture (GL_TEXTURE_2D, texture); if (interp == 0) @@ -246,12 +262,12 @@ static void draw_frame_inter(CMD2MODEL *_object, int n, float interp, int textur { if (i < 0) { - glBegin (GL_TRIANGLE_FAN); + glBegin(GL_TRIANGLE_FAN); i = -i; } else { - glBegin (GL_TRIANGLE_STRIP); + glBegin(GL_TRIANGLE_STRIP); } // Draw each vertex of this group @@ -332,21 +348,6 @@ static void draw_frame_inter(CMD2MODEL *_object, int n, float interp, int textur } -// // Generate one list for each frame -// -// static void make_lists(CMD2MODEL *mdl) -// { -// int i; -// -// mdl->list = glGenLists(mdl->num_frames); -// -// for (i = 0; i < mdl->num_frames; i++) -// { -// glNewList(mdl->list + i, GL_COMPILE); -// draw_frame_inter(mdl, i, 0, mdl->texture); -// glEndList(); -// } -// } //--------------------------------------------------------------------------- @@ -431,21 +432,11 @@ BEGIN_METHOD(Md2Model_Load, GB_STRING name) // Read model data memcpy(mdl->skins, &addr[mdl->offset_skins], sizeof(skinmd2) * mdl->num_skins); - - //fseek (fp, mdl->offset_st, SEEK_SET); - //fi=fread (mdl->texcoords, sizeof (texCoordmd2), mdl->num_st, fp); memcpy(mdl->texcoords, &addr[mdl->offset_st], sizeof(texCoordmd2) * mdl->num_st); - - //fseek (fp, mdl->offset_tris, SEEK_SET); - //fi=fread (mdl->triangles, sizeof (trianglemd2), mdl->num_tris, fp); memcpy(mdl->triangles, &addr[mdl->offset_tris], sizeof(trianglemd2) * mdl->num_tris); - - //fseek (fp, mdl->offset_glcmds, SEEK_SET); - //fi=fread (mdl->glcmds, sizeof (int), mdl->num_glcmds, fp); memcpy(mdl->glcmds, &addr[mdl->offset_glcmds], sizeof(int) * mdl->num_glcmds); // Read frames - //fseek (fp, mdl->offset_frames, SEEK_SET); { char *p = &addr[mdl->offset_frames]; @@ -459,10 +450,6 @@ BEGIN_METHOD(Md2Model_Load, GB_STRING name) memcpy(mdl->frames[i].translate, p, sizeof(float) * 3); p += sizeof(float) * 3; memcpy(mdl->frames[i].name, p, 16); p += 16; memcpy(mdl->frames[i].verts, p, sizeof(vertexmd2) * mdl->num_vertices); p += sizeof(vertexmd2) * mdl->num_vertices; - //fi=fread (mdl->frames[i].scale, sizeof (float)*3, 1, fp); - //fi=fread (mdl->frames[i].translate, sizeof (float)*3, 1, fp); - //fi=fread (mdl->frames[i].name, sizeof (char), 16, fp); - //fi=fread (mdl->frames[i].verts, sizeof (vertexmd2), mdl->num_vertices, fp); } } @@ -481,41 +468,6 @@ __ERROR: END_METHOD -BEGIN_METHOD(Md2Model_Move, GB_FLOAT x; GB_FLOAT y; GB_FLOAT z) - - THIS->position[0] = VARG(x); - THIS->position[1] = VARG(y); - THIS->position[2] = VARG(z); - -END_METHOD - -BEGIN_PROPERTY(Md2Model_X) - - if (READ_PROPERTY) - GB.ReturnFloat(THIS->position[0]); - else - THIS->position[0] = VPROP(GB_FLOAT); - -END_PROPERTY - -BEGIN_PROPERTY(Md2Model_Y) - - if (READ_PROPERTY) - GB.ReturnFloat(THIS->position[1]); - else - THIS->position[1] = VPROP(GB_FLOAT); - -END_PROPERTY - -BEGIN_PROPERTY(Md2Model_Z) - - if (READ_PROPERTY) - GB.ReturnFloat(THIS->position[2]); - else - THIS->position[2] = VPROP(GB_FLOAT); - -END_PROPERTY - BEGIN_METHOD(Md2Model_Scale, GB_FLOAT sx; GB_FLOAT sy; GB_FLOAT sz) THIS->scale[0] = VARG(sx); @@ -524,7 +476,6 @@ BEGIN_METHOD(Md2Model_Scale, GB_FLOAT sx; GB_FLOAT sy; GB_FLOAT sz) END_METHOD - BEGIN_PROPERTY(Md2Model_Count) GB.ReturnInteger(THIS->num_frames); @@ -555,32 +506,11 @@ BEGIN_PROPERTY(Md2Model_Texture) END_PROPERTY -BEGIN_PROPERTY(Md2Model_Pos) - - if (READ_PROPERTY) - GB.ReturnFloat(THIS->pos); - else - THIS->pos = VPROP(GB_FLOAT); - -END_PROPERTY - -BEGIN_METHOD_VOID(Md2Model_Draw) - - draw_frame_inter(THIS, (int)THIS->pos, THIS->pos - (int)THIS->pos, THIS->texture); - -END_METHOD - //--------------------------------------------------------------------------- -BEGIN_METHOD(Md2Model_Frame_Draw, GB_INTEGER texture) +BEGIN_METHOD(Md2Model_Frame_Draw, GB_FLOAT interp; GB_INTEGER texture) - draw_frame_inter(THIS, THIS->frame, 0, VARG(texture)); - -END_METHOD - -BEGIN_METHOD(Md2Model_Frame_DrawInter, GB_FLOAT inter; GB_INTEGER texture) - - draw_frame_inter(THIS, THIS->frame, VARG(inter), VARG(texture)); + MD2MODEL_draw(THIS, (double)THIS->frame + VARGOPT(interp, 0.0), VARGOPT(texture, THIS->texture), NULL, NULL, NULL); END_METHOD @@ -595,9 +525,10 @@ END_METHOD GB_DESC Md2ModelFrameDesc[] = { GB_DECLARE_VIRTUAL(".Md2Model.Frame"), + GB_PROPERTY_READ("Name", "s", Md2Model_Frame_Name), - GB_METHOD("Draw", NULL, Md2Model_Frame_Draw, "(Texture)i"), - GB_METHOD("DrawInter", NULL, Md2Model_Frame_DrawInter, "(InterFrame)f(Texture)i"), + GB_METHOD("Draw", NULL, Md2Model_Frame_Draw, "[(Interpolation)f(Texture)i]"), + GB_END_DECLARE }; @@ -610,19 +541,12 @@ GB_DESC Md2ModelDesc[] = GB_STATIC_METHOD("Load", "Md2Model" , Md2Model_Load, "(Name)s"), - GB_METHOD("Move", NULL, Md2Model_Move, "(X)f(Y)f(Z)f"), - GB_PROPERTY_READ("X", "f", Md2Model_X), - GB_PROPERTY_READ("Y", "f", Md2Model_Y), - GB_PROPERTY_READ("Z", "f", Md2Model_Z), - GB_PROPERTY_READ("Count", "i", Md2Model_Count), GB_METHOD("_get", ".Md2Model.Frame", Md2Model_get, "(Frame)i"), - GB_METHOD("Scale", NULL, Md2Model_Scale, "(ScaleX)f(ScaleY)f(ScaleZ)f" ), + GB_METHOD("Scale", NULL, Md2Model_Scale, "(SX)f(SY)f(SZ)f" ), GB_PROPERTY("Texture", "i", Md2Model_Texture), - GB_PROPERTY("Pos", "f", Md2Model_Pos), - GB_METHOD("Draw", NULL, Md2Model_Draw, NULL), GB_END_DECLARE }; diff --git a/gb.opengl/src/sge/cmd2model.h b/gb.opengl/src/sge/cmd2model.h index a13cb0a2c..b6a8a7b5b 100644 --- a/gb.opengl/src/sge/cmd2model.h +++ b/gb.opengl/src/sge/cmd2model.h @@ -57,6 +57,7 @@ #include "gambas.h" #include "main.h" +#include "cmd2object.h" #ifndef __CMD2MODEL_C extern GB_DESC Md2ModelFrameDesc[]; @@ -119,7 +120,7 @@ struct md2_glcmd typedef - struct { + struct CMD2MODEL { GB_BASE ob; //Header int ident; @@ -151,21 +152,16 @@ typedef framemd2 *frames; int *glcmds; - GLuint tex_id; - //Model specific data - float position[3]; float scale[3]; - int f_no; - float inter_frame; int frame; // frame being accessed with the [] operator - int texture; - double pos; + GLuint texture; //End model specific data } CMD2MODEL; CMD2MODEL *MD2MODEL_create(void); - +void MD2MODEL_draw(CMD2MODEL *_object, double frame, int texture, float *pos, float *rotate, float *scale); + #endif diff --git a/gb.opengl/src/sge/cmd2object.c b/gb.opengl/src/sge/cmd2object.c new file mode 100644 index 000000000..b143a8ee6 --- /dev/null +++ b/gb.opengl/src/sge/cmd2object.c @@ -0,0 +1,175 @@ +/*************************************************************************** + + cmd2object.c + + (c) 2012 Tomasz Kołodziejczyk "Tommyline" + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + +***************************************************************************/ + +#define __CMD2OBJECT_C + +#include "cmd2object.h" + +#define THIS OBJECT(CMD2OBJECT) + +//--------------------------------------------------------------------------- + +BEGIN_METHOD(Md2Object_new, GB_OBJECT model) + + CMD2MODEL *model = VARG(model); + + if (GB.CheckObject(model)) + return; + + THIS->model = model; + GB.Ref(model); + + THIS->texture = -1; + + THIS->scale[0] = THIS->scale[1] = THIS->scale[2] = 1; + +END_METHOD + +BEGIN_METHOD_VOID(Md2Object_free) + + GB.Unref(POINTER(&THIS->model)); + +END_METHOD + + +BEGIN_METHOD(Md2Object_Move, GB_FLOAT x; GB_FLOAT y; GB_FLOAT z) + + THIS->pos[0] = VARG(x); + THIS->pos[1] = VARG(y); + THIS->pos[2] = VARG(z); + +END_METHOD + +BEGIN_PROPERTY(Md2Object_X) + + if (READ_PROPERTY) + GB.ReturnFloat(THIS->pos[0]); + else + THIS->pos[0] = VPROP(GB_FLOAT); + +END_PROPERTY + +BEGIN_PROPERTY(Md2Object_Y) + + if (READ_PROPERTY) + GB.ReturnFloat(THIS->pos[1]); + else + THIS->pos[1] = VPROP(GB_FLOAT); + +END_PROPERTY + +BEGIN_PROPERTY(Md2Object_Z) + + if (READ_PROPERTY) + GB.ReturnFloat(THIS->pos[2]); + else + THIS->pos[2] = VPROP(GB_FLOAT); + +END_PROPERTY + +BEGIN_METHOD(Md2Object_Scale, GB_FLOAT sx; GB_FLOAT sy; GB_FLOAT sz) + + THIS->scale[0] = VARG(sx); + THIS->scale[1] = VARG(sy); + THIS->scale[2] = VARG(sz); + +END_METHOD + +BEGIN_METHOD(Md2Object_Rotate, GB_FLOAT angle; GB_FLOAT rx; GB_FLOAT ry; GB_FLOAT rz) + + THIS->rotate[0] = VARG(angle); + THIS->rotate[1] = VARG(rx); + THIS->rotate[2] = VARG(ry); + THIS->rotate[3] = VARG(rz); + +END_METHOD + +BEGIN_PROPERTY(Md2Object_Texture) + + if (READ_PROPERTY) + GB.ReturnInteger(THIS->texture); + else + THIS->texture = VPROP(GB_INTEGER); + +END_PROPERTY + +BEGIN_PROPERTY(Md2Object_Frame) + + if (READ_PROPERTY) + GB.ReturnFloat(THIS->frame); + else + THIS->frame = VPROP(GB_FLOAT); + +END_PROPERTY + +BEGIN_METHOD_VOID(Md2Object_Draw) + + int texture = THIS->texture; + + if (texture < 0) + texture = THIS->model->texture; + + MD2MODEL_draw(THIS->model, THIS->frame, texture, THIS->pos, THIS->scale, THIS->rotate); + +END_METHOD + +BEGIN_PROPERTY(Md2Object_Model) + + GB.ReturnObject(THIS->model); + +END_PROPERTY + +BEGIN_PROPERTY(Md2Object_Count) + + GB.ReturnInteger(THIS->model->num_frames); + +END_PROPERTY + +//--------------------------------------------------------------------------- + +GB_DESC Md2ObjectDesc[] = +{ + GB_DECLARE("Md2Object", sizeof(CMD2OBJECT)), + + GB_METHOD("_new", NULL, Md2Object_new, "(Model)Md2Model;"), + GB_METHOD("_free", NULL, Md2Object_free, NULL), + + GB_PROPERTY_READ("X", "f", Md2Object_X), + GB_PROPERTY_READ("Y", "f", Md2Object_Y), + GB_PROPERTY_READ("Z", "f", Md2Object_Z), + + GB_METHOD("Move", NULL, Md2Object_Move, "(X)f(Y)f(Z)f"), + GB_METHOD("Scale", NULL, Md2Object_Scale, "(SX)f(SY)f(SZ)f"), + GB_METHOD("Rotate", NULL, Md2Object_Rotate, "(Angle)f(RX)f(RY)f(RZ)f"), + + GB_PROPERTY("Texture", "i", Md2Object_Texture), + GB_PROPERTY("Frame", "f", Md2Object_Frame), + GB_PROPERTY_READ("Count", "i", Md2Object_Count), + GB_METHOD("Draw", NULL, Md2Object_Draw, NULL), + + GB_PROPERTY_READ("Model", "Md2Model", Md2Object_Model), + + GB_END_DECLARE +}; + + diff --git a/gb.opengl/src/sge/cmd2object.h b/gb.opengl/src/sge/cmd2object.h new file mode 100644 index 000000000..4e461e1a5 --- /dev/null +++ b/gb.opengl/src/sge/cmd2object.h @@ -0,0 +1,48 @@ +/*************************************************************************** + + cmd2object.h + + (c) 2013 Benoît Minisini + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General License for more details. + + You should have received a copy of the GNU General License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + +***************************************************************************/ + +#ifndef __CMD2OBJECT_H +#define __CMD2OBJECT_H + +#include "gambas.h" +#include "main.h" +#include "cmd2model.h" + +#ifndef __CMD2OBJECT_C +extern GB_DESC Md2ObjectDesc[]; +#endif + +typedef + struct { + GB_BASE ob; + struct CMD2MODEL *model; + float pos[3]; + float scale[3]; + float rotate[4]; + double frame; + GLuint texture; + GB_VARIANT tag; + } + CMD2OBJECT; + +#endif diff --git a/gb.opengl/src/sge/main.c b/gb.opengl/src/sge/main.c index ab975c30e..03fddcb95 100644 --- a/gb.opengl/src/sge/main.c +++ b/gb.opengl/src/sge/main.c @@ -27,6 +27,7 @@ #include "main.h" #include "cmd2model.h" +#include "cmd2object.h" GB_INTERFACE GB EXPORT; @@ -34,7 +35,7 @@ GB_DESC *GB_CLASSES[] EXPORT = { Md2ModelFrameDesc, Md2ModelDesc, - + Md2ObjectDesc, NULL };