[EXAMPLES]

* NEW: Rework Md2Model example with the new gb.opengl.sge interface.

[GB.OPENGL.SGE]
* NEW: Split the model into Md2Model and Md2Object classes. Many Md2Object
  can share the same model.


git-svn-id: svn://localhost/gambas/trunk@5837 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2013-09-08 23:19:36 +00:00
parent 0d2256a19d
commit 3f71877a8b
7 changed files with 283 additions and 133 deletions

View File

@ -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

View File

@ -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

View File

@ -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
};

View File

@ -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

View File

@ -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
};

View File

@ -0,0 +1,48 @@
/***************************************************************************
cmd2object.h
(c) 2013 Benoît Minisini <gambas@users.sourceforge.net>
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

View File

@ -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
};