summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Schinagl <oliver@schinagl.nl>2008-05-14 11:56:06 (GMT)
committerOliver Schinagl <oliver@schinagl.nl>2008-05-14 11:56:06 (GMT)
commitd4d35970d88edccdd963e53ea3e11f702e1e2bab (patch)
treeaa3f522ef826752bf08e2396f70a3156e1b81e5b
parentab5d6fe55a31891ac8ad2949c31704e8245e116f (diff)
download2iv55-d4d35970d88edccdd963e53ea3e11f702e1e2bab.zip
2iv55-d4d35970d88edccdd963e53ea3e11f702e1e2bab.tar.gz
2iv55-d4d35970d88edccdd963e53ea3e11f702e1e2bab.tar.bz2
fix this
-rw-r--r--matchblox/AUTHORS0
-rw-r--r--matchblox/C_3DObject.cpp336
-rw-r--r--matchblox/C_3DObject.h66
-rw-r--r--matchblox/C_Block.cpp71
-rw-r--r--matchblox/C_Block.h33
-rw-r--r--matchblox/C_Box.cpp111
-rw-r--r--matchblox/C_Box.h35
-rw-r--r--matchblox/C_Environment.cpp119
-rw-r--r--matchblox/C_Environment.h32
-rw-r--r--matchblox/C_Hand.cpp43
-rw-r--r--matchblox/C_Hand.h33
-rw-r--r--matchblox/C_Log.cpp24
-rw-r--r--matchblox/C_Log.h20
-rw-r--r--matchblox/C_MatchBloxEngine.cpp348
-rw-r--r--matchblox/C_MatchBloxEngine.h87
-rw-r--r--matchblox/ChangeLog18
-rw-r--r--matchblox/Makefile43
-rw-r--r--matchblox/Makefile.am32
-rw-r--r--matchblox/NEWS0
-rw-r--r--matchblox/README0
-rw-r--r--matchblox/TODO.tasks6
-rwxr-xr-xmatchblox/autogen.sh159
-rw-r--r--matchblox/bitmap.cpp98
-rw-r--r--matchblox/bitmap.h24
-rw-r--r--matchblox/common/bitmap.c114
-rw-r--r--matchblox/common/bitmap.h24
-rw-r--r--matchblox/common/font.c90
-rw-r--r--matchblox/common/font.h30
-rw-r--r--matchblox/common/message_queue.c101
-rw-r--r--matchblox/common/message_queue.h37
-rw-r--r--matchblox/configure.ac29
-rw-r--r--matchblox/engine/C_3DObject.cpp336
-rw-r--r--matchblox/engine/C_3DObject.h66
-rw-r--r--matchblox/engine/C_Block.cpp71
-rw-r--r--matchblox/engine/C_Block.h33
-rw-r--r--matchblox/engine/C_Box.cpp111
-rw-r--r--matchblox/engine/C_Box.h35
-rw-r--r--matchblox/engine/C_Environment.cpp119
-rw-r--r--matchblox/engine/C_Environment.h32
-rw-r--r--matchblox/engine/C_Hand.cpp43
-rw-r--r--matchblox/engine/C_Hand.h33
-rw-r--r--matchblox/engine/C_Log.cpp24
-rw-r--r--matchblox/engine/C_Log.h20
-rw-r--r--matchblox/engine/C_MatchBloxEngine.cpp348
-rw-r--r--matchblox/engine/C_MatchBloxEngine.h87
-rw-r--r--matchblox/engine/MessageQueue.h26
-rw-r--r--matchblox/engine/typedefs.h128
-rw-r--r--matchblox/main.cpp158
-rw-r--r--matchblox/matchblox.anjuta44
-rw-r--r--matchblox/matchblox.vcproj277
-rw-r--r--matchblox/menu/button.c328
-rw-r--r--matchblox/menu/button.h54
-rw-r--r--matchblox/menu/menu.c359
-rw-r--r--matchblox/menu/menu.h10
-rw-r--r--matchblox/src/Makefile299
-rw-r--r--matchblox/src/Makefile.am13
-rw-r--r--matchblox/src/Makefile.in299
-rw-r--r--matchblox/src/main.c32
-rw-r--r--matchblox/src/renderer_opengl.c307
-rw-r--r--matchblox/src/renderer_opengl.h25
-rw-r--r--matchblox/typedefs.h128
61 files changed, 4745 insertions, 1263 deletions
diff --git a/matchblox/AUTHORS b/matchblox/AUTHORS
deleted file mode 100644
index e69de29..0000000
--- a/matchblox/AUTHORS
+++ /dev/null
diff --git a/matchblox/C_3DObject.cpp b/matchblox/C_3DObject.cpp
new file mode 100644
index 0000000..3cb00b1
--- /dev/null
+++ b/matchblox/C_3DObject.cpp
@@ -0,0 +1,336 @@
+#include <GL/glut.h>
+#include <vector>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include "typedefs.h"
+#include "C_3DObject.h"
+
+#include "bitmap.h"
+
+C_3DObject::C_3DObject()
+ : m_Pos(0.0, 0.0, 0.0), m_Rot(0.0, 0.0, 0.0),
+ m_Scale(1.0, 1.0, 1.0),
+ m_bOwnTexture(false),
+ m_bDispListValid(false)
+{
+ std::cout << "C_3DObject:: default constructor\n";
+}
+
+
+C_3DObject::C_3DObject(const char* f_strFileName,
+ char* f_strColorTexName,
+ MatProps_t f_Material)
+ : m_Pos(0.0, 0.0, 0.0), m_Rot(0.0, 0.0, 0.0),
+ m_Scale(1.0, 1.0, 1.0),
+ m_bOwnTexture(false),
+ m_bDispListValid(false),
+ m_Mat(f_Material)
+{
+ BitmapStruct l_bmp;
+
+ //load 3d model
+ m_bDispListValid = CreateObject(f_strFileName);
+
+ //load textures
+ if (m_bDispListValid)
+ {
+ if (f_strColorTexName != NULL)
+ {
+ std::cout << "Loading " << f_strColorTexName << std::endl;
+ l_bmp = BitmapLoad(f_strColorTexName);
+ m_uiColorTex = (GLuint)l_bmp.m_iImageId;
+ m_bOwnTexture = true;
+ }
+ }
+}
+
+C_3DObject::C_3DObject(const char* f_strFileName,
+ GLuint f_uiTexture,
+ MatProps_t f_Material)
+ : m_Pos(0.0, 0.0, 0.0), m_Rot(0.0, 0.0, 0.0),
+ m_Scale(1.0, 1.0, 1.0),
+ m_bOwnTexture(false),
+ m_bDispListValid(false),
+ m_uiColorTex(f_uiTexture),
+ m_Mat(f_Material)
+{
+ //load 3d model
+ m_bDispListValid = CreateObject(f_strFileName);
+
+}
+
+C_3DObject::~C_3DObject()
+{
+ if (glIsList(m_uiListIndex))
+ glDeleteLists(m_uiListIndex, 1);
+
+ if (glIsTexture(m_uiColorTex) && m_bOwnTexture)
+ glDeleteTextures(1, &m_uiColorTex);
+}
+
+void C_3DObject::TransRotateScale()
+{
+ glScaled(m_Scale.x, m_Scale.y, m_Scale.z);
+ glTranslated(m_Pos.x, m_Pos.y, m_Pos.z);
+ glRotated(m_Rot.z, 0.0, 0.0, 1.0);
+ glRotated(m_Rot.x, 1.0, 0.0, 0.0);
+ glRotated(m_Rot.y, 0.0, 1.0, 0.0);
+}
+
+void C_3DObject::Render()
+{
+ //apply OpenGL settings for rendering this Object
+ glPushAttrib(GL_TEXTURE_BIT);
+ glEnable(GL_TEXTURE_2D);
+ //modulate the texture color with the computed material
+ //colors
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glBindTexture(GL_TEXTURE_2D, m_uiColorTex);
+
+ //set material properties
+ glMaterialfv(GL_FRONT, GL_AMBIENT, m_Mat.m_fAmb);
+ glMaterialfv(GL_FRONT, GL_DIFFUSE, m_Mat.m_fDif);
+ glMaterialfv(GL_FRONT, GL_SPECULAR, m_Mat.m_fSpec);
+ glMaterialfv(GL_FRONT, GL_EMISSION, m_Mat.m_fEmi);
+ glMaterialf(GL_FRONT, GL_SHININESS, m_Mat.m_fShin);
+
+/*
+ //scale translate and rotate
+ glPushMatrix();
+
+ glScaled(m_Scale.x, m_Scale.y, m_Scale.z);
+ glTranslated(m_Pos.x, m_Pos.y, m_Pos.z);
+ glRotated(m_Rot.z, 0.0, 0.0, 1.0);
+ glRotated(m_Rot.x, 1.0, 0.0, 0.0);
+ glRotated(m_Rot.y, 0.0, 1.0, 0.0);
+*/
+
+ //render by calling the display list
+ if(m_bDispListValid)
+ {
+ glCallList(m_uiListIndex);
+ }
+ else
+ {
+ //or render a LARGE cube when we failed to load the
+ //geometry
+ glutSolidCube(10.0);
+ }
+
+// glPopMatrix();
+
+ glPopAttrib();
+}
+
+
+
+bool C_3DObject::CreateObject(const char *f_pFilePath)
+{
+ Geometry_t l_Geom;
+ bool l_bParseOk;
+ Vect3D_t l_DummyVect;
+
+ //the triangle indices are 1-based so we insert dummy Vect3D_t
+ //to fill the 0 positions in the vertex, normals and texcoords
+ //vector containers.
+ l_Geom.m_verts.push_back(l_DummyVect);
+ l_Geom.m_norms.push_back(l_DummyVect);
+ l_Geom.m_texs.push_back(l_DummyVect);
+
+ l_bParseOk = LoadGeometryData(f_pFilePath, l_Geom);
+
+ //output statistics
+ std::cout << "C_3DObject: file " << f_pFilePath
+ << "\nParse: " << (l_bParseOk? "SUCCESS" : "FAILURE")
+ << "\nVertices: " << l_Geom.m_verts.size()-1
+ << "\nNormals: " << l_Geom.m_norms.size()-1
+ << "\nTexCrds: " << l_Geom.m_texs.size()-1
+ << "\nTriangles: " << l_Geom.m_triangles.size()
+ << "\nBoundBox: x(" << m_BBox.m_dLeft << "," << m_BBox.m_dRight << ")"
+ << "\n y(" << m_BBox.m_dBottom << "," << m_BBox.m_dTop << ")"
+ << "\n z(" << m_BBox.m_dFront << "," << m_BBox.m_dBack << ")"
+ << std::endl;
+
+ if(!l_bParseOk)
+ {
+ std::cout << "C_3DObject Error: failed to parse file "
+ << f_pFilePath << std::endl;
+
+ return false;
+ }
+
+ //create display list
+ m_uiListIndex = glGenLists(1);
+ glNewList(m_uiListIndex, GL_COMPILE);
+
+ glBegin(GL_TRIANGLES);
+
+ //iterate through the triangles
+ std::vector<Triangle_t>::iterator it = l_Geom.m_triangles.begin();
+ for(; it != l_Geom.m_triangles.end(); it++)
+ {
+ //vertex1
+ Vect3D_t v = l_Geom.m_verts[it->v1],
+ t = l_Geom.m_texs[it->t1],
+ n = l_Geom.m_norms[it->n1];
+
+ glNormal3d(n.x, n.y, n.z);
+ glTexCoord3d(t.x, t.y, t.z);
+ glVertex3d(v.x, v.y, v.z);
+
+ //vertex2
+ v = l_Geom.m_verts[it->v2],
+ t = l_Geom.m_texs[it->t2],
+ n = l_Geom.m_norms[it->n2];
+
+ glNormal3d(n.x, n.y, n.z);
+ glTexCoord3d(t.x, t.y, t.z);
+ glVertex3d(v.x, v.y, v.z);
+
+ //vertex3
+ v = l_Geom.m_verts[it->v3],
+ t = l_Geom.m_texs[it->t3],
+ n = l_Geom.m_norms[it->n3];
+
+ glNormal3d(n.x, n.y, n.z);
+ glTexCoord3d(t.x, t.y, t.z);
+ glVertex3d(v.x, v.y, v.z);}
+
+ glEnd();
+
+ glEndList();
+
+ return true;
+}
+
+bool C_3DObject::LoadGeometryData(const char *f_pFilePath, Geometry_t &f_Geom)
+{
+ std::ifstream l_infile(f_pFilePath);
+ char l_inbuffer[256];
+ bool l_bParseOk = true;
+ Vect3D_t l_v3;
+ Triangle_t l_tri;
+
+ if (l_infile.fail())
+ {
+ std::cout << "C_3DObject Error: could not open file "
+ << f_pFilePath << std::endl;
+
+ return false;
+ }
+
+
+ //load data
+ while(!l_infile.eof() && l_bParseOk)
+ {
+ //read the next line
+ l_infile.getline(l_inbuffer, 256);
+
+ //check if reading succeeded
+ if (l_infile.eof() || l_infile.fail() || l_infile.bad())
+ {
+ break;
+ }
+
+ //try to parse the first string of the line as one of the keywords:
+ //v -> vertex coordinate
+ //vt -> texture coordinate
+ //vn -> vertex normal
+ //f -> face record
+ switch (l_inbuffer[0])
+ {
+ case 'v' :
+ //posibilities 'v' 'vt' 'vn'
+ switch (l_inbuffer[1])
+ {
+ case ' ':
+ //vertex
+ if (l_bParseOk = ParseVect3D(&l_inbuffer[2], l_v3))
+ {
+ f_Geom.m_verts.push_back(l_v3);
+ //update boundingbox
+ UpdBBox(m_BBox, l_v3);
+ }
+ break;
+
+ case 't':
+ if (l_inbuffer[2] == ' ')
+ {
+ //texture coordinates
+ if (l_bParseOk = ParseVect3D(&l_inbuffer[3], l_v3))
+ {
+ f_Geom.m_texs.push_back(l_v3);
+ }
+ }
+ break;
+
+ case 'n':
+ if (l_inbuffer[2] == ' ')
+ {
+ //normal
+ if (l_bParseOk = ParseVect3D(&l_inbuffer[3], l_v3))
+ {
+ f_Geom.m_norms.push_back(l_v3);
+ }
+ }
+ break;
+ }
+ break;
+
+ case 'f':
+ if (l_inbuffer[1] == ' ')
+ {
+ //face (triangle)
+ if (l_bParseOk = ParseTriangle(&l_inbuffer[2], l_tri))
+ {
+ f_Geom.m_triangles.push_back(l_tri);
+ }
+ }
+ break;
+
+ case 'm' : // 'mtllib'?
+ break;
+
+ case 'u' : // 'usemtl' ?
+ break;
+ }
+ }
+
+ l_infile.close();
+
+ if (!l_bParseOk)
+ {
+ std::cout << "Parse error in: \"" << l_inbuffer << "\"\n";
+ }
+
+ return l_bParseOk;
+}
+
+bool C_3DObject::ParseVect3D(const char *f_pInBuffer, Vect3D_t &f_V3)
+{
+ //format: " x y z "
+ std::stringstream l_inbuffer(f_pInBuffer);
+
+ l_inbuffer >> std::skipws >> f_V3.x >> f_V3.y >> f_V3.z;
+
+ //std::cout << "Read values: " << f_V3.x << ", " << f_V3.y << ", " << f_V3.z << "\n";
+
+ return !l_inbuffer.fail();
+}
+
+bool C_3DObject::ParseTriangle(const char *f_pInBuffer, Triangle_t &f_triangle)
+{
+ //format v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3
+ std::stringstream l_inbuffer(f_pInBuffer);
+
+ char l_slash;
+
+ l_inbuffer >> std::skipws >> f_triangle.v1 >> l_slash >> f_triangle.t1 >> l_slash >> f_triangle.n1;
+ l_inbuffer >> std::skipws >> f_triangle.v2 >> l_slash >> f_triangle.t2 >> l_slash >> f_triangle.n2;
+ l_inbuffer >> std::skipws >> f_triangle.v3 >> l_slash >> f_triangle.t3 >> l_slash >> f_triangle.n3;
+
+ return !l_inbuffer.fail();
+}
+
diff --git a/matchblox/C_3DObject.h b/matchblox/C_3DObject.h
new file mode 100644
index 0000000..4027596
--- /dev/null
+++ b/matchblox/C_3DObject.h
@@ -0,0 +1,66 @@
+#ifndef C_3DOBJECT_HEADER_FILE
+
+#define C_3DOBJECT_HEADER_FILE
+
+#include <fstream>
+#include <vector>
+
+#include "typedefs.h"
+
+class C_3DObject
+{
+public:
+ C_3DObject();
+ C_3DObject(const char* f_strFileName,
+ char* f_strColorTexName,
+ MatProps_t f_Material);
+ C_3DObject(const char* f_strFileName,
+ GLuint f_uiTexturei,
+ MatProps_t f_Material);
+
+ ~C_3DObject();
+
+ inline void SetPos(double f_dX, double f_dY, double f_dZ)
+ { m_Pos.x = f_dX; m_Pos.y = f_dY; m_Pos.z = f_dZ; }
+ inline void SetRot(double f_dX, double f_dY, double f_dZ)
+ { m_Rot.x = f_dX; m_Rot.y = f_dY; m_Rot.z = f_dZ; }
+ inline void SetScale(double f_dX, double f_dY, double f_dZ)
+ { m_Scale.x = f_dX; m_Scale.y = f_dY; m_Scale.z = f_dZ; }
+ inline void SetPos(const Vect3D_t &pos)
+ { m_Pos = pos; }
+ inline void SetRot(const Vect3D_t &rot)
+ { m_Rot = rot; }
+ inline void SetScale(const Vect3D_t &scale)
+ { m_Scale = scale; }
+
+ inline const Vect3D_t& GetPos() { return m_Pos; }
+ inline const Vect3D_t& GetRot() { return m_Rot; }
+ inline const Vect3D_t& GetScale() { return m_Scale; }
+ inline const BoundingBox_t& GetBoundingBox() { return m_BBox; }
+ inline bool Initialized() { return m_bDispListValid; }
+
+ void TransRotateScale(); //applies the scaling, translation and rotation
+ //for this object
+ virtual void Render(); //renders the object using the current projection
+ //and modelview matrices
+
+protected:
+ Vect3D_t m_Pos,
+ m_Rot,
+ m_Scale;
+
+ BoundingBox_t m_BBox; //bounding box of the object
+ GLuint m_uiListIndex; //display list index
+ bool m_bDispListValid;
+ GLuint m_uiColorTex;
+ bool m_bOwnTexture;
+ MatProps_t m_Mat;
+
+ bool CreateObject(const char *f_pFilePath);
+ bool LoadGeometryData(const char *f_pFilePath, Geometry_t &f_Geom);
+ bool ParseVect3D(const char *f_pInbuffer, Vect3D_t &f_V3);
+ bool ParseTriangle(const char *f_pInbuffer, Triangle_t &f_triangle);
+};
+
+#endif //C_3DOBJECT_HEADER_FILE
+
diff --git a/matchblox/C_Block.cpp b/matchblox/C_Block.cpp
new file mode 100644
index 0000000..4c092a2
--- /dev/null
+++ b/matchblox/C_Block.cpp
@@ -0,0 +1,71 @@
+#include <GL/glut.h>
+
+#include <iostream>
+
+#include "C_Block.h"
+
+#define FADE_DURATION 500
+
+/*Durations of animations*/
+unsigned int g_BlockAnimDurations[4] = {0, 500, 500, 500};
+
+C_Block::C_Block(const char* f_strFileName,
+ GLuint f_uiColorTex ,
+ MatProps_t f_Mat)
+: C_3DObject(f_strFileName, f_uiColorTex, f_Mat),
+ m_CurrState(BS_IDLE), m_uiAnimStart(0)
+{
+
+}
+
+C_Block::~C_Block()
+{
+
+}
+
+void C_Block::Render(unsigned int f_iElapsedTime)
+{
+ unsigned int l_uiDeltaTime = f_iElapsedTime - m_uiAnimStart;
+ double l_Scale = 0.0;
+
+
+ //check if the previous animation has ended in between
+ //calls to this Render function.
+ if (l_uiDeltaTime > g_BlockAnimDurations[(int)m_CurrState])
+ {
+ m_CurrState = BS_IDLE;
+ }
+
+ glPushMatrix();
+
+ switch (m_CurrState)
+ {
+ case BS_FADE_IN:
+ l_Scale = (double)l_uiDeltaTime / (double)g_BlockAnimDurations[BS_FADE_IN];
+ //glScaled(l_Scale, l_Scale, l_Scale);
+ SetScale(l_Scale, l_Scale, l_Scale);
+ TransRotateScale();
+ C_3DObject::Render();
+ break;
+
+ case BS_FADE_OUT:
+ l_Scale = 1.0 - ((double)l_uiDeltaTime / (double)g_BlockAnimDurations[BS_FADE_OUT]);
+// glScaled(l_Scale, l_Scale, l_Scale);
+ SetScale(l_Scale, l_Scale, l_Scale);
+ TransRotateScale();
+ C_3DObject::Render();
+ break;
+
+ case BS_COLLIDE:
+ break;
+
+ case BS_IDLE:
+ default:
+ TransRotateScale();
+ C_3DObject::Render();
+ break;
+ }
+
+ glPopMatrix();
+
+}
diff --git a/matchblox/C_Block.h b/matchblox/C_Block.h
new file mode 100644
index 0000000..f0e03b7
--- /dev/null
+++ b/matchblox/C_Block.h
@@ -0,0 +1,33 @@
+#ifndef C_BLOCK_HEADER_FILE
+
+#define C_BLOCK_HEADER_FILE
+
+#include "C_3DObject.h"
+
+typedef enum BlockAnimState
+{
+ BS_IDLE = 0,
+ BS_FADE_IN = 1,
+ BS_FADE_OUT = 2,
+ BS_COLLIDE = 3
+};
+
+
+class C_Block : public C_3DObject
+{
+public:
+ C_Block(const char* f_strFileName,
+ GLuint f_uiColorTex ,
+ MatProps_t f_Mat);
+ ~C_Block();
+
+ void Render(unsigned int f_iElapsedTime);
+ inline void SetState(BlockAnimState f_State, unsigned int f_uiElapsedTime) { m_CurrState = f_State; m_uiAnimStart = f_uiElapsedTime; }
+
+private:
+ BlockAnimState m_CurrState;
+ unsigned int m_uiAnimStart;
+};
+
+#endif //C_BLOCK_HEADER_FILE
+
diff --git a/matchblox/C_Box.cpp b/matchblox/C_Box.cpp
new file mode 100644
index 0000000..9bde3ff
--- /dev/null
+++ b/matchblox/C_Box.cpp
@@ -0,0 +1,111 @@
+#include <GL/glut.h>
+#include <math.h>
+
+#include "C_Box.h"
+#include "typedefs.h"
+
+C_Box::C_Box(const char *f_strFileName,
+ GLuint f_uiTexture,
+ MatProps_t f_Mat,
+ int f_iTilesX, int f_iTilesY,
+ C_3DObject *f_pTiles[5])
+: C_3DObject(f_strFileName, f_uiTexture, f_Mat),
+ m_pTiles(f_pTiles), m_iTilesX(f_iTilesX),
+ m_iTilesY(f_iTilesY)
+{
+ m_iNumTiles = m_iTilesX * m_iTilesY;
+ //create a new tiles layout array
+ m_iTilesLayout = new int[m_iNumTiles];
+
+ //calculate the tile size (this should be the same
+ //for all tile types)
+ BoundingBox_t l_BBox = m_pTiles[0]->GetBoundingBox();
+ m_dTileSize = l_BBox.m_dRight - l_BBox.m_dLeft;
+
+ //calculate the lower left tile position (in xz plane)
+ m_LowLeftTilePos = Vect3D_t(-m_dTileSize * (double)(m_iTilesX-1)/2.0,
+ 0.0,
+ m_dTileSize * (double)(m_iTilesY-1)/2.0);
+}
+
+C_Box::~C_Box()
+{
+ delete [] m_iTilesLayout;
+}
+
+void C_Box::RandomizeTiles()
+{
+ int l_iNumTiles = m_iTilesX * m_iTilesY;
+
+ //first set the layout to all tiles with no hole
+ for (int i=0; i<l_iNumTiles; i++)
+ m_iTilesLayout[i] = 4;
+
+ //add the four hole tiles
+ for (int i=0; i<4; i++)
+ {
+ //generate a random number in the range
+ //0 - (l_iNumTiles-1)
+ int pos = rand() % l_iNumTiles;
+
+ //skip position in which we already inserted a hole
+ //type tile (type 4)
+ while (m_iTilesLayout[pos] != 4)
+ pos = (pos+1) % l_iNumTiles;
+
+ //insert the hole tile in the free spot
+ m_iTilesLayout[pos] = i;
+
+ //set the position for the hole tile relative to the box its position
+ int col = pos % m_iTilesX;
+ int row = pos / m_iTilesX;
+
+ m_pTiles[i]->SetPos(m_LowLeftTilePos.x + (double)col * m_dTileSize,
+ 0.0,
+ m_LowLeftTilePos.z - (double)row * m_dTileSize);
+ }
+}
+
+void C_Box::Render()
+{
+ //
+ glPushMatrix();
+
+ //apply transformation for box
+ TransRotateScale();
+
+ //render the box
+ C_3DObject::Render();
+
+
+ //render the tiles
+ for(int x=0; x<m_iTilesX; x++)
+ for(int y=0; y<m_iTilesY; y++)
+ {
+ int l_iTileIndex = m_iTilesLayout[x + y*m_iTilesX];
+ //check the tile
+ if (l_iTileIndex >= 0 && l_iTileIndex <= 3)
+ {
+ //tile with a hole
+ glPushMatrix();
+ m_pTiles[l_iTileIndex]->TransRotateScale();
+ m_pTiles[l_iTileIndex]->Render();
+ glPopMatrix();
+ }
+ else
+ {
+ //tile without a hole
+ //set the position
+ m_pTiles[4]->SetPos(m_LowLeftTilePos.x + (double)x * m_dTileSize,
+ 0.0,
+ m_LowLeftTilePos.z - (double)y * m_dTileSize);
+ glPushMatrix();
+ m_pTiles[4]->TransRotateScale();
+ m_pTiles[4]->Render();
+ glPopMatrix();
+ }
+ }
+
+ glPopMatrix();
+}
+
diff --git a/matchblox/C_Box.h b/matchblox/C_Box.h
new file mode 100644
index 0000000..ed8c133
--- /dev/null
+++ b/matchblox/C_Box.h
@@ -0,0 +1,35 @@
+#ifndef C_BOX_HEADER_FILE
+
+#define C_BOX_HEADER_FILE
+
+#include <GL/glut.h>
+#include "C_3DObject.h"
+
+class C_Box : public C_3DObject
+{
+public:
+ C_Box(const char *f_strFileName,
+ GLuint f_uiTexture,
+ MatProps_t f_Mat,
+ int f_iTilesX, int f_iTilesY,
+ C_3DObject *f_pTiles[5]);
+
+ ~C_Box();
+
+ void RandomizeTiles();
+ void Render();
+
+private:
+ C_3DObject **m_pTiles; //the tile objects for the top face of the box (holes)
+ int m_iTilesX, //number of tiles in x direction
+ m_iTilesY, //number of tiles in y direction
+ m_iNumTiles; //total number of tiles
+ double m_dTileSize; //the width and height of a tile
+ Vect3D_t m_LowLeftTilePos; //center position of the lower leftmost
+ //tile (relative to the box its position)
+
+ int *m_iTilesLayout; //the indices of the tile objects
+};
+
+#endif //C_BOX_HEADER_FILE
+
diff --git a/matchblox/C_Environment.cpp b/matchblox/C_Environment.cpp
new file mode 100644
index 0000000..0c7cbfd
--- /dev/null
+++ b/matchblox/C_Environment.cpp
@@ -0,0 +1,119 @@
+#include <GL/glut.h>
+#include <string>
+#include <iostream>
+
+#include "bitmap.h"
+#include "C_Environment.h"
+
+#ifndef GL_CLAMP_TO_EDGE
+#define GL_CLAMP_TO_EDGE 0x812F
+#endif //GL_CLAMP_TO_EDGE
+
+using namespace std;
+
+C_Environment::C_Environment(const char *f_strEnvMapBaseName,
+ double f_dDistance)
+ : m_dDist(f_dDistance)
+{
+ string l_strBase = f_strEnvMapBaseName,
+ l_strFilename;
+ const char *l_suffix[] = { "negative_x.bmp",
+ "negative_y.bmp",
+ "negative_z.bmp",
+ "positive_x.bmp",
+ "positive_y.bmp",
+ "positive_z.bmp"
+ };
+
+ BitmapStruct l_bmp;
+
+ //load textures
+ for (int i=0; i<6; i++)
+ {
+ l_strFilename = l_strBase + l_suffix[i];
+ l_bmp = BitmapLoad((char*)l_strFilename.c_str());
+ m_uiFaceTex[i] = (GLuint)l_bmp.m_iImageId;
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ }
+}
+
+C_Environment::~C_Environment()
+{
+ glDeleteTextures(6, m_uiFaceTex);
+}
+
+void C_Environment::Render()
+{
+ double l_Vertices[8][3] =
+ { { -m_dDist, -m_dDist, m_dDist },
+ { m_dDist, -m_dDist, m_dDist },
+ { m_dDist, -m_dDist, -m_dDist },
+ { -m_dDist, -m_dDist, -m_dDist },
+ { -m_dDist, m_dDist, m_dDist },
+ { m_dDist, m_dDist, m_dDist },
+ { m_dDist, m_dDist, -m_dDist },
+ { -m_dDist, m_dDist, -m_dDist } };
+
+
+ //init render settings for rendering of the environment
+ //mapped cube
+
+ glPushAttrib(GL_TEXTURE_BIT | GL_ENABLE_BIT);
+
+ //no lighting
+ glDisable(GL_LIGHTING);
+ //enable texturing
+ glEnable(GL_TEXTURE_2D);
+ glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ //neg x (left)
+ glBindTexture(GL_TEXTURE_2D, m_uiFaceTex[0]);
+ RenderFace(l_Vertices, 3, 0, 4, 7);
+
+ //neg y (down)
+ glBindTexture(GL_TEXTURE_2D, m_uiFaceTex[1]);
+ RenderFace(l_Vertices, 3, 2, 1, 0);
+
+ //nez z (front)
+ glBindTexture(GL_TEXTURE_2D, m_uiFaceTex[2]);
+ RenderFace(l_Vertices, 2, 3, 7, 6);
+
+ //pos x (right)
+ glBindTexture(GL_TEXTURE_2D, m_uiFaceTex[3]);
+ RenderFace(l_Vertices, 1, 2, 6, 5);
+
+ //pos y (top)
+ glBindTexture(GL_TEXTURE_2D, m_uiFaceTex[4]);
+ RenderFace(l_Vertices, 4, 5, 6, 7);
+
+ //pos z (back)
+ glBindTexture(GL_TEXTURE_2D, m_uiFaceTex[5]);
+ RenderFace(l_Vertices, 0, 1, 5, 4);
+
+ glPopAttrib();
+}
+
+void C_Environment::RenderFace(double f_verts[8][3],
+ int f_v00, int f_v10,
+ int f_v11, int f_v01)
+{
+ //render textured quad in counter clockwise order
+ glBegin(GL_QUADS);
+ glTexCoord2i(0,0);
+ glVertex3dv(f_verts[f_v00]);
+
+ glTexCoord2i(1,0);
+ glVertex3dv(f_verts[f_v10]);
+
+ glTexCoord2i(1,1);
+ glVertex3dv(f_verts[f_v11]);
+
+ glTexCoord2i(0,1);
+ glVertex3dv(f_verts[f_v01]);
+ glEnd();
+
+}
diff --git a/matchblox/C_Environment.h b/matchblox/C_Environment.h
new file mode 100644
index 0000000..cfdb816
--- /dev/null
+++ b/matchblox/C_Environment.h
@@ -0,0 +1,32 @@
+#ifndef C_ENVIRONMENT_H
+
+#define C_ENVIRONMENT_H
+
+#include <GL/glut.h>
+
+class C_Environment
+{
+public:
+ //environment map consist of 6 bitmaps with a common
+ //base name with the axis name (_positive_x.bmp,
+ //_negative_y.bmp, ...)
+ //appended, the distance is the distance from the center
+ //to the sides of the cube
+ C_Environment(const char *f_strEnvMapBaseName,
+ double f_dDistance);
+ ~C_Environment();
+
+ void Render();
+ void RenderFace(double f_verts[8][3],
+ int f_v00, int f_v10,
+ int f_v11, int f_v01);
+
+private:
+ double m_dDist;
+
+ //texture handles for the faces of the cube
+ GLuint m_uiFaceTex[6]; //order -x, -y, -z, +x, +y, +z
+};
+
+#endif //C_ENVIRONMENT_H
+
diff --git a/matchblox/C_Hand.cpp b/matchblox/C_Hand.cpp
new file mode 100644
index 0000000..8c4d977
--- /dev/null
+++ b/matchblox/C_Hand.cpp
@@ -0,0 +1,43 @@
+#include <GL/glut.h>
+#include "C_Hand.h"
+
+#define FADE_DURATION 500
+
+//duration of animations in ms
+unsigned int g_HandAnimDurations[3] = {0, 100, 100};
+
+
+C_Hand::C_Hand(const char* f_strFileName, GLuint f_uiTex,
+ MatProps_t f_Mat)
+: C_3DObject(f_strFileName, f_uiTex, f_Mat),
+ m_CurrState(HS_IDLE), m_uiAnimStart(0)
+{
+}
+
+
+void C_Hand::Render(unsigned int f_iElapsedTime)
+{
+ unsigned int l_uiDeltaTime = f_iElapsedTime - m_uiAnimStart;
+
+ if (l_uiDeltaTime > g_HandAnimDurations[(int)m_CurrState])
+ {
+ m_CurrState = HS_IDLE;
+ }
+
+ switch (m_CurrState)
+ {
+ case HS_GRAB:
+ C_3DObject::Render();
+ break;
+
+ case HS_RELEASE:
+ C_3DObject::Render();
+ break;
+
+ case HS_IDLE:
+ default:
+ C_3DObject::Render();
+ break;
+ }
+
+}
diff --git a/matchblox/C_Hand.h b/matchblox/C_Hand.h
new file mode 100644
index 0000000..3ada63d
--- /dev/null
+++ b/matchblox/C_Hand.h
@@ -0,0 +1,33 @@
+#ifndef C_HAND_HEADER_FILE
+
+#define C_HAND_HEADER_FILE
+
+#include "C_3DObject.h"
+#include "typedefs.h"
+
+typedef enum HandAnimState
+{
+ HS_IDLE = 0,
+ HS_GRAB = 1,
+ HS_RELEASE = 2,
+ HS_COLLIDE = 3
+};
+
+
+class C_Hand : public C_3DObject
+{
+public:
+ C_Hand(const char* f_strFileName, GLuint f_uiTex,
+ MatProps_t f_Mat);
+ ~C_Hand();
+
+ void Render(unsigned int f_iElapsedTime);
+ inline void SetState(HandAnimState f_State, unsigned int f_uiElapsedTime) { m_CurrState = f_State; m_uiAnimStart = f_uiElapsedTime; }
+
+private:
+ HandAnimState m_CurrState;
+ unsigned int m_uiAnimStart;
+};
+
+#endif //C_HAND_HEADER_FILE
+
diff --git a/matchblox/C_Log.cpp b/matchblox/C_Log.cpp
new file mode 100644
index 0000000..d9a1154
--- /dev/null
+++ b/matchblox/C_Log.cpp
@@ -0,0 +1,24 @@
+#include "C_Log.h"
+
+C_Log::C_Log(char *f_strFileName)
+{
+}
+
+C_Log::~C_Log()
+{
+}
+
+bool C_Log::LogNewSession(int f_iUserID, int f_iGameID)
+{
+ return true;
+}
+
+bool C_Log::LogSessionTurn(int f_iUserID, int f_iGameID, int f_iBlockNr, int HolePos, unsigned int f_uiTime)
+{
+ return true;
+}
+
+bool C_Log::LogSessionTotals(int f_iUserID, int f_iGameID, unsigned int f_uiTotalTime)
+{
+ return true;
+}
diff --git a/matchblox/C_Log.h b/matchblox/C_Log.h
new file mode 100644
index 0000000..2b598dd
--- /dev/null
+++ b/matchblox/C_Log.h
@@ -0,0 +1,20 @@
+#ifndef C_LOG_HEADER_FILE
+
+#define C_LOG_HEADER_FILE
+
+class C_Log
+{
+public:
+ C_Log(char *f_strFileName);
+ ~C_Log();
+
+ bool LogNewSession(int f_iUserID, int f_iGameID);
+ bool LogSessionTurn(int f_iUserID, int f_iGameID, int f_iBlockNr, int HolePos, unsigned int f_uiTime);
+ bool LogSessionTotals(int f_iUserID, int f_iGameID, unsigned int f_uiTotalTime);
+
+private:
+// FILE *m_pLogFile;
+};
+
+#endif //C_LOG_HEADER_FILE
+
diff --git a/matchblox/C_MatchBloxEngine.cpp b/matchblox/C_MatchBloxEngine.cpp
new file mode 100644
index 0000000..7e17b1b
--- /dev/null
+++ b/matchblox/C_MatchBloxEngine.cpp
@@ -0,0 +1,348 @@
+#include <GL/glut.h>
+
+#include <time.h>
+#include <string>
+#include <iostream>
+
+#include "C_MatchBloxEngine.h"
+
+#include "C_3DObject.h"
+#include "C_Environment.h"
+#include "C_Hand.h"
+#include "C_Block.h"
+#include "C_Box.h"
+#include "C_Log.h"
+#include "bitmap.h"
+
+C_MatchBloxEngine::C_MatchBloxEngine(const char *f_strModelPath,
+ const char *f_strLogFile)
+{
+ //create logger
+
+
+ //Load models
+ if (LoadModels(f_strModelPath))
+ {
+ //set state to initialised;
+ m_State = ES_INITIALISED;
+ }
+ else
+ {
+ m_State = ES_ERROR;
+ }
+
+ //initialise a random seed
+ srand ( time(NULL) );
+
+ //init vars
+ m_CurrentBox = BS_SMALL;
+
+ //debug
+ m_pBox[0]->SetPos(0.0, -5.0, -15.0);
+ m_pBox[0]->SetRot(45.0, 0.0, 0.0);
+ m_pBox[0]->RandomizeTiles();
+
+ m_pBlock[0]->SetPos(-6.0, 1.0, -10.0);
+ m_pBlock[0]->SetRot(90.0, 0.0, 0.0);
+ m_pBlock[1]->SetPos(-2.0, 1.0, -10.0);
+ m_pBlock[1]->SetRot(90.0, 0.0, 0.0);
+ m_pBlock[2]->SetPos(2.0, 1.0, -10.0);
+ m_pBlock[2]->SetRot(90.0, 0.0, 0.0);
+ m_pBlock[3]->SetPos(6.0, 1.0, -10.0);
+ m_pBlock[3]->SetRot(90.0, 0.0, 0.0);
+}
+
+C_MatchBloxEngine::~C_MatchBloxEngine()
+{
+ //destroy logger
+
+ //delete models
+ DeleteModels();
+}
+
+GameResult C_MatchBloxEngine::GameStep(msgQueue &f_Queue)
+{
+ //process message queue
+ return GR_ERROR;
+}
+
+void C_MatchBloxEngine::Render_Basics(unsigned int f_uiElapsedTime)
+{
+ //render the environment
+ m_pEnvMap->Render();
+
+ m_pBox[(intptr_t)m_CurrentBox]->Render();
+ for (int i=0; i<4; i++)
+ m_pBlock[i]->Render(f_uiElapsedTime);
+// m_pHand->Render(f_uiElapsedTime);
+}
+
+void C_MatchBloxEngine::Render(unsigned int f_uiElapsedTime)
+{
+ switch (m_State)
+ {
+ case ES_INITIALISED:
+ Render_Basics(f_uiElapsedTime);
+ break;
+
+ case ES_ERROR:
+ //render a red cube
+ glPushMatrix();
+ glPushAttrib(GL_ENABLE_BIT);
+ glDisable(GL_LIGHTING);
+ glColor3d(1.0, 0.0, 0.0);
+ glTranslated(0.0, 0.0, -5.0);
+ glutSolidCube(5.0);
+ glPopAttrib();
+ glPopMatrix();
+ break;
+
+ case ES_GET_READY:
+ Render_Basics(f_uiElapsedTime);
+ //render some GET READY text
+ break;
+
+ case ES_PLAYING_GRAB_BLOCK:
+ Render_Basics(f_uiElapsedTime);
+ break;
+
+ case ES_PLAYING_PUT_BLOCK:
+ Render_Basics(f_uiElapsedTime);
+ break;
+
+ case ES_PAUSED:
+ Render_Basics(f_uiElapsedTime);
+ //render menu??
+ break;
+
+ case ES_FINISHED:
+ //render results...
+ break;
+ }
+
+ //glPushMatrix();
+
+ //double l_dSeconds = (double)f_uiElapsedTime/1000.0;
+
+ //glRotated(l_dSeconds * 5.0, 0.0, 1.0, 0.0);
+ ////glRotated(l_dSeconds * 10, 0.0, 0.0, 1.0);
+
+ //m_pEnvMap->Render();
+
+ //glPopMatrix();
+
+ //m_pBox[0]->Render();
+
+ //for(int i=0; i<4; i++)
+ //{
+ // glPushMatrix();
+ // m_pBlock[i]->Render(f_uiElapsedTime);
+ // glPopMatrix();
+ //}
+
+}
+
+bool C_MatchBloxEngine::NewGame(int f_iUserID, int f_iGameId, BoxSize f_BS)
+{
+ if(m_State == ES_INITIALISED)
+ {
+ //log new game
+
+ //prepare a fresh box
+ m_CurrentBox = f_BS;
+ m_pBox[(int)m_CurrentBox]->RandomizeTiles();
+
+ //set state to GET READY
+ m_State = ES_GET_READY;
+
+ //init object positions
+ m_pBox[(int)m_CurrentBox]->SetPos(0.0, -6.0, -15.0);
+ return true;
+ }
+
+ return false;
+}
+
+bool C_MatchBloxEngine::StartGame()
+{
+ return false;
+}
+
+bool C_MatchBloxEngine::Pause()
+{
+ //only pause when playing
+ if (m_State == ES_PLAYING_GRAB_BLOCK ||
+ m_State == ES_PLAYING_PUT_BLOCK)
+ {
+ //save current state
+ m_SavedState = m_State;
+
+ //probably do something with a time variable
+
+ //set current state to paused
+ m_State = ES_PAUSED;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool C_MatchBloxEngine::Resume()
+{
+ if (m_State == ES_PAUSED)
+ {
+ //restore previous state
+ m_State = m_SavedState;
+
+ //restore timers
+ //
+
+ return true;
+ }
+ return false;
+}
+
+bool C_MatchBloxEngine::Abort()
+{
+ //abort when not in error or init state
+ if (m_State != ES_ERROR && m_State != ES_INITIALISED)
+ {
+ //set state to initialised
+ m_State = ES_INITIALISED;
+
+ //..
+
+ return true;
+ }
+ return false;
+}
+
+bool C_MatchBloxEngine::LoadModels(const char* f_strModelDir)
+{
+ MatProps_t l_Mat;
+ std::string l_BaseName = f_strModelDir;
+
+ //create the environment mapped cube
+ m_pEnvMap = new C_Environment("envmaps/terrain_", 50.0);
+
+ //load the bitmaps for the textures
+ LoadTexture((l_BaseName + "/wood1.bmp").c_str(), m_uiWood1Tex);
+ LoadTexture((l_BaseName + "/wood2.bmp").c_str(), m_uiWood2Tex);
+ LoadTexture((l_BaseName + "/wood3.bmp").c_str(), m_uiWood3Tex);
+
+ //load the block models
+ //red squares
+ l_Mat.setAmb(1.0, 0.0, 0.0, 1.0);
+ l_Mat.setDif(1.0, 0.0, 0.0, 1.0);
+ m_pBlock[BT_SQUARE] = new C_Block((l_BaseName + "/square.obj").c_str(),
+ m_uiWood1Tex, l_Mat);
+ if (!m_pBlock[BT_SQUARE]->Initialized()) return false;
+
+ //yellow cricles
+ l_Mat.setAmb(0.0, 1.0, 1.0, 1.0);
+ l_Mat.setDif(0.0, 1.0, 1.0, 1.0);
+ m_pBlock[BT_CIRCLE] = new C_Block((l_BaseName + "/circle.obj").c_str(),
+ m_uiWood1Tex, l_Mat);
+ if (!m_pBlock[BT_CIRCLE]->Initialized()) return false;
+
+ //green triangles
+ l_Mat.setAmb(0.0, 1.0, 0.0, 1.0);
+ l_Mat.setDif(0.0, 1.0, 0.0, 1.0);
+ m_pBlock[BT_TRIANGLE] = new C_Block((l_BaseName + "/triangle.obj").c_str(),
+ m_uiWood1Tex, l_Mat);
+ if (!m_pBlock[BT_TRIANGLE]->Initialized()) return false;
+
+ //blue crosses
+ l_Mat.setAmb(0.0, 0.0, 1.0, 1.0);
+ l_Mat.setDif(0.0, 0.0, 1.0, 1.0);
+ m_pBlock[BT_CROSS] = new C_Block((l_BaseName + "/cross.obj").c_str(),
+ m_uiWood1Tex, l_Mat);
+ if (!m_pBlock[BT_CROSS]->Initialized()) return false;
+
+
+ //load the hand???
+
+
+ //Load the box tiles
+ l_Mat.setAmb(1.0, 1.0, 1.0, 1.0);
+ l_Mat.setDif(1.0, 1.0, 1.0, 1.0);
+
+ m_pTiles[BT_SQUARE] = new C_3DObject((l_BaseName + "/tile_square.obj").c_str(),
+ m_uiWood3Tex, l_Mat);
+ if (!m_pTiles[BT_SQUARE]->Initialized()) return false;
+
+ m_pTiles[BT_CIRCLE] = new C_3DObject((l_BaseName + "/tile_circle.obj").c_str(),
+ m_uiWood3Tex, l_Mat);
+ if (!m_pTiles[BT_CIRCLE]->Initialized()) return false;
+
+ m_pTiles[BT_TRIANGLE] = new C_3DObject((l_BaseName + "/tile_triangle.obj").c_str(),
+ m_uiWood3Tex, l_Mat);
+ if (!m_pTiles[BT_TRIANGLE]->Initialized()) return false;
+
+ m_pTiles[BT_CROSS] = new C_3DObject((l_BaseName + "/tile_cross.obj").c_str(),
+ m_uiWood3Tex, l_Mat);
+ if (!m_pTiles[BT_CROSS]->Initialized()) return false;
+
+ m_pTiles[4] = new C_3DObject((l_BaseName + "/tile_no_hole.obj").c_str(),
+ m_uiWood3Tex, l_Mat);
+ if (!m_pTiles[4]->Initialized()) return false;
+
+
+ //Load the box models
+ m_pBox[0] = new C_Box((l_BaseName + "/box_small.obj").c_str(),
+ m_uiWood2Tex, l_Mat, 2, 2, m_pTiles);
+ if (!m_pBox[0]->Initialized()) return false;
+
+ m_pBox[1] = new C_Box((l_BaseName + "/box_med.obj").c_str(),
+ m_uiWood2Tex, l_Mat, 4, 2, m_pTiles);
+ if (!m_pBox[1]->Initialized()) return false;
+
+ m_pBox[2] = new C_Box((l_BaseName + "/box_large.obj").c_str(),
+ m_uiWood2Tex, l_Mat, 4, 4, m_pTiles);
+ if (!m_pBox[2]->Initialized()) return false;
+
+
+ return true;
+}
+
+void C_MatchBloxEngine::DeleteModels()
+{
+ //delete objects
+ delete m_pEnvMap;
+ delete m_pBlock[0];
+ delete m_pBlock[1];
+ delete m_pBlock[2];
+ delete m_pBlock[3];
+ //delete m_pHand;
+ delete m_pBox[0];
+ delete m_pBox[1];
+ delete m_pBox[2];
+ delete m_pTiles[0];
+ delete m_pTiles[1];
+ delete m_pTiles[2];
+ delete m_pTiles[3];
+ delete m_pTiles[4];
+
+ //delete textures
+ glDeleteTextures(1, &m_uiWood1Tex);
+ glDeleteTextures(1, &m_uiWood2Tex);
+ glDeleteTextures(1, &m_uiWood3Tex);
+}
+
+void C_MatchBloxEngine::LoadTexture(const char* f_BmpName, GLuint &f_uiTexHandle)
+{
+ BitmapStruct l_Bmp;
+
+ l_Bmp = BitmapLoad((char*)f_BmpName);
+ f_uiTexHandle = (GLuint)l_Bmp.m_iImageId;
+
+ glBindTexture(GL_TEXTURE_2D, f_uiTexHandle);
+
+ //set the texture paramaters
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+}
+
diff --git a/matchblox/C_MatchBloxEngine.h b/matchblox/C_MatchBloxEngine.h
new file mode 100644
index 0000000..97aa892
--- /dev/null
+++ b/matchblox/C_MatchBloxEngine.h
@@ -0,0 +1,87 @@
+#ifndef C_MATCHBLOXENGINE_HEADER_FILE
+
+#define C_MATCHBLOXENGINE_HEADER_FILE
+
+#include "MessageQueue.h"
+
+class C_3DObject;
+class C_Block;
+class C_Hand;
+class C_Log;
+class C_Environment;
+class C_Box;
+
+typedef enum GameResult
+{
+ GR_FINISHED,
+ GR_BUSY,
+ GR_ERROR
+} GameResult;
+
+enum EngineState
+{
+ ES_INITIALISED,
+ ES_ERROR,
+ ES_GET_READY, //game initialised, waiting for start signal from player
+ ES_PLAYING_GRAB_BLOCK, //no block in hand -> grab floating block
+ ES_PLAYING_PUT_BLOCK, //block in hand -> put block in box
+ ES_PAUSED, //pause...
+ ES_FINISHED //finished -> show score and goto init
+};
+
+enum BlockType
+{
+ BT_SQUARE = 0,
+ BT_CIRCLE = 1,
+ BT_TRIANGLE = 2,
+ BT_CROSS = 3
+};
+
+enum BoxSize
+{
+ BS_SMALL = 0,
+ BS_MED = 1,
+ BS_LARGE = 2
+};
+
+
+class C_MatchBloxEngine
+{
+public:
+ C_MatchBloxEngine(const char *f_strModelPath,
+ const char *f_strLogFile);
+ ~C_MatchBloxEngine();
+
+ GameResult GameStep(msgQueue &f_Queue);
+ void Render(unsigned int f_uiElapsedTime);
+
+ bool NewGame(int f_iUserID, int f_iGameId, BoxSize f_BS);
+ bool StartGame();
+ bool Pause();
+ bool Resume();
+ bool Abort();
+
+private:
+ C_Environment *m_pEnvMap;
+ C_Block *m_pBlock[4];
+ C_Hand *m_pHand;
+ C_3DObject *m_pTiles[5];
+ C_Box *m_pBox[3];
+ C_Log *m_pLog;
+
+ GLuint m_uiWood1Tex,
+ m_uiWood2Tex,
+ m_uiWood3Tex;
+
+ EngineState m_State, m_SavedState;
+ BoxSize m_CurrentBox;
+
+ void Render_Basics(unsigned int f_uiElapsedTime);
+
+ bool LoadModels(const char* f_strModelDir);
+ void DeleteModels();
+ void LoadTexture(const char* f_BmpName, GLuint &f_uiTexHandle);
+};
+
+#endif //C_MATCHBLOXENGINE_HEADER_FILE
+
diff --git a/matchblox/ChangeLog b/matchblox/ChangeLog
deleted file mode 100644
index c9b8f0e..0000000
--- a/matchblox/ChangeLog
+++ /dev/null
@@ -1,18 +0,0 @@
-2007-12-28 Johannes Schmid,,, <jhs@idefix>
-
- reviewed by: <delete if not using a buddy>
-
- * project.anjuta:
-
-2007-12-23 Johannes Schmid,,, <jhs@idefix>
-
- reviewed by: <delete if not using a buddy>
-
- * src/Makefile.am.tpl:
-
-2007-12-23 Johannes Schmid,,, <jhs@idefix>
-
- reviewed by: <delete if not using a buddy>
-
- * src/Makefile.am.tpl:
-
diff --git a/matchblox/Makefile b/matchblox/Makefile
new file mode 100644
index 0000000..0222105
--- /dev/null
+++ b/matchblox/Makefile
@@ -0,0 +1,43 @@
+CFLAGS=-Icommon -Imenu -Iengine -O2
+CXXFLAGS=$(CFLAGS)
+LDFLAGS=-lglut
+CXX=g++
+CC=gcc
+
+
+all: matchblox_menu matchblox_engine
+ $(CXX) $(LDFLAGS) main.o bitmap.o button.o font.o menu.o C_3DObject.o C_Hand.o C_Block.o C_Log.o C_Environment.o C_Box.o C_MatchBloxEngine.o -o MatchBlox
+
+
+matchblox_common:
+ $(CC) $(CFLAGS) -o message_queue -c common/message_queue.c
+ $(CC) $(CFLAGS) -o bitmap.o -c common/bitmap.c
+ $(CC) $(CFLAGS) -o font.o -c common/font.c
+
+matchblox_menu: matchblox_common
+ $(CC) $(CFLAGS) -o button.o -c menu/button.c
+ $(CC) $(CFLAGS) -o menu.o -c menu/menu.c
+
+matchblox_engine: matchblox_common
+ $(CXX) $(CXXFLAGS) -o C_3DObject.o -c engine/C_3DObject.cpp
+ $(CXX) $(CXXFLAGS) -o C_Hand.o -c engine/C_Hand.cpp
+ $(CXX) $(CXXFLAGS) -o C_Block.o -c engine/C_Block.cpp
+ $(CXX) $(CXXFLAGS) -o C_Log.o -c engine/C_Log.cpp
+ $(CXX) $(CXXFLAGS) -o C_Environment.o -c engine/C_Environment.cpp
+ $(CXX) $(CXXFLAGS) -o C_Box.o -c engine/C_Box.cpp
+ $(CXX) $(CXXFLAGS) -o C_MatchBloxEngine.o -c engine/C_MatchBloxEngine.cpp
+ $(CXX) $(CXXFLAGS) -o main.o -c main.cpp
+
+#automatically generate targets with their dependencies
+%.d: %.cpp
+ @set -e; rm -f $@; \
+ $(CC) -M $(CFLAGS) $< > $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+#include the automatically generated targets
+include $(sources:.cpp=.d)
+
+clean:
+ -rm MatchBlox *.o *.d
+
diff --git a/matchblox/Makefile.am b/matchblox/Makefile.am
deleted file mode 100644
index c473cf2..0000000
--- a/matchblox/Makefile.am
+++ /dev/null
@@ -1,32 +0,0 @@
-## Process this file with automake to produce Makefile.in
-## Created by Anjuta
-
-SUBDIRS = src
-
-matchbloxdocdir = ${prefix}/doc/matchblox
-matchbloxdoc_DATA = \
- README\
- COPYING\
- AUTHORS\
- ChangeLog\
- INSTALL\
- NEWS
-
-EXTRA_DIST = $(matchbloxdoc_DATA)
-
-bin_PROGRAMS = \
- matchblox
-
-matchblox_SOURCES = \
- src/main.c \
- src/renderer_opengl.c \
- src/renderer_opengl.h
-
-# Copy all the spec files. Of cource, only one is actually used.
-dist-hook:
- for specfile in *.spec; do \
- if test -f $$specfile; then \
- cp -p $$specfile $(distdir); \
- fi \
- done
-
diff --git a/matchblox/NEWS b/matchblox/NEWS
deleted file mode 100644
index e69de29..0000000
--- a/matchblox/NEWS
+++ /dev/null
diff --git a/matchblox/README b/matchblox/README
deleted file mode 100644
index e69de29..0000000
--- a/matchblox/README
+++ /dev/null
diff --git a/matchblox/TODO.tasks b/matchblox/TODO.tasks
deleted file mode 100644
index d1fa282..0000000
--- a/matchblox/TODO.tasks
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0"?>
-<gtodo>
- <category title="Personal" place="0"/>
- <category title="Business" place="1"/>
- <category title="Unfiled" place="2"/>
-</gtodo>
diff --git a/matchblox/autogen.sh b/matchblox/autogen.sh
deleted file mode 100755
index 9ab346a..0000000
--- a/matchblox/autogen.sh
+++ /dev/null
@@ -1,159 +0,0 @@
-#!/bin/sh
-# Run this to generate all the initial makefiles, etc.
-
-srcdir=`dirname $0`
-test -z "$srcdir" && srcdir=.
-
-DIE=0
-
-if [ -n "$GNOME2_DIR" ]; then
- ACLOCAL_FLAGS="-I $GNOME2_DIR/share/aclocal $ACLOCAL_FLAGS"
- LD_LIBRARY_PATH="$GNOME2_DIR/lib:$LD_LIBRARY_PATH"
- PATH="$GNOME2_DIR/bin:$PATH"
- export PATH
- export LD_LIBRARY_PATH
-fi
-
-(test -f $srcdir/configure.ac) || {
- echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
- echo " top-level package directory"
- exit 1
-}
-
-(autoconf --version) < /dev/null > /dev/null 2>&1 || {
- echo
- echo "**Error**: You must have \`autoconf' installed."
- echo "Download the appropriate package for your distribution,"
- echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
- DIE=1
-}
-
-(grep "^IT_PROG_INTLTOOL" $srcdir/configure.ac >/dev/null) && {
- (intltoolize --version) < /dev/null > /dev/null 2>&1 || {
- echo
- echo "**Error**: You must have \`intltool' installed."
- echo "You can get it from:"
- echo " ftp://ftp.gnome.org/pub/GNOME/"
- DIE=1
- }
-}
-
-(grep "^AM_PROG_XML_I18N_TOOLS" $srcdir/configure.ac >/dev/null) && {
- (xml-i18n-toolize --version) < /dev/null > /dev/null 2>&1 || {
- echo
- echo "**Error**: You must have \`xml-i18n-toolize' installed."
- echo "You can get it from:"
- echo " ftp://ftp.gnome.org/pub/GNOME/"
- DIE=1
- }
-}
-
-(grep "^AM_PROG_LIBTOOL" $srcdir/configure.ac >/dev/null) && {
- (libtool --version) < /dev/null > /dev/null 2>&1 || {
- echo
- echo "**Error**: You must have \`libtool' installed."
- echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
- DIE=1
- }
-}
-
-(grep "^AM_GLIB_GNU_GETTEXT" $srcdir/configure.ac >/dev/null) && {
- (grep "sed.*POTFILES" $srcdir/configure.ac) > /dev/null || \
- (glib-gettextize --version) < /dev/null > /dev/null 2>&1 || {
- echo
- echo "**Error**: You must have \`glib' installed."
- echo "You can get it from: ftp://ftp.gtk.org/pub/gtk"
- DIE=1
- }
-}
-
-(automake --version) < /dev/null > /dev/null 2>&1 || {
- echo
- echo "**Error**: You must have \`automake' installed."
- echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
- DIE=1
- NO_AUTOMAKE=yes
-}
-
-
-# if no automake, don't bother testing for aclocal
-test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
- echo
- echo "**Error**: Missing \`aclocal'. The version of \`automake'"
- echo "installed doesn't appear recent enough."
- echo "You can get automake from ftp://ftp.gnu.org/pub/gnu/"
- DIE=1
-}
-
-if test "$DIE" -eq 1; then
- exit 1
-fi
-
-if test -z "$*"; then
- echo "**Warning**: I am going to run \`configure' with no arguments."
- echo "If you wish to pass any to it, please specify them on the"
- echo \`$0\'" command line."
- echo
-fi
-
-case $CC in
-xlc )
- am_opt=--include-deps;;
-esac
-
-for coin in `find $srcdir -path $srcdir/CVS -prune -o -name configure.ac -print`
-do
- dr=`dirname $coin`
- if test -f $dr/NO-AUTO-GEN; then
- echo skipping $dr -- flagged as no auto-gen
- else
- echo processing $dr
- ( cd $dr
-
- aclocalinclude="$ACLOCAL_FLAGS"
-
- if grep "^AM_GLIB_GNU_GETTEXT" configure.ac >/dev/null; then
- echo "Creating $dr/aclocal.m4 ..."
- test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
- echo "Running glib-gettextize... Ignore non-fatal messages."
- echo "no" | glib-gettextize --force --copy
- echo "Making $dr/aclocal.m4 writable ..."
- test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
- fi
- if grep "^IT_PROG_INTLTOOL" configure.ac >/dev/null; then
- echo "Running intltoolize..."
- intltoolize --copy --force --automake
- fi
- if grep "^AM_PROG_XML_I18N_TOOLS" configure.ac >/dev/null; then
- echo "Running xml-i18n-toolize..."
- xml-i18n-toolize --copy --force --automake
- fi
- if grep "^AM_PROG_LIBTOOL" configure.ac >/dev/null; then
- if test -z "$NO_LIBTOOLIZE" ; then
- echo "Running libtoolize..."
- libtoolize --force --copy
- fi
- fi
- echo "Running aclocal $aclocalinclude ..."
- aclocal $aclocalinclude
- if grep "^AM_CONFIG_HEADER" configure.ac >/dev/null; then
- echo "Running autoheader..."
- autoheader
- fi
- echo "Running automake --gnu $am_opt ..."
- automake --add-missing --gnu $am_opt
- echo "Running autoconf ..."
- autoconf
- )
- fi
-done
-
-conf_flags="--enable-maintainer-mode"
-
-if test x$NOCONFIGURE = x; then
- echo Running $srcdir/configure $conf_flags "$@" ...
- $srcdir/configure $conf_flags "$@" \
- && echo Now type \`make\' to compile. || exit 1
-else
- echo Skipping configure process.
-fi
diff --git a/matchblox/bitmap.cpp b/matchblox/bitmap.cpp
new file mode 100644
index 0000000..243952a
--- /dev/null
+++ b/matchblox/bitmap.cpp
@@ -0,0 +1,98 @@
+#ifdef G_OS_WIN32
+ #define WIN32_LEAN_AND_MEAN 1
+ #include <windows.h>
+ #define GL_BGR 0x80E0
+ #define GL_BGRA 0x80E1
+#endif
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "bitmap.h"
+
+#define BITMAP_FILESIZE 0x02
+#define BITMAP_OFFSET 0x0a
+#define BITMAP_HEADERSIZE 0x0e
+#define BITMAP_WIDTH 0x12
+#define BITMAP_HEIGHT 0x16
+#define BITMAP_DEPTH 0x1c
+#define BITMAP_IMAGE_SIZE 0x22
+
+
+struct BitmapStruct BitmapLoad(char *filename)
+{
+ struct BitmapStruct l_sImage;
+ GLuint texture;
+ FILE *bitmap;
+
+ // try to open the file
+ bitmap = fopen(filename, "r");
+
+ // does the bitmap exist?
+ if (bitmap > 0)
+ {
+ unsigned int dataoffset, filesize, imagesize;
+ short depth;
+ GLsizei width, height;
+ unsigned char *imagedata;
+
+ fseek(bitmap, BITMAP_FILESIZE, SEEK_SET);
+ fread(&filesize, 4, 1, bitmap);
+ fseek(bitmap, BITMAP_OFFSET, SEEK_SET);
+ fread(&dataoffset, 4, 1, bitmap);
+ fseek(bitmap, BITMAP_WIDTH, SEEK_SET);
+ fread(&width, 4, 1, bitmap);
+ fread(&height, 4, 1, bitmap);
+ fseek(bitmap, BITMAP_DEPTH, SEEK_SET);
+ fread(&depth, 2, 1, bitmap);
+ fseek(bitmap, BITMAP_IMAGE_SIZE, SEEK_SET);
+ fread(&imagesize, 4, 1, bitmap);
+
+ imagedata = (unsigned char *)malloc((size_t)imagesize);
+
+ fseek(bitmap, dataoffset, SEEK_SET);
+ fread(imagedata, (size_t)imagesize, 1, bitmap);
+
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ if (depth == 24) // 24 bits
+ {
+ gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, width, height, GL_BGR, GL_UNSIGNED_BYTE, imagedata);
+ }
+ else // depth == 32 bits
+ {
+ gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, width, height, GL_BGRA, GL_UNSIGNED_BYTE, imagedata);;
+ }
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ l_sImage.m_iImageId = texture;
+ l_sImage.m_iWidth = width;
+ l_sImage.m_iHeight = height;
+
+ free(imagedata);
+ fclose(bitmap);
+
+ return l_sImage;
+ }
+ else
+ {
+ // couldn't find bitmap
+ exit(0);
+ }
+}
+
+
+
+void BitmapConvertWidth(struct BitmapStruct *f_sImage, double f_dHeight)
+{
+ double l_dRatio;
+
+ l_dRatio = (double)f_sImage->m_iHeight / f_dHeight;
+ f_sImage->m_iWidth = (int)(f_sImage->m_iWidth / l_dRatio);
+
+} // ConvertButton
diff --git a/matchblox/bitmap.h b/matchblox/bitmap.h
new file mode 100644
index 0000000..5aa9be6
--- /dev/null
+++ b/matchblox/bitmap.h
@@ -0,0 +1,24 @@
+#ifndef _CBITMAP_H
+#define _CBITMAP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct BitmapStruct {
+ int m_iImageId;
+ int m_iWidth;
+ int m_iHeight;
+};
+
+struct BitmapStruct BitmapLoad(char *filename);
+void BitmapRender(int f_iXPos, int f_iYPos, int f_iWidth, int f_iHeight, int f_iImageId);
+void BitmapConvertWidth(struct BitmapStruct *f_sImage, double f_dHeight);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/matchblox/common/bitmap.c b/matchblox/common/bitmap.c
new file mode 100644
index 0000000..2d69bc9
--- /dev/null
+++ b/matchblox/common/bitmap.c
@@ -0,0 +1,114 @@
+#ifdef G_OS_WIN32
+ #define WIN32_LEAN_AND_MEAN 1
+ #include <windows.h>
+ #define GL_BGR 0x80E0
+ #define GL_BGRA 0x80E1
+ #define GL_CLAMP_TO_EDGE 0x812F
+#endif
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "bitmap.h"
+
+#define BITMAP_FILESIZE 0x02
+#define BITMAP_OFFSET 0x0a
+#define BITMAP_HEADERSIZE 0x0e
+#define BITMAP_WIDTH 0x12
+#define BITMAP_HEIGHT 0x16
+#define BITMAP_DEPTH 0x1c
+#define BITMAP_IMAGE_SIZE 0x22
+
+
+struct BitmapStruct BitmapLoad(char *filename)
+{
+ struct BitmapStruct l_sImage;
+ GLuint texture;
+ FILE *bitmap;
+
+ // try to open the file
+ bitmap = fopen(filename, "r");
+
+ // does the bitmap exist?
+ if (bitmap > 0)
+ {
+ unsigned int dataoffset, filesize, imagesize;
+ short depth;
+ GLsizei width, height;
+ unsigned char *imagedata;
+
+ fseek(bitmap, BITMAP_FILESIZE, SEEK_SET);
+ fread(&filesize, 4, 1, bitmap);
+ fseek(bitmap, BITMAP_OFFSET, SEEK_SET);
+ fread(&dataoffset, 4, 1, bitmap);
+ fseek(bitmap, BITMAP_WIDTH, SEEK_SET);
+ fread(&width, 4, 1, bitmap);
+ fread(&height, 4, 1, bitmap);
+ fseek(bitmap, BITMAP_DEPTH, SEEK_SET);
+ fread(&depth, 2, 1, bitmap);
+ fseek(bitmap, BITMAP_IMAGE_SIZE, SEEK_SET);
+ fread(&imagesize, 4, 1, bitmap);
+
+ imagedata = (unsigned char *)malloc((size_t)imagesize);
+
+ fseek(bitmap, dataoffset, SEEK_SET);
+ fread(imagedata, (size_t)imagesize, 1, bitmap);
+
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ if (depth == 24) // 24 bits
+ {
+ gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, width, height, GL_BGR, GL_UNSIGNED_BYTE, imagedata);
+ }
+ else // depth == 32 bits
+ {
+ gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, width, height, GL_BGRA, GL_UNSIGNED_BYTE, imagedata);;
+ }
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ l_sImage.m_iImageId = texture;
+ l_sImage.m_iWidth = width;
+ l_sImage.m_iHeight = height;
+
+ free(imagedata);
+ fclose(bitmap);
+
+ return l_sImage;
+ }
+ else
+ {
+ // couldn't find bitmap
+ exit(0);
+ }
+}
+
+
+void BitmapRender(int f_iXPos, int f_iYPos, int f_iWidth, int f_iHeight, int f_iImageId)
+{
+ glBindTexture(GL_TEXTURE_2D, f_iImageId);
+
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2i(0, 1); glVertex2i(f_iXPos, f_iYPos);
+ glTexCoord2i(1, 1); glVertex2i(f_iXPos + f_iWidth, f_iYPos);
+ glTexCoord2i(0, 0); glVertex2i(f_iXPos, f_iYPos + f_iHeight);
+ glTexCoord2i(1, 0); glVertex2i(f_iXPos + f_iWidth, f_iYPos + f_iHeight);
+ glEnd();
+
+} // BitmapRender
+
+
+void BitmapConvertWidth(struct BitmapStruct *f_sImage, double f_dHeight)
+{
+ double l_dRatio;
+
+ l_dRatio = (double)f_sImage->m_iHeight / f_dHeight;
+ f_sImage->m_iWidth = (int)(f_sImage->m_iWidth / l_dRatio);
+
+} // ConvertButton
diff --git a/matchblox/common/bitmap.h b/matchblox/common/bitmap.h
new file mode 100644
index 0000000..5aa9be6
--- /dev/null
+++ b/matchblox/common/bitmap.h
@@ -0,0 +1,24 @@
+#ifndef _CBITMAP_H
+#define _CBITMAP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct BitmapStruct {
+ int m_iImageId;
+ int m_iWidth;
+ int m_iHeight;
+};
+
+struct BitmapStruct BitmapLoad(char *filename);
+void BitmapRender(int f_iXPos, int f_iYPos, int f_iWidth, int f_iHeight, int f_iImageId);
+void BitmapConvertWidth(struct BitmapStruct *f_sImage, double f_dHeight);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/matchblox/common/font.c b/matchblox/common/font.c
new file mode 100644
index 0000000..0332174
--- /dev/null
+++ b/matchblox/common/font.c
@@ -0,0 +1,90 @@
+#ifdef G_OS_WIN32
+ #define WIN32_LEAN_AND_MEAN 1
+ #include <windows.h>
+#else
+ #define FALSE 0
+ #define TRUE !FALSE
+#endif
+
+#include <GL/gl.h>
+#include <string.h>
+
+#include "font.h"
+#include "bitmap.h"
+
+struct BitmapStruct g_sFont;
+
+int g_iWinWidth;
+int g_iWinHeight;
+
+GLuint g_iBase;
+
+
+void FontInit(int f_iWinWidth, int f_iWinHeight)
+{
+ float cx;
+ float cy;
+ int l_iImageId;
+ int i = 0;
+
+ float x = (float)(1.0f/FONT_XCHAR);
+
+ g_iWinWidth = f_iWinWidth;
+ g_iWinHeight = f_iWinHeight;
+
+ g_sFont = BitmapLoad("img/continuum_textured_alpha.bmp");
+ l_iImageId = g_sFont.m_iImageId;
+
+ g_iBase = glGenLists(FONT_COUNT);
+ glBindTexture(GL_TEXTURE_2D, l_iImageId);
+
+ for (i = 0; i < FONT_COUNT; i++)
+ {
+ cx = (float)(i % 16) / 16.0f;
+ cy = (float)(i / 16) / 16.0f;
+
+ glNewList(g_iBase + i, GL_COMPILE);
+
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2f(cx, 1 - cy); glVertex2i(0, 0);
+ glTexCoord2f(cx + x, 1 - cy); glVertex2i(FONT_WIDTH, 0);
+ glTexCoord2f(cx, 1 - cy - x); glVertex2i(0, FONT_HEIGHT);
+ glTexCoord2f(cx + x, 1 - cy - x); glVertex2i(FONT_WIDTH, FONT_HEIGHT);
+ glEnd();
+
+ glTranslated(FONT_SPACING, 0, 0);
+ glEndList();
+ }
+
+} // BuildFont
+
+
+void FontDelete(void)
+{
+ glDeleteLists(g_iBase, FONT_COUNT);
+
+} // FontDelete
+
+
+void glPrint(GLint x, GLint y, char *string, struct ColorStruct f_sColor)
+{
+ glColor3d(f_sColor.m_dRed, f_sColor.m_dGreen, f_sColor.m_dBlue);
+ glBindTexture(GL_TEXTURE_2D, g_sFont.m_iImageId);
+ glDisable(GL_DEPTH_TEST);
+ glMatrixMode(GL_PROJECTION);
+
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(0, g_iWinWidth, g_iWinHeight, 0, 0, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ glTranslated(x, y, 0);
+ glListBase(g_iBase - 32);
+ glCallLists((GLsizei)strlen(string), GL_UNSIGNED_BYTE, string);
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+} // glPrint
diff --git a/matchblox/common/font.h b/matchblox/common/font.h
new file mode 100644
index 0000000..ec84ccb
--- /dev/null
+++ b/matchblox/common/font.h
@@ -0,0 +1,30 @@
+#ifndef _CFONT_H
+#define _CFONT_H
+
+#define FONT_WIDTH 32 // width of a character (in the bitmap source!)
+#define FONT_HEIGHT 32 // height of a character (in the bitmap source!)
+#define FONT_SPACING 20 // spacing between characters when printing
+#define FONT_XCHAR 16 // number of characters aligned on the x-axis in the bitmap source
+#define FONT_COUNT 256 // number of characters in the bitmap source
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ColorStruct {
+ double m_dRed;
+ double m_dGreen;
+ double m_dBlue;
+};
+
+void FontInit(int f_iWinWidth, int f_iWinHeight);
+void FontDelete(GLvoid);
+void glPrint(GLint x, GLint y, char *string, struct ColorStruct f_sColor);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/matchblox/common/message_queue.c b/matchblox/common/message_queue.c
new file mode 100644
index 0000000..ad28b6e
--- /dev/null
+++ b/matchblox/common/message_queue.c
@@ -0,0 +1,101 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ * message_queue.c
+ * Copyright (C) Oliver 2008 <o.m.schinagl@student.tue.nl>
+ *
+ * main.c 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * main.c 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef G_OS_WIN32
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "message_queue.h"
+
+
+#define MAX_MESSAGES MESSAGE_WINDOW_SIZE
+
+
+struct messageq_s messageq[MAX_MESSAGES];
+static int messageq_index, messageq_serial;
+static int messageq_last_free;
+
+
+void messageq_init(void)
+{
+ int i;
+
+ messageq_index = 0;
+ messageq_serial = 0;
+ messageq_last_free = 0;
+ for( i = 0; i < MAX_MESSAGES; i++) {
+ messageq[i].sender = 0;
+ messageq[i].recipient = 0;
+ messageq[i].payload = NULL;
+ messageq[i].payload_size = 0;
+ }
+}
+
+
+static void msgcpy(struct messageq_s *dest, const struct messageq_s *src)
+{
+ dest->sender = src->sender;
+ dest->recipient = src->recipient;
+ dest->payload = (void *)malloc(src->payload_size);
+ memcpy(dest->payload, src->payload, src->payload_size);
+ dest->payload_size = src->payload_size;
+}
+
+static void msgfree(int index) {
+ messageq[index].sender = 0;
+ messageq[index].recipient = 0;
+ free(messageq[index].payload);
+ messageq[index].payload_size = 0;
+}
+
+
+struct messageq_s *messageq_get(int recipient)
+{
+ int i;
+
+ i = messageq_index;
+ while (messageq[i].recipient != recipient && i != (messageq_index -1)) {
+ i = (i < MAX_MESSAGES -1) ? i +1 : 0;
+ }
+
+ /*
+ * We found the message for our recipient. We'll now set the recipient field to 0 since the recipient
+ * should know the message was for him, he asked for it. This is needed to prefent the above loop
+ * to find the same message again, since the message will stay alive in the system until its expired.
+ */
+ messageq[i].recipient = MESSAGE_NONE;
+
+ return &messageq[i];
+}
+
+
+void messageq_send(struct messageq_s *message)
+{
+ /* Before sending the message, we clean out old cruft. We do this here
+ * since we will be overwriting the contens of the message here anyway.
+ */
+ msgfree(messageq_index);
+ msgcpy(&messageq[messageq_index], message);
+ messageq_index = ++messageq_serial %MAX_MESSAGES;
+}
diff --git a/matchblox/common/message_queue.h b/matchblox/common/message_queue.h
new file mode 100644
index 0000000..9fd1241
--- /dev/null
+++ b/matchblox/common/message_queue.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
+#ifndef _CMESSAGE_QUEUE_H
+#define _CMESSAGE_QUEUE_H
+
+
+#define MESSAGE_NONE 0x000000
+#define MESSAGE_MENU 0x001000
+#define MESSAGE_RENDERER 0x002000
+
+#define MESSAGE_WINDOW_SIZE 16
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct messageq_s
+{
+ int recipient;
+ int sender;
+ void *payload;
+ size_t payload_size;
+};
+
+
+void messageq_init(void);
+
+void messageq_send(struct messageq_s *message);
+
+struct messageq_s *messageq_get(int recipient);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/matchblox/configure.ac b/matchblox/configure.ac
deleted file mode 100644
index fe2bee6..0000000
--- a/matchblox/configure.ac
+++ /dev/null
@@ -1,29 +0,0 @@
-dnl Process this file with autoconf to produce a configure script.
-dnl Created by Anjuta application wizard.
-
-AC_INIT(matchblox, 0.1)
-
-AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
-AM_CONFIG_HEADER(config.h)
-AM_MAINTAINER_MODE
-
-AC_ISC_POSIX
-AC_PROG_CC
-AM_PROG_CC_STDC
-AC_HEADER_STDC
-
-
-
-
-
-
-
-
-
-
-
-AC_OUTPUT([
-Makefile
-src/Makefile
-
-])
diff --git a/matchblox/engine/C_3DObject.cpp b/matchblox/engine/C_3DObject.cpp
new file mode 100644
index 0000000..3cb00b1
--- /dev/null
+++ b/matchblox/engine/C_3DObject.cpp
@@ -0,0 +1,336 @@
+#include <GL/glut.h>
+#include <vector>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include "typedefs.h"
+#include "C_3DObject.h"
+
+#include "bitmap.h"
+
+C_3DObject::C_3DObject()
+ : m_Pos(0.0, 0.0, 0.0), m_Rot(0.0, 0.0, 0.0),
+ m_Scale(1.0, 1.0, 1.0),
+ m_bOwnTexture(false),
+ m_bDispListValid(false)
+{
+ std::cout << "C_3DObject:: default constructor\n";
+}
+
+
+C_3DObject::C_3DObject(const char* f_strFileName,
+ char* f_strColorTexName,
+ MatProps_t f_Material)
+ : m_Pos(0.0, 0.0, 0.0), m_Rot(0.0, 0.0, 0.0),
+ m_Scale(1.0, 1.0, 1.0),
+ m_bOwnTexture(false),
+ m_bDispListValid(false),
+ m_Mat(f_Material)
+{
+ BitmapStruct l_bmp;
+
+ //load 3d model
+ m_bDispListValid = CreateObject(f_strFileName);
+
+ //load textures
+ if (m_bDispListValid)
+ {
+ if (f_strColorTexName != NULL)
+ {
+ std::cout << "Loading " << f_strColorTexName << std::endl;
+ l_bmp = BitmapLoad(f_strColorTexName);
+ m_uiColorTex = (GLuint)l_bmp.m_iImageId;
+ m_bOwnTexture = true;
+ }
+ }
+}
+
+C_3DObject::C_3DObject(const char* f_strFileName,
+ GLuint f_uiTexture,
+ MatProps_t f_Material)
+ : m_Pos(0.0, 0.0, 0.0), m_Rot(0.0, 0.0, 0.0),
+ m_Scale(1.0, 1.0, 1.0),
+ m_bOwnTexture(false),
+ m_bDispListValid(false),
+ m_uiColorTex(f_uiTexture),
+ m_Mat(f_Material)
+{
+ //load 3d model
+ m_bDispListValid = CreateObject(f_strFileName);
+
+}
+
+C_3DObject::~C_3DObject()
+{
+ if (glIsList(m_uiListIndex))
+ glDeleteLists(m_uiListIndex, 1);
+
+ if (glIsTexture(m_uiColorTex) && m_bOwnTexture)
+ glDeleteTextures(1, &m_uiColorTex);
+}
+
+void C_3DObject::TransRotateScale()
+{
+ glScaled(m_Scale.x, m_Scale.y, m_Scale.z);
+ glTranslated(m_Pos.x, m_Pos.y, m_Pos.z);
+ glRotated(m_Rot.z, 0.0, 0.0, 1.0);
+ glRotated(m_Rot.x, 1.0, 0.0, 0.0);
+ glRotated(m_Rot.y, 0.0, 1.0, 0.0);
+}
+
+void C_3DObject::Render()
+{
+ //apply OpenGL settings for rendering this Object
+ glPushAttrib(GL_TEXTURE_BIT);
+ glEnable(GL_TEXTURE_2D);
+ //modulate the texture color with the computed material
+ //colors
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glBindTexture(GL_TEXTURE_2D, m_uiColorTex);
+
+ //set material properties
+ glMaterialfv(GL_FRONT, GL_AMBIENT, m_Mat.m_fAmb);
+ glMaterialfv(GL_FRONT, GL_DIFFUSE, m_Mat.m_fDif);
+ glMaterialfv(GL_FRONT, GL_SPECULAR, m_Mat.m_fSpec);
+ glMaterialfv(GL_FRONT, GL_EMISSION, m_Mat.m_fEmi);
+ glMaterialf(GL_FRONT, GL_SHININESS, m_Mat.m_fShin);
+
+/*
+ //scale translate and rotate
+ glPushMatrix();
+
+ glScaled(m_Scale.x, m_Scale.y, m_Scale.z);
+ glTranslated(m_Pos.x, m_Pos.y, m_Pos.z);
+ glRotated(m_Rot.z, 0.0, 0.0, 1.0);
+ glRotated(m_Rot.x, 1.0, 0.0, 0.0);
+ glRotated(m_Rot.y, 0.0, 1.0, 0.0);
+*/
+
+ //render by calling the display list
+ if(m_bDispListValid)
+ {
+ glCallList(m_uiListIndex);
+ }
+ else
+ {
+ //or render a LARGE cube when we failed to load the
+ //geometry
+ glutSolidCube(10.0);
+ }
+
+// glPopMatrix();
+
+ glPopAttrib();
+}
+
+
+
+bool C_3DObject::CreateObject(const char *f_pFilePath)
+{
+ Geometry_t l_Geom;
+ bool l_bParseOk;
+ Vect3D_t l_DummyVect;
+
+ //the triangle indices are 1-based so we insert dummy Vect3D_t
+ //to fill the 0 positions in the vertex, normals and texcoords
+ //vector containers.
+ l_Geom.m_verts.push_back(l_DummyVect);
+ l_Geom.m_norms.push_back(l_DummyVect);
+ l_Geom.m_texs.push_back(l_DummyVect);
+
+ l_bParseOk = LoadGeometryData(f_pFilePath, l_Geom);
+
+ //output statistics
+ std::cout << "C_3DObject: file " << f_pFilePath
+ << "\nParse: " << (l_bParseOk? "SUCCESS" : "FAILURE")
+ << "\nVertices: " << l_Geom.m_verts.size()-1
+ << "\nNormals: " << l_Geom.m_norms.size()-1
+ << "\nTexCrds: " << l_Geom.m_texs.size()-1
+ << "\nTriangles: " << l_Geom.m_triangles.size()
+ << "\nBoundBox: x(" << m_BBox.m_dLeft << "," << m_BBox.m_dRight << ")"
+ << "\n y(" << m_BBox.m_dBottom << "," << m_BBox.m_dTop << ")"
+ << "\n z(" << m_BBox.m_dFront << "," << m_BBox.m_dBack << ")"
+ << std::endl;
+
+ if(!l_bParseOk)
+ {
+ std::cout << "C_3DObject Error: failed to parse file "
+ << f_pFilePath << std::endl;
+
+ return false;
+ }
+
+ //create display list
+ m_uiListIndex = glGenLists(1);
+ glNewList(m_uiListIndex, GL_COMPILE);
+
+ glBegin(GL_TRIANGLES);
+
+ //iterate through the triangles
+ std::vector<Triangle_t>::iterator it = l_Geom.m_triangles.begin();
+ for(; it != l_Geom.m_triangles.end(); it++)
+ {
+ //vertex1
+ Vect3D_t v = l_Geom.m_verts[it->v1],
+ t = l_Geom.m_texs[it->t1],
+ n = l_Geom.m_norms[it->n1];
+
+ glNormal3d(n.x, n.y, n.z);
+ glTexCoord3d(t.x, t.y, t.z);
+ glVertex3d(v.x, v.y, v.z);
+
+ //vertex2
+ v = l_Geom.m_verts[it->v2],
+ t = l_Geom.m_texs[it->t2],
+ n = l_Geom.m_norms[it->n2];
+
+ glNormal3d(n.x, n.y, n.z);
+ glTexCoord3d(t.x, t.y, t.z);
+ glVertex3d(v.x, v.y, v.z);
+
+ //vertex3
+ v = l_Geom.m_verts[it->v3],
+ t = l_Geom.m_texs[it->t3],
+ n = l_Geom.m_norms[it->n3];
+
+ glNormal3d(n.x, n.y, n.z);
+ glTexCoord3d(t.x, t.y, t.z);
+ glVertex3d(v.x, v.y, v.z);}
+
+ glEnd();
+
+ glEndList();
+
+ return true;
+}
+
+bool C_3DObject::LoadGeometryData(const char *f_pFilePath, Geometry_t &f_Geom)
+{
+ std::ifstream l_infile(f_pFilePath);
+ char l_inbuffer[256];
+ bool l_bParseOk = true;
+ Vect3D_t l_v3;
+ Triangle_t l_tri;
+
+ if (l_infile.fail())
+ {
+ std::cout << "C_3DObject Error: could not open file "
+ << f_pFilePath << std::endl;
+
+ return false;
+ }
+
+
+ //load data
+ while(!l_infile.eof() && l_bParseOk)
+ {
+ //read the next line
+ l_infile.getline(l_inbuffer, 256);
+
+ //check if reading succeeded
+ if (l_infile.eof() || l_infile.fail() || l_infile.bad())
+ {
+ break;
+ }
+
+ //try to parse the first string of the line as one of the keywords:
+ //v -> vertex coordinate
+ //vt -> texture coordinate
+ //vn -> vertex normal
+ //f -> face record
+ switch (l_inbuffer[0])
+ {
+ case 'v' :
+ //posibilities 'v' 'vt' 'vn'
+ switch (l_inbuffer[1])
+ {
+ case ' ':
+ //vertex
+ if (l_bParseOk = ParseVect3D(&l_inbuffer[2], l_v3))
+ {
+ f_Geom.m_verts.push_back(l_v3);
+ //update boundingbox
+ UpdBBox(m_BBox, l_v3);
+ }
+ break;
+
+ case 't':
+ if (l_inbuffer[2] == ' ')
+ {
+ //texture coordinates
+ if (l_bParseOk = ParseVect3D(&l_inbuffer[3], l_v3))
+ {
+ f_Geom.m_texs.push_back(l_v3);
+ }
+ }
+ break;
+
+ case 'n':
+ if (l_inbuffer[2] == ' ')
+ {
+ //normal
+ if (l_bParseOk = ParseVect3D(&l_inbuffer[3], l_v3))
+ {
+ f_Geom.m_norms.push_back(l_v3);
+ }
+ }
+ break;
+ }
+ break;
+
+ case 'f':
+ if (l_inbuffer[1] == ' ')
+ {
+ //face (triangle)
+ if (l_bParseOk = ParseTriangle(&l_inbuffer[2], l_tri))
+ {
+ f_Geom.m_triangles.push_back(l_tri);
+ }
+ }
+ break;
+
+ case 'm' : // 'mtllib'?
+ break;
+
+ case 'u' : // 'usemtl' ?
+ break;
+ }
+ }
+
+ l_infile.close();
+
+ if (!l_bParseOk)
+ {
+ std::cout << "Parse error in: \"" << l_inbuffer << "\"\n";
+ }
+
+ return l_bParseOk;
+}
+
+bool C_3DObject::ParseVect3D(const char *f_pInBuffer, Vect3D_t &f_V3)
+{
+ //format: " x y z "
+ std::stringstream l_inbuffer(f_pInBuffer);
+
+ l_inbuffer >> std::skipws >> f_V3.x >> f_V3.y >> f_V3.z;
+
+ //std::cout << "Read values: " << f_V3.x << ", " << f_V3.y << ", " << f_V3.z << "\n";
+
+ return !l_inbuffer.fail();
+}
+
+bool C_3DObject::ParseTriangle(const char *f_pInBuffer, Triangle_t &f_triangle)
+{
+ //format v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3
+ std::stringstream l_inbuffer(f_pInBuffer);
+
+ char l_slash;
+
+ l_inbuffer >> std::skipws >> f_triangle.v1 >> l_slash >> f_triangle.t1 >> l_slash >> f_triangle.n1;
+ l_inbuffer >> std::skipws >> f_triangle.v2 >> l_slash >> f_triangle.t2 >> l_slash >> f_triangle.n2;
+ l_inbuffer >> std::skipws >> f_triangle.v3 >> l_slash >> f_triangle.t3 >> l_slash >> f_triangle.n3;
+
+ return !l_inbuffer.fail();
+}
+
diff --git a/matchblox/engine/C_3DObject.h b/matchblox/engine/C_3DObject.h
new file mode 100644
index 0000000..4027596
--- /dev/null
+++ b/matchblox/engine/C_3DObject.h
@@ -0,0 +1,66 @@
+#ifndef C_3DOBJECT_HEADER_FILE
+
+#define C_3DOBJECT_HEADER_FILE
+
+#include <fstream>
+#include <vector>
+
+#include "typedefs.h"
+
+class C_3DObject
+{
+public:
+ C_3DObject();
+ C_3DObject(const char* f_strFileName,
+ char* f_strColorTexName,
+ MatProps_t f_Material);
+ C_3DObject(const char* f_strFileName,
+ GLuint f_uiTexturei,
+ MatProps_t f_Material);
+
+ ~C_3DObject();
+
+ inline void SetPos(double f_dX, double f_dY, double f_dZ)
+ { m_Pos.x = f_dX; m_Pos.y = f_dY; m_Pos.z = f_dZ; }
+ inline void SetRot(double f_dX, double f_dY, double f_dZ)
+ { m_Rot.x = f_dX; m_Rot.y = f_dY; m_Rot.z = f_dZ; }
+ inline void SetScale(double f_dX, double f_dY, double f_dZ)
+ { m_Scale.x = f_dX; m_Scale.y = f_dY; m_Scale.z = f_dZ; }
+ inline void SetPos(const Vect3D_t &pos)
+ { m_Pos = pos; }
+ inline void SetRot(const Vect3D_t &rot)
+ { m_Rot = rot; }
+ inline void SetScale(const Vect3D_t &scale)
+ { m_Scale = scale; }
+
+ inline const Vect3D_t& GetPos() { return m_Pos; }
+ inline const Vect3D_t& GetRot() { return m_Rot; }
+ inline const Vect3D_t& GetScale() { return m_Scale; }
+ inline const BoundingBox_t& GetBoundingBox() { return m_BBox; }
+ inline bool Initialized() { return m_bDispListValid; }
+
+ void TransRotateScale(); //applies the scaling, translation and rotation
+ //for this object
+ virtual void Render(); //renders the object using the current projection
+ //and modelview matrices
+
+protected:
+ Vect3D_t m_Pos,
+ m_Rot,
+ m_Scale;
+
+ BoundingBox_t m_BBox; //bounding box of the object
+ GLuint m_uiListIndex; //display list index
+ bool m_bDispListValid;
+ GLuint m_uiColorTex;
+ bool m_bOwnTexture;
+ MatProps_t m_Mat;
+
+ bool CreateObject(const char *f_pFilePath);
+ bool LoadGeometryData(const char *f_pFilePath, Geometry_t &f_Geom);
+ bool ParseVect3D(const char *f_pInbuffer, Vect3D_t &f_V3);
+ bool ParseTriangle(const char *f_pInbuffer, Triangle_t &f_triangle);
+};
+
+#endif //C_3DOBJECT_HEADER_FILE
+
diff --git a/matchblox/engine/C_Block.cpp b/matchblox/engine/C_Block.cpp
new file mode 100644
index 0000000..4c092a2
--- /dev/null
+++ b/matchblox/engine/C_Block.cpp
@@ -0,0 +1,71 @@
+#include <GL/glut.h>
+
+#include <iostream>
+
+#include "C_Block.h"
+
+#define FADE_DURATION 500
+
+/*Durations of animations*/
+unsigned int g_BlockAnimDurations[4] = {0, 500, 500, 500};
+
+C_Block::C_Block(const char* f_strFileName,
+ GLuint f_uiColorTex ,
+ MatProps_t f_Mat)
+: C_3DObject(f_strFileName, f_uiColorTex, f_Mat),
+ m_CurrState(BS_IDLE), m_uiAnimStart(0)
+{
+
+}
+
+C_Block::~C_Block()
+{
+
+}
+
+void C_Block::Render(unsigned int f_iElapsedTime)
+{
+ unsigned int l_uiDeltaTime = f_iElapsedTime - m_uiAnimStart;
+ double l_Scale = 0.0;
+
+
+ //check if the previous animation has ended in between
+ //calls to this Render function.
+ if (l_uiDeltaTime > g_BlockAnimDurations[(int)m_CurrState])
+ {
+ m_CurrState = BS_IDLE;
+ }
+
+ glPushMatrix();
+
+ switch (m_CurrState)
+ {
+ case BS_FADE_IN:
+ l_Scale = (double)l_uiDeltaTime / (double)g_BlockAnimDurations[BS_FADE_IN];
+ //glScaled(l_Scale, l_Scale, l_Scale);
+ SetScale(l_Scale, l_Scale, l_Scale);
+ TransRotateScale();
+ C_3DObject::Render();
+ break;
+
+ case BS_FADE_OUT:
+ l_Scale = 1.0 - ((double)l_uiDeltaTime / (double)g_BlockAnimDurations[BS_FADE_OUT]);
+// glScaled(l_Scale, l_Scale, l_Scale);
+ SetScale(l_Scale, l_Scale, l_Scale);
+ TransRotateScale();
+ C_3DObject::Render();
+ break;
+
+ case BS_COLLIDE:
+ break;
+
+ case BS_IDLE:
+ default:
+ TransRotateScale();
+ C_3DObject::Render();
+ break;
+ }
+
+ glPopMatrix();
+
+}
diff --git a/matchblox/engine/C_Block.h b/matchblox/engine/C_Block.h
new file mode 100644
index 0000000..f0e03b7
--- /dev/null
+++ b/matchblox/engine/C_Block.h
@@ -0,0 +1,33 @@
+#ifndef C_BLOCK_HEADER_FILE
+
+#define C_BLOCK_HEADER_FILE
+
+#include "C_3DObject.h"
+
+typedef enum BlockAnimState
+{
+ BS_IDLE = 0,
+ BS_FADE_IN = 1,
+ BS_FADE_OUT = 2,
+ BS_COLLIDE = 3
+};
+
+
+class C_Block : public C_3DObject
+{
+public:
+ C_Block(const char* f_strFileName,
+ GLuint f_uiColorTex ,
+ MatProps_t f_Mat);
+ ~C_Block();
+
+ void Render(unsigned int f_iElapsedTime);
+ inline void SetState(BlockAnimState f_State, unsigned int f_uiElapsedTime) { m_CurrState = f_State; m_uiAnimStart = f_uiElapsedTime; }
+
+private:
+ BlockAnimState m_CurrState;
+ unsigned int m_uiAnimStart;
+};
+
+#endif //C_BLOCK_HEADER_FILE
+
diff --git a/matchblox/engine/C_Box.cpp b/matchblox/engine/C_Box.cpp
new file mode 100644
index 0000000..9bde3ff
--- /dev/null
+++ b/matchblox/engine/C_Box.cpp
@@ -0,0 +1,111 @@
+#include <GL/glut.h>
+#include <math.h>
+
+#include "C_Box.h"
+#include "typedefs.h"
+
+C_Box::C_Box(const char *f_strFileName,
+ GLuint f_uiTexture,
+ MatProps_t f_Mat,
+ int f_iTilesX, int f_iTilesY,
+ C_3DObject *f_pTiles[5])
+: C_3DObject(f_strFileName, f_uiTexture, f_Mat),
+ m_pTiles(f_pTiles), m_iTilesX(f_iTilesX),
+ m_iTilesY(f_iTilesY)
+{
+ m_iNumTiles = m_iTilesX * m_iTilesY;
+ //create a new tiles layout array
+ m_iTilesLayout = new int[m_iNumTiles];
+
+ //calculate the tile size (this should be the same
+ //for all tile types)
+ BoundingBox_t l_BBox = m_pTiles[0]->GetBoundingBox();
+ m_dTileSize = l_BBox.m_dRight - l_BBox.m_dLeft;
+
+ //calculate the lower left tile position (in xz plane)
+ m_LowLeftTilePos = Vect3D_t(-m_dTileSize * (double)(m_iTilesX-1)/2.0,
+ 0.0,
+ m_dTileSize * (double)(m_iTilesY-1)/2.0);
+}
+
+C_Box::~C_Box()
+{
+ delete [] m_iTilesLayout;
+}
+
+void C_Box::RandomizeTiles()
+{
+ int l_iNumTiles = m_iTilesX * m_iTilesY;
+
+ //first set the layout to all tiles with no hole
+ for (int i=0; i<l_iNumTiles; i++)
+ m_iTilesLayout[i] = 4;
+
+ //add the four hole tiles
+ for (int i=0; i<4; i++)
+ {
+ //generate a random number in the range
+ //0 - (l_iNumTiles-1)
+ int pos = rand() % l_iNumTiles;
+
+ //skip position in which we already inserted a hole
+ //type tile (type 4)
+ while (m_iTilesLayout[pos] != 4)
+ pos = (pos+1) % l_iNumTiles;
+
+ //insert the hole tile in the free spot
+ m_iTilesLayout[pos] = i;
+
+ //set the position for the hole tile relative to the box its position
+ int col = pos % m_iTilesX;
+ int row = pos / m_iTilesX;
+
+ m_pTiles[i]->SetPos(m_LowLeftTilePos.x + (double)col * m_dTileSize,
+ 0.0,
+ m_LowLeftTilePos.z - (double)row * m_dTileSize);
+ }
+}
+
+void C_Box::Render()
+{
+ //
+ glPushMatrix();
+
+ //apply transformation for box
+ TransRotateScale();
+
+ //render the box
+ C_3DObject::Render();
+
+
+ //render the tiles
+ for(int x=0; x<m_iTilesX; x++)
+ for(int y=0; y<m_iTilesY; y++)
+ {
+ int l_iTileIndex = m_iTilesLayout[x + y*m_iTilesX];
+ //check the tile
+ if (l_iTileIndex >= 0 && l_iTileIndex <= 3)
+ {
+ //tile with a hole
+ glPushMatrix();
+ m_pTiles[l_iTileIndex]->TransRotateScale();
+ m_pTiles[l_iTileIndex]->Render();
+ glPopMatrix();
+ }
+ else
+ {
+ //tile without a hole
+ //set the position
+ m_pTiles[4]->SetPos(m_LowLeftTilePos.x + (double)x * m_dTileSize,
+ 0.0,
+ m_LowLeftTilePos.z - (double)y * m_dTileSize);
+ glPushMatrix();
+ m_pTiles[4]->TransRotateScale();
+ m_pTiles[4]->Render();
+ glPopMatrix();
+ }
+ }
+
+ glPopMatrix();
+}
+
diff --git a/matchblox/engine/C_Box.h b/matchblox/engine/C_Box.h
new file mode 100644
index 0000000..ed8c133
--- /dev/null
+++ b/matchblox/engine/C_Box.h
@@ -0,0 +1,35 @@
+#ifndef C_BOX_HEADER_FILE
+
+#define C_BOX_HEADER_FILE
+
+#include <GL/glut.h>
+#include "C_3DObject.h"
+
+class C_Box : public C_3DObject
+{
+public:
+ C_Box(const char *f_strFileName,
+ GLuint f_uiTexture,
+ MatProps_t f_Mat,
+ int f_iTilesX, int f_iTilesY,
+ C_3DObject *f_pTiles[5]);
+
+ ~C_Box();
+
+ void RandomizeTiles();
+ void Render();
+
+private:
+ C_3DObject **m_pTiles; //the tile objects for the top face of the box (holes)
+ int m_iTilesX, //number of tiles in x direction
+ m_iTilesY, //number of tiles in y direction
+ m_iNumTiles; //total number of tiles
+ double m_dTileSize; //the width and height of a tile
+ Vect3D_t m_LowLeftTilePos; //center position of the lower leftmost
+ //tile (relative to the box its position)
+
+ int *m_iTilesLayout; //the indices of the tile objects
+};
+
+#endif //C_BOX_HEADER_FILE
+
diff --git a/matchblox/engine/C_Environment.cpp b/matchblox/engine/C_Environment.cpp
new file mode 100644
index 0000000..0c7cbfd
--- /dev/null
+++ b/matchblox/engine/C_Environment.cpp
@@ -0,0 +1,119 @@
+#include <GL/glut.h>
+#include <string>
+#include <iostream>
+
+#include "bitmap.h"
+#include "C_Environment.h"
+
+#ifndef GL_CLAMP_TO_EDGE
+#define GL_CLAMP_TO_EDGE 0x812F
+#endif //GL_CLAMP_TO_EDGE
+
+using namespace std;
+
+C_Environment::C_Environment(const char *f_strEnvMapBaseName,
+ double f_dDistance)
+ : m_dDist(f_dDistance)
+{
+ string l_strBase = f_strEnvMapBaseName,
+ l_strFilename;
+ const char *l_suffix[] = { "negative_x.bmp",
+ "negative_y.bmp",
+ "negative_z.bmp",
+ "positive_x.bmp",
+ "positive_y.bmp",
+ "positive_z.bmp"
+ };
+
+ BitmapStruct l_bmp;
+
+ //load textures
+ for (int i=0; i<6; i++)
+ {
+ l_strFilename = l_strBase + l_suffix[i];
+ l_bmp = BitmapLoad((char*)l_strFilename.c_str());
+ m_uiFaceTex[i] = (GLuint)l_bmp.m_iImageId;
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ }
+}
+
+C_Environment::~C_Environment()
+{
+ glDeleteTextures(6, m_uiFaceTex);
+}
+
+void C_Environment::Render()
+{
+ double l_Vertices[8][3] =
+ { { -m_dDist, -m_dDist, m_dDist },
+ { m_dDist, -m_dDist, m_dDist },
+ { m_dDist, -m_dDist, -m_dDist },
+ { -m_dDist, -m_dDist, -m_dDist },
+ { -m_dDist, m_dDist, m_dDist },
+ { m_dDist, m_dDist, m_dDist },
+ { m_dDist, m_dDist, -m_dDist },
+ { -m_dDist, m_dDist, -m_dDist } };
+
+
+ //init render settings for rendering of the environment
+ //mapped cube
+
+ glPushAttrib(GL_TEXTURE_BIT | GL_ENABLE_BIT);
+
+ //no lighting
+ glDisable(GL_LIGHTING);
+ //enable texturing
+ glEnable(GL_TEXTURE_2D);
+ glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ //neg x (left)
+ glBindTexture(GL_TEXTURE_2D, m_uiFaceTex[0]);
+ RenderFace(l_Vertices, 3, 0, 4, 7);
+
+ //neg y (down)
+ glBindTexture(GL_TEXTURE_2D, m_uiFaceTex[1]);
+ RenderFace(l_Vertices, 3, 2, 1, 0);
+
+ //nez z (front)
+ glBindTexture(GL_TEXTURE_2D, m_uiFaceTex[2]);
+ RenderFace(l_Vertices, 2, 3, 7, 6);
+
+ //pos x (right)
+ glBindTexture(GL_TEXTURE_2D, m_uiFaceTex[3]);
+ RenderFace(l_Vertices, 1, 2, 6, 5);
+
+ //pos y (top)
+ glBindTexture(GL_TEXTURE_2D, m_uiFaceTex[4]);
+ RenderFace(l_Vertices, 4, 5, 6, 7);
+
+ //pos z (back)
+ glBindTexture(GL_TEXTURE_2D, m_uiFaceTex[5]);
+ RenderFace(l_Vertices, 0, 1, 5, 4);
+
+ glPopAttrib();
+}
+
+void C_Environment::RenderFace(double f_verts[8][3],
+ int f_v00, int f_v10,
+ int f_v11, int f_v01)
+{
+ //render textured quad in counter clockwise order
+ glBegin(GL_QUADS);
+ glTexCoord2i(0,0);
+ glVertex3dv(f_verts[f_v00]);
+
+ glTexCoord2i(1,0);
+ glVertex3dv(f_verts[f_v10]);
+
+ glTexCoord2i(1,1);
+ glVertex3dv(f_verts[f_v11]);
+
+ glTexCoord2i(0,1);
+ glVertex3dv(f_verts[f_v01]);
+ glEnd();
+
+}
diff --git a/matchblox/engine/C_Environment.h b/matchblox/engine/C_Environment.h
new file mode 100644
index 0000000..cfdb816
--- /dev/null
+++ b/matchblox/engine/C_Environment.h
@@ -0,0 +1,32 @@
+#ifndef C_ENVIRONMENT_H
+
+#define C_ENVIRONMENT_H
+
+#include <GL/glut.h>
+
+class C_Environment
+{
+public:
+ //environment map consist of 6 bitmaps with a common
+ //base name with the axis name (_positive_x.bmp,
+ //_negative_y.bmp, ...)
+ //appended, the distance is the distance from the center
+ //to the sides of the cube
+ C_Environment(const char *f_strEnvMapBaseName,
+ double f_dDistance);
+ ~C_Environment();
+
+ void Render();
+ void RenderFace(double f_verts[8][3],
+ int f_v00, int f_v10,
+ int f_v11, int f_v01);
+
+private:
+ double m_dDist;
+
+ //texture handles for the faces of the cube
+ GLuint m_uiFaceTex[6]; //order -x, -y, -z, +x, +y, +z
+};
+
+#endif //C_ENVIRONMENT_H
+
diff --git a/matchblox/engine/C_Hand.cpp b/matchblox/engine/C_Hand.cpp
new file mode 100644
index 0000000..8c4d977
--- /dev/null
+++ b/matchblox/engine/C_Hand.cpp
@@ -0,0 +1,43 @@
+#include <GL/glut.h>
+#include "C_Hand.h"
+
+#define FADE_DURATION 500
+
+//duration of animations in ms
+unsigned int g_HandAnimDurations[3] = {0, 100, 100};
+
+
+C_Hand::C_Hand(const char* f_strFileName, GLuint f_uiTex,
+ MatProps_t f_Mat)
+: C_3DObject(f_strFileName, f_uiTex, f_Mat),
+ m_CurrState(HS_IDLE), m_uiAnimStart(0)
+{
+}
+
+
+void C_Hand::Render(unsigned int f_iElapsedTime)
+{
+ unsigned int l_uiDeltaTime = f_iElapsedTime - m_uiAnimStart;
+
+ if (l_uiDeltaTime > g_HandAnimDurations[(int)m_CurrState])
+ {
+ m_CurrState = HS_IDLE;
+ }
+
+ switch (m_CurrState)
+ {
+ case HS_GRAB:
+ C_3DObject::Render();
+ break;
+
+ case HS_RELEASE:
+ C_3DObject::Render();
+ break;
+
+ case HS_IDLE:
+ default:
+ C_3DObject::Render();
+ break;
+ }
+
+}
diff --git a/matchblox/engine/C_Hand.h b/matchblox/engine/C_Hand.h
new file mode 100644
index 0000000..3ada63d
--- /dev/null
+++ b/matchblox/engine/C_Hand.h
@@ -0,0 +1,33 @@
+#ifndef C_HAND_HEADER_FILE
+
+#define C_HAND_HEADER_FILE
+
+#include "C_3DObject.h"
+#include "typedefs.h"
+
+typedef enum HandAnimState
+{
+ HS_IDLE = 0,
+ HS_GRAB = 1,
+ HS_RELEASE = 2,
+ HS_COLLIDE = 3
+};
+
+
+class C_Hand : public C_3DObject
+{
+public:
+ C_Hand(const char* f_strFileName, GLuint f_uiTex,
+ MatProps_t f_Mat);
+ ~C_Hand();
+
+ void Render(unsigned int f_iElapsedTime);
+ inline void SetState(HandAnimState f_State, unsigned int f_uiElapsedTime) { m_CurrState = f_State; m_uiAnimStart = f_uiElapsedTime; }
+
+private:
+ HandAnimState m_CurrState;
+ unsigned int m_uiAnimStart;
+};
+
+#endif //C_HAND_HEADER_FILE
+
diff --git a/matchblox/engine/C_Log.cpp b/matchblox/engine/C_Log.cpp
new file mode 100644
index 0000000..d9a1154
--- /dev/null
+++ b/matchblox/engine/C_Log.cpp
@@ -0,0 +1,24 @@
+#include "C_Log.h"
+
+C_Log::C_Log(char *f_strFileName)
+{
+}
+
+C_Log::~C_Log()
+{
+}
+
+bool C_Log::LogNewSession(int f_iUserID, int f_iGameID)
+{
+ return true;
+}
+
+bool C_Log::LogSessionTurn(int f_iUserID, int f_iGameID, int f_iBlockNr, int HolePos, unsigned int f_uiTime)
+{
+ return true;
+}
+
+bool C_Log::LogSessionTotals(int f_iUserID, int f_iGameID, unsigned int f_uiTotalTime)
+{
+ return true;
+}
diff --git a/matchblox/engine/C_Log.h b/matchblox/engine/C_Log.h
new file mode 100644
index 0000000..2b598dd
--- /dev/null
+++ b/matchblox/engine/C_Log.h
@@ -0,0 +1,20 @@
+#ifndef C_LOG_HEADER_FILE
+
+#define C_LOG_HEADER_FILE
+
+class C_Log
+{
+public:
+ C_Log(char *f_strFileName);
+ ~C_Log();
+
+ bool LogNewSession(int f_iUserID, int f_iGameID);
+ bool LogSessionTurn(int f_iUserID, int f_iGameID, int f_iBlockNr, int HolePos, unsigned int f_uiTime);
+ bool LogSessionTotals(int f_iUserID, int f_iGameID, unsigned int f_uiTotalTime);
+
+private:
+// FILE *m_pLogFile;
+};
+
+#endif //C_LOG_HEADER_FILE
+
diff --git a/matchblox/engine/C_MatchBloxEngine.cpp b/matchblox/engine/C_MatchBloxEngine.cpp
new file mode 100644
index 0000000..7e17b1b
--- /dev/null
+++ b/matchblox/engine/C_MatchBloxEngine.cpp
@@ -0,0 +1,348 @@
+#include <GL/glut.h>
+
+#include <time.h>
+#include <string>
+#include <iostream>
+
+#include "C_MatchBloxEngine.h"
+
+#include "C_3DObject.h"
+#include "C_Environment.h"
+#include "C_Hand.h"
+#include "C_Block.h"
+#include "C_Box.h"
+#include "C_Log.h"
+#include "bitmap.h"
+
+C_MatchBloxEngine::C_MatchBloxEngine(const char *f_strModelPath,
+ const char *f_strLogFile)
+{
+ //create logger
+
+
+ //Load models
+ if (LoadModels(f_strModelPath))
+ {
+ //set state to initialised;
+ m_State = ES_INITIALISED;
+ }
+ else
+ {
+ m_State = ES_ERROR;
+ }
+
+ //initialise a random seed
+ srand ( time(NULL) );
+
+ //init vars
+ m_CurrentBox = BS_SMALL;
+
+ //debug
+ m_pBox[0]->SetPos(0.0, -5.0, -15.0);
+ m_pBox[0]->SetRot(45.0, 0.0, 0.0);
+ m_pBox[0]->RandomizeTiles();
+
+ m_pBlock[0]->SetPos(-6.0, 1.0, -10.0);
+ m_pBlock[0]->SetRot(90.0, 0.0, 0.0);
+ m_pBlock[1]->SetPos(-2.0, 1.0, -10.0);
+ m_pBlock[1]->SetRot(90.0, 0.0, 0.0);
+ m_pBlock[2]->SetPos(2.0, 1.0, -10.0);
+ m_pBlock[2]->SetRot(90.0, 0.0, 0.0);
+ m_pBlock[3]->SetPos(6.0, 1.0, -10.0);
+ m_pBlock[3]->SetRot(90.0, 0.0, 0.0);
+}
+
+C_MatchBloxEngine::~C_MatchBloxEngine()
+{
+ //destroy logger
+
+ //delete models
+ DeleteModels();
+}
+
+GameResult C_MatchBloxEngine::GameStep(msgQueue &f_Queue)
+{
+ //process message queue
+ return GR_ERROR;
+}
+
+void C_MatchBloxEngine::Render_Basics(unsigned int f_uiElapsedTime)
+{
+ //render the environment
+ m_pEnvMap->Render();
+
+ m_pBox[(intptr_t)m_CurrentBox]->Render();
+ for (int i=0; i<4; i++)
+ m_pBlock[i]->Render(f_uiElapsedTime);
+// m_pHand->Render(f_uiElapsedTime);
+}
+
+void C_MatchBloxEngine::Render(unsigned int f_uiElapsedTime)
+{
+ switch (m_State)
+ {
+ case ES_INITIALISED:
+ Render_Basics(f_uiElapsedTime);
+ break;
+
+ case ES_ERROR:
+ //render a red cube
+ glPushMatrix();
+ glPushAttrib(GL_ENABLE_BIT);
+ glDisable(GL_LIGHTING);
+ glColor3d(1.0, 0.0, 0.0);
+ glTranslated(0.0, 0.0, -5.0);
+ glutSolidCube(5.0);
+ glPopAttrib();
+ glPopMatrix();
+ break;
+
+ case ES_GET_READY:
+ Render_Basics(f_uiElapsedTime);
+ //render some GET READY text
+ break;
+
+ case ES_PLAYING_GRAB_BLOCK:
+ Render_Basics(f_uiElapsedTime);
+ break;
+
+ case ES_PLAYING_PUT_BLOCK:
+ Render_Basics(f_uiElapsedTime);
+ break;
+
+ case ES_PAUSED:
+ Render_Basics(f_uiElapsedTime);
+ //render menu??
+ break;
+
+ case ES_FINISHED:
+ //render results...
+ break;
+ }
+
+ //glPushMatrix();
+
+ //double l_dSeconds = (double)f_uiElapsedTime/1000.0;
+
+ //glRotated(l_dSeconds * 5.0, 0.0, 1.0, 0.0);
+ ////glRotated(l_dSeconds * 10, 0.0, 0.0, 1.0);
+
+ //m_pEnvMap->Render();
+
+ //glPopMatrix();
+
+ //m_pBox[0]->Render();
+
+ //for(int i=0; i<4; i++)
+ //{
+ // glPushMatrix();
+ // m_pBlock[i]->Render(f_uiElapsedTime);
+ // glPopMatrix();
+ //}
+
+}
+
+bool C_MatchBloxEngine::NewGame(int f_iUserID, int f_iGameId, BoxSize f_BS)
+{
+ if(m_State == ES_INITIALISED)
+ {
+ //log new game
+
+ //prepare a fresh box
+ m_CurrentBox = f_BS;
+ m_pBox[(int)m_CurrentBox]->RandomizeTiles();
+
+ //set state to GET READY
+ m_State = ES_GET_READY;
+
+ //init object positions
+ m_pBox[(int)m_CurrentBox]->SetPos(0.0, -6.0, -15.0);
+ return true;
+ }
+
+ return false;
+}
+
+bool C_MatchBloxEngine::StartGame()
+{
+ return false;
+}
+
+bool C_MatchBloxEngine::Pause()
+{
+ //only pause when playing
+ if (m_State == ES_PLAYING_GRAB_BLOCK ||
+ m_State == ES_PLAYING_PUT_BLOCK)
+ {
+ //save current state
+ m_SavedState = m_State;
+
+ //probably do something with a time variable
+
+ //set current state to paused
+ m_State = ES_PAUSED;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool C_MatchBloxEngine::Resume()
+{
+ if (m_State == ES_PAUSED)
+ {
+ //restore previous state
+ m_State = m_SavedState;
+
+ //restore timers
+ //
+
+ return true;
+ }
+ return false;
+}
+
+bool C_MatchBloxEngine::Abort()
+{
+ //abort when not in error or init state
+ if (m_State != ES_ERROR && m_State != ES_INITIALISED)
+ {
+ //set state to initialised
+ m_State = ES_INITIALISED;
+
+ //..
+
+ return true;
+ }
+ return false;
+}
+
+bool C_MatchBloxEngine::LoadModels(const char* f_strModelDir)
+{
+ MatProps_t l_Mat;
+ std::string l_BaseName = f_strModelDir;
+
+ //create the environment mapped cube
+ m_pEnvMap = new C_Environment("envmaps/terrain_", 50.0);
+
+ //load the bitmaps for the textures
+ LoadTexture((l_BaseName + "/wood1.bmp").c_str(), m_uiWood1Tex);
+ LoadTexture((l_BaseName + "/wood2.bmp").c_str(), m_uiWood2Tex);
+ LoadTexture((l_BaseName + "/wood3.bmp").c_str(), m_uiWood3Tex);
+
+ //load the block models
+ //red squares
+ l_Mat.setAmb(1.0, 0.0, 0.0, 1.0);
+ l_Mat.setDif(1.0, 0.0, 0.0, 1.0);
+ m_pBlock[BT_SQUARE] = new C_Block((l_BaseName + "/square.obj").c_str(),
+ m_uiWood1Tex, l_Mat);
+ if (!m_pBlock[BT_SQUARE]->Initialized()) return false;
+
+ //yellow cricles
+ l_Mat.setAmb(0.0, 1.0, 1.0, 1.0);
+ l_Mat.setDif(0.0, 1.0, 1.0, 1.0);
+ m_pBlock[BT_CIRCLE] = new C_Block((l_BaseName + "/circle.obj").c_str(),
+ m_uiWood1Tex, l_Mat);
+ if (!m_pBlock[BT_CIRCLE]->Initialized()) return false;
+
+ //green triangles
+ l_Mat.setAmb(0.0, 1.0, 0.0, 1.0);
+ l_Mat.setDif(0.0, 1.0, 0.0, 1.0);
+ m_pBlock[BT_TRIANGLE] = new C_Block((l_BaseName + "/triangle.obj").c_str(),
+ m_uiWood1Tex, l_Mat);
+ if (!m_pBlock[BT_TRIANGLE]->Initialized()) return false;
+
+ //blue crosses
+ l_Mat.setAmb(0.0, 0.0, 1.0, 1.0);
+ l_Mat.setDif(0.0, 0.0, 1.0, 1.0);
+ m_pBlock[BT_CROSS] = new C_Block((l_BaseName + "/cross.obj").c_str(),
+ m_uiWood1Tex, l_Mat);
+ if (!m_pBlock[BT_CROSS]->Initialized()) return false;
+
+
+ //load the hand???
+
+
+ //Load the box tiles
+ l_Mat.setAmb(1.0, 1.0, 1.0, 1.0);
+ l_Mat.setDif(1.0, 1.0, 1.0, 1.0);
+
+ m_pTiles[BT_SQUARE] = new C_3DObject((l_BaseName + "/tile_square.obj").c_str(),
+ m_uiWood3Tex, l_Mat);
+ if (!m_pTiles[BT_SQUARE]->Initialized()) return false;
+
+ m_pTiles[BT_CIRCLE] = new C_3DObject((l_BaseName + "/tile_circle.obj").c_str(),
+ m_uiWood3Tex, l_Mat);
+ if (!m_pTiles[BT_CIRCLE]->Initialized()) return false;
+
+ m_pTiles[BT_TRIANGLE] = new C_3DObject((l_BaseName + "/tile_triangle.obj").c_str(),
+ m_uiWood3Tex, l_Mat);
+ if (!m_pTiles[BT_TRIANGLE]->Initialized()) return false;
+
+ m_pTiles[BT_CROSS] = new C_3DObject((l_BaseName + "/tile_cross.obj").c_str(),
+ m_uiWood3Tex, l_Mat);
+ if (!m_pTiles[BT_CROSS]->Initialized()) return false;
+
+ m_pTiles[4] = new C_3DObject((l_BaseName + "/tile_no_hole.obj").c_str(),
+ m_uiWood3Tex, l_Mat);
+ if (!m_pTiles[4]->Initialized()) return false;
+
+
+ //Load the box models
+ m_pBox[0] = new C_Box((l_BaseName + "/box_small.obj").c_str(),
+ m_uiWood2Tex, l_Mat, 2, 2, m_pTiles);
+ if (!m_pBox[0]->Initialized()) return false;
+
+ m_pBox[1] = new C_Box((l_BaseName + "/box_med.obj").c_str(),
+ m_uiWood2Tex, l_Mat, 4, 2, m_pTiles);
+ if (!m_pBox[1]->Initialized()) return false;
+
+ m_pBox[2] = new C_Box((l_BaseName + "/box_large.obj").c_str(),
+ m_uiWood2Tex, l_Mat, 4, 4, m_pTiles);
+ if (!m_pBox[2]->Initialized()) return false;
+
+
+ return true;
+}
+
+void C_MatchBloxEngine::DeleteModels()
+{
+ //delete objects
+ delete m_pEnvMap;
+ delete m_pBlock[0];
+ delete m_pBlock[1];
+ delete m_pBlock[2];
+ delete m_pBlock[3];
+ //delete m_pHand;
+ delete m_pBox[0];
+ delete m_pBox[1];
+ delete m_pBox[2];
+ delete m_pTiles[0];
+ delete m_pTiles[1];
+ delete m_pTiles[2];
+ delete m_pTiles[3];
+ delete m_pTiles[4];
+
+ //delete textures
+ glDeleteTextures(1, &m_uiWood1Tex);
+ glDeleteTextures(1, &m_uiWood2Tex);
+ glDeleteTextures(1, &m_uiWood3Tex);
+}
+
+void C_MatchBloxEngine::LoadTexture(const char* f_BmpName, GLuint &f_uiTexHandle)
+{
+ BitmapStruct l_Bmp;
+
+ l_Bmp = BitmapLoad((char*)f_BmpName);
+ f_uiTexHandle = (GLuint)l_Bmp.m_iImageId;
+
+ glBindTexture(GL_TEXTURE_2D, f_uiTexHandle);
+
+ //set the texture paramaters
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+}
+
diff --git a/matchblox/engine/C_MatchBloxEngine.h b/matchblox/engine/C_MatchBloxEngine.h
new file mode 100644
index 0000000..97aa892
--- /dev/null
+++ b/matchblox/engine/C_MatchBloxEngine.h
@@ -0,0 +1,87 @@
+#ifndef C_MATCHBLOXENGINE_HEADER_FILE
+
+#define C_MATCHBLOXENGINE_HEADER_FILE
+
+#include "MessageQueue.h"
+
+class C_3DObject;
+class C_Block;
+class C_Hand;
+class C_Log;
+class C_Environment;
+class C_Box;
+
+typedef enum GameResult
+{
+ GR_FINISHED,
+ GR_BUSY,
+ GR_ERROR
+} GameResult;
+
+enum EngineState
+{
+ ES_INITIALISED,
+ ES_ERROR,
+ ES_GET_READY, //game initialised, waiting for start signal from player
+ ES_PLAYING_GRAB_BLOCK, //no block in hand -> grab floating block
+ ES_PLAYING_PUT_BLOCK, //block in hand -> put block in box
+ ES_PAUSED, //pause...
+ ES_FINISHED //finished -> show score and goto init
+};
+
+enum BlockType
+{
+ BT_SQUARE = 0,
+ BT_CIRCLE = 1,
+ BT_TRIANGLE = 2,
+ BT_CROSS = 3
+};
+
+enum BoxSize
+{
+ BS_SMALL = 0,
+ BS_MED = 1,
+ BS_LARGE = 2
+};
+
+
+class C_MatchBloxEngine
+{
+public:
+ C_MatchBloxEngine(const char *f_strModelPath,
+ const char *f_strLogFile);
+ ~C_MatchBloxEngine();
+
+ GameResult GameStep(msgQueue &f_Queue);
+ void Render(unsigned int f_uiElapsedTime);
+
+ bool NewGame(int f_iUserID, int f_iGameId, BoxSize f_BS);
+ bool StartGame();
+ bool Pause();
+ bool Resume();
+ bool Abort();
+
+private:
+ C_Environment *m_pEnvMap;
+ C_Block *m_pBlock[4];
+ C_Hand *m_pHand;
+ C_3DObject *m_pTiles[5];
+ C_Box *m_pBox[3];
+ C_Log *m_pLog;
+
+ GLuint m_uiWood1Tex,
+ m_uiWood2Tex,
+ m_uiWood3Tex;
+
+ EngineState m_State, m_SavedState;
+ BoxSize m_CurrentBox;
+
+ void Render_Basics(unsigned int f_uiElapsedTime);
+
+ bool LoadModels(const char* f_strModelDir);
+ void DeleteModels();
+ void LoadTexture(const char* f_BmpName, GLuint &f_uiTexHandle);
+};
+
+#endif //C_MATCHBLOXENGINE_HEADER_FILE
+
diff --git a/matchblox/engine/MessageQueue.h b/matchblox/engine/MessageQueue.h
new file mode 100644
index 0000000..47a061e
--- /dev/null
+++ b/matchblox/engine/MessageQueue.h
@@ -0,0 +1,26 @@
+#ifndef MESSAGEQUEUE_HEADER_FILE
+
+#define MESSAGEQUEUE_HEADER_FILE
+
+#include <queue>
+
+typedef enum msgType
+{
+ MOUSE_MOVE,
+ MOUSE_PRESS,
+ KEY_PRESS,
+ SPECIAL_KEY,
+ WII_CURSOR_MOVE,
+ WII_BUTTON_PRESS
+};
+
+typedef struct message
+{
+ msgType m_MessageType;
+ int parm1, parm2, parm3, parm4;
+} msgStruct;
+
+typedef std::queue<msgStruct> msgQueue;
+
+#endif //MESSAGEQUEUE_HEADER_FILE
+
diff --git a/matchblox/engine/typedefs.h b/matchblox/engine/typedefs.h
new file mode 100644
index 0000000..0262c14
--- /dev/null
+++ b/matchblox/engine/typedefs.h
@@ -0,0 +1,128 @@
+#ifndef TYPEDEFS_H
+
+#define TYPEDEFS_H
+
+#include <vector>
+#include <limits>
+
+typedef struct bb
+{
+ bb() {
+ //init a bounding box with the min values set to max double and visa versa
+ m_dLeft = m_dBottom = m_dFront = std::numeric_limits<double>::max();
+ m_dRight = m_dTop = m_dBack = -std::numeric_limits<double>::max();
+ }
+
+ double m_dLeft, //min x
+ m_dBottom, //min y
+ m_dFront, //min z
+ m_dRight, //max x
+ m_dTop, //max y
+ m_dBack; //max z
+
+} BoundingBox_t;
+
+typedef struct vec3d
+{
+ double x, y, z;
+
+ //constructors
+ vec3d()
+ { x=0.0, y=0.0, z=0.0; }
+ vec3d(double fx, double fy, double fz)
+ { x=fx, y=fy, z=fz; }
+ vec3d(const vec3d &clone)
+ { x=clone.x; y=clone.y; z=clone.z; }
+
+ inline vec3d& operator=(const vec3d &rhs)
+ { x=rhs.x; y=rhs.y; z=rhs.z; return *this; }
+ inline vec3d& operator+=(const vec3d &rhs)
+ { x+=rhs.x; y+=rhs.y; z+=rhs.z; return *this; }
+ inline vec3d& operator-=(const vec3d &rhs)
+ { x-=rhs.x; y-=rhs.y; z-=rhs.z; return *this; }
+ inline vec3d& operator*=(const vec3d &rhs)
+ { x*=rhs.x; y*=rhs.y; z*=rhs.z; return *this; }
+ inline vec3d& operator*=(const double &scal)
+ { x*=scal; y*=scal; z*=scal; return *this; }
+
+ inline const vec3d& operator+(const vec3d &rhs)
+ { return vec3d(*this) += rhs; }
+ inline const vec3d& operator-(const vec3d &rhs)
+ { return vec3d(*this) -= rhs; }
+ inline const vec3d& operator*(const vec3d &rhs)
+ { return vec3d(*this) *= rhs; }
+ inline const vec3d& operator*(const double &scal)
+ { return vec3d(*this) *= scal; }
+} Vect3D_t;
+
+
+
+inline void UpdBBox(BoundingBox_t &B, Vect3D_t &V)
+{
+ if (V.x < B.m_dLeft)
+ B.m_dLeft = V.x;
+ else if (V.x > B.m_dRight)
+ B.m_dRight = V.x;
+ if (V.y < B.m_dBottom)
+ B.m_dBottom = V.y;
+ else if (V.y > B.m_dTop)
+ B.m_dTop = V.y;
+ if (V.z < B.m_dFront)
+ B.m_dFront = V.z;
+ else if (V.z > B.m_dBack)
+ B.m_dBack = V.z;
+};
+
+typedef struct triangle
+{
+ int v1, n1, t1,
+ v2, n2, t2,
+ v3, n3, t3;
+} Triangle_t;
+
+typedef struct mat
+{
+ GLfloat m_fAmb[4],
+ m_fDif[4],
+ m_fSpec[4],
+ m_fEmi[4],
+ m_fShin;
+
+ //default constructor
+ mat()
+ {
+ m_fAmb[0] = m_fAmb[1] = m_fAmb[2] = 0.7f; m_fAmb[3] = 1.0f;
+ m_fDif[0] = m_fDif[1] = m_fDif[3] = 0.7f; m_fDif[3] = 1.0f;
+ m_fSpec[0] = m_fSpec[1] = m_fSpec[2] = m_fSpec[3] = 1.0f;
+ m_fEmi[0] = m_fEmi[1] = m_fEmi[2] = 0.0f; m_fEmi[3] = 1.0f;
+ m_fShin = 128.0f;
+ }
+ //for convenience
+ inline void setAmb(float r, float g, float b, float a)
+ { m_fAmb[0] = r; m_fAmb[1] = g; m_fAmb[2] = b; m_fAmb[3] = a; }
+ inline void setDif(float r, float g, float b, float a)
+ { m_fDif[0] = r; m_fDif[1] = g; m_fDif[2] = b; m_fDif[3] = a; }
+ inline void setSpec(float r, float g, float b, float a)
+ { m_fSpec[0] = r; m_fSpec[1] = g; m_fSpec[2] = b; m_fSpec[3] = a; }
+ inline void setEmi(float r, float g, float b, float a)
+ { m_fEmi[0] = r; m_fEmi[1] = g; m_fEmi[2] = b; m_fEmi[3] = a; }
+
+} MatProps_t;
+/*
+typedef struct facegroup
+{
+ MatProps_t m_material;
+ std::vector<Face_t> m_faces;
+} FaceGroup_t;
+*/
+
+typedef struct geom
+{
+ std::vector<Vect3D_t> m_verts,
+ m_norms,
+ m_texs;
+ std::vector<Triangle_t> m_triangles;
+} Geometry_t;
+
+#endif //TYPEDEFS_H
+
diff --git a/matchblox/main.cpp b/matchblox/main.cpp
new file mode 100644
index 0000000..dc4ec64
--- /dev/null
+++ b/matchblox/main.cpp
@@ -0,0 +1,158 @@
+#include <GL/glut.h>
+#include <iostream>
+
+#include "MessageQueue.h"
+#include "C_MatchBloxEngine.h"
+
+#define SCREEN_WIDTH 640
+#define SCREEN_HEIGHT 480
+
+msgQueue g_Queue;
+C_MatchBloxEngine *g_pEngine;
+
+void init_gl(void)
+{
+ GLfloat l_fLightpos[4] = {0.0, 1.0, 1.0, 0.0};
+ glClearColor(0.9, 0.9, 0.9, 1.0);
+ glClearDepth(1000.0);
+ glShadeModel(GL_SMOOTH);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glLightfv(GL_LIGHT0, GL_POSITION, l_fLightpos);
+ glEnable(GL_NORMALIZE);
+
+ glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+} // init_gl
+
+void idle_func(void)
+{
+ //call engine idle func
+
+ glutPostRedisplay();
+}
+
+void render_scene(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ g_pEngine->Render(glutGet(GLUT_ELAPSED_TIME));
+
+ glutSwapBuffers();
+
+} // render_scene
+
+void reshape(int w, int h)
+{
+ //set the new viewport dimension
+ glViewport(0, 0, w, h);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(90.0, ((GLdouble)h)/((GLdouble)w), 0.5, 100.0);
+ glTranslated(0.0, 0.0, -0.5);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+void process_normal_keys(unsigned char key, int x, int y)
+{
+ // escape
+ if (key == 27)
+ {
+ exit(0);
+ }
+ else
+ {
+ if (key == 'n')
+ {
+ g_pEngine->Abort();
+ g_pEngine->NewGame(0, 0, BS_LARGE);
+ }
+ msgStruct l_msg;
+ l_msg.m_MessageType = KEY_PRESS;
+ l_msg.parm1 = key;
+ l_msg.parm2 = x;
+ l_msg.parm3 = y;
+
+ g_Queue.push(l_msg);
+ }
+} // process_normal_keys
+
+
+
+void process_special_keys(int key, int x, int y)
+{
+ switch (key)
+ {
+ // do sumting
+ }
+ msgStruct l_msg;
+ l_msg.m_MessageType = SPECIAL_KEY;
+ l_msg.parm1 = key;
+ l_msg.parm2 = x;
+ l_msg.parm3 = y;
+
+ g_Queue.push(l_msg);
+
+} // process_special_keys
+
+
+
+void process_mouse(int button, int state, int x, int y)
+{
+ msgStruct l_msg;
+ l_msg.m_MessageType = MOUSE_PRESS;
+ l_msg.parm1 = button;
+ l_msg.parm2 = state;
+ l_msg.parm3 = x;
+ l_msg.parm4 = y;
+
+ g_Queue.push(l_msg);
+
+
+} // process_mouse
+
+
+
+void process_passive_mouse(int x, int y)
+{
+ //process_mouse(-1, -1, x, y);
+ msgStruct l_msg;
+ l_msg.m_MessageType = MOUSE_MOVE;
+ l_msg.parm1 = x;
+ l_msg.parm2 = y;
+ l_msg.parm3 = 0;
+ l_msg.parm4 = 0;
+
+ g_Queue.push(l_msg);
+
+} // process_passive_mouse
+
+
+
+int main(int argc, char **argv)
+{
+ glutInit(&argc, argv);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+ glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
+ glutCreateWindow("MatchBloxEngine demo");
+
+ glutReshapeFunc(reshape);
+ glutDisplayFunc(render_scene);
+ glutIdleFunc(idle_func);
+ glutKeyboardFunc(process_normal_keys);
+ glutSpecialFunc(process_special_keys);
+ glutMouseFunc(process_mouse);
+ glutPassiveMotionFunc(process_passive_mouse);
+
+ init_gl();
+ //MenuInit(SCREEN_WIDTH, SCREEN_HEIGHT);
+
+ g_pEngine = new C_MatchBloxEngine("models", "");
+
+ glutMainLoop();
+
+ return 0;
+
+} // main
+
diff --git a/matchblox/matchblox.anjuta b/matchblox/matchblox.anjuta
deleted file mode 100644
index 51ddd65..0000000
--- a/matchblox/matchblox.anjuta
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0"?>
-<anjuta>
- <plugin name="GBF Project Manager"
- url="http://anjuta.org/plugins/"
- mandatory="yes">
- <require group="Anjuta Plugin"
- attribute="Interfaces"
- value="IAnjutaProjectManager"/>
- <require group="Project"
- attribute="Supported-Project-Types"
- value="automake"/>
- </plugin>
- <plugin name="Symbol Browser"
- url="http://anjuta.org/plugins/"
- mandatory="yes">
- <require group="Anjuta Plugin"
- attribute="Interfaces"
- value="IAnjutaSymbolManager"/>
- </plugin>
- <plugin name="Make Build System"
- url="http://anjuta.org/plugins/"
- mandatory="yes">
- <require group="Anjuta Plugin"
- attribute="Interfaces"
- value="IAnjutaBuildable"/>
- <require group="Build"
- attribute="Supported-Build-Types"
- value="make"/>
- </plugin>
- <plugin name="Task Manager"
- url="http://anjuta.org/plugins/"
- mandatory="no">
- <require group="Anjuta Plugin"
- attribute="Interfaces"
- value="IAnjutaTodo"/>
- </plugin>
- <plugin name="Debug Manager"
- url="http://anjuta.org/plugins/"
- mandatory="no">
- <require group="Anjuta Plugin"
- attribute="Interfaces"
- value="IAnjutaDebuggerManager"/>
- </plugin>
-</anjuta>
diff --git a/matchblox/matchblox.vcproj b/matchblox/matchblox.vcproj
new file mode 100644
index 0000000..0f7ecc0
--- /dev/null
+++ b/matchblox/matchblox.vcproj
@@ -0,0 +1,277 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8,00"
+ Name="MatchBloxEngine"
+ ProjectGUID="{76B80F87-6EFD-4439-9D32-86FA7BD83035}"
+ RootNamespace="MatchBloxEngine"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\headtrack_stereo_demo\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;G_OS_WIN32"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="glut32.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="..\..\headtrack_stereo_demo\lib\win32\"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="copy ..\..\headtrack_stereo_demo\lib\win32\glut32.dll &quot;$(OutDir)&quot;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\headtrack_stereo_demo\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="glut32.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="..\..\headtrack_stereo_demo\lib\win32\"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="copy ..\..\headtrack_stereo_demo\lib\win32\glut32.dll &quot;$(OutDir)&quot;"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\bitmap.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\C_3DObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\C_Block.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\C_Box.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\C_Environment.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\C_Hand.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\C_Log.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\C_MatchBloxEngine.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\main.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\bitmap.h"
+ >
+ </File>
+ <File
+ RelativePath=".\C_3DObject.h"
+ >
+ </File>
+ <File
+ RelativePath=".\C_Block.h"
+ >
+ </File>
+ <File
+ RelativePath=".\C_Box.h"
+ >
+ </File>
+ <File
+ RelativePath=".\C_Environment.h"
+ >
+ </File>
+ <File
+ RelativePath=".\C_Hand.h"
+ >
+ </File>
+ <File
+ RelativePath=".\C_Log.h"
+ >
+ </File>
+ <File
+ RelativePath=".\C_MatchBloxEngine.h"
+ >
+ </File>
+ <File
+ RelativePath=".\MessageQueue.h"
+ >
+ </File>
+ <File
+ RelativePath=".\typedefs.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/matchblox/menu/button.c b/matchblox/menu/button.c
new file mode 100644
index 0000000..d452fd0
--- /dev/null
+++ b/matchblox/menu/button.c
@@ -0,0 +1,328 @@
+#ifdef G_OS_WIN32
+ #define WIN32_LEAN_AND_MEAN 1
+ #include <windows.h>
+#else
+ #define FALSE 0
+ #define TRUE !FALSE
+ #define max(a, b) (((a) > (b)) ? (a) : (b))
+
+#endif
+
+#include <string.h>
+
+#include <GL/gl.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "button.h"
+#include "font.h"
+
+
+struct ButtonStruct ButtonCreate(int f_iXPos, int f_iYPos, int f_iWidth, int f_iHeight, char *f_pcTitle, int f_iType, int f_iGroup, int f_iId)
+{
+ struct ButtonStruct l_sButton;
+
+ // copy parameters
+ l_sButton.m_iXPos = f_iXPos;
+ l_sButton.m_iYPos = f_iYPos;
+ l_sButton.m_iType = f_iType;
+ l_sButton.m_iHeight = f_iHeight;
+ l_sButton.m_iWidth = f_iWidth;
+ l_sButton.m_iGroup = f_iGroup;
+ l_sButton.m_iId = f_iId;
+
+ // copy title
+ memset(&l_sButton.m_pcTitle, 0, sizeof(l_sButton.m_pcTitle));
+ memcpy(l_sButton.m_pcTitle, f_pcTitle, strlen(f_pcTitle));
+
+ switch (f_iType)
+ {
+ case BUTTON_CLICK:
+ l_sButton.m_psImgNormal[0] = BitmapLoad("img/button_click_left.bmp");
+ l_sButton.m_psImgNormal[1] = BitmapLoad("img/button_click_center.bmp");
+ l_sButton.m_psImgNormal[2] = BitmapLoad("img/button_click_right.bmp");
+
+ l_sButton.m_psImgHover[0] = BitmapLoad("img/button_click_left_hover.bmp");
+ l_sButton.m_psImgHover[1] = BitmapLoad("img/button_click_center_hover.bmp");
+ l_sButton.m_psImgHover[2] = BitmapLoad("img/button_click_right_hover.bmp");
+
+ BitmapConvertWidth(&l_sButton.m_psImgNormal[0], f_iHeight);
+ BitmapConvertWidth(&l_sButton.m_psImgNormal[1], f_iHeight);
+ BitmapConvertWidth(&l_sButton.m_psImgNormal[2], f_iHeight);
+
+ BitmapConvertWidth(&l_sButton.m_psImgHover[0], f_iHeight);
+ BitmapConvertWidth(&l_sButton.m_psImgHover[1], f_iHeight);
+ BitmapConvertWidth(&l_sButton.m_psImgHover[2], f_iHeight);
+
+ // calculate (center)width of image
+ l_sButton.m_iCenterWidth = max(f_iWidth - l_sButton.m_psImgNormal[0].m_iWidth - l_sButton.m_psImgNormal[2].m_iWidth, 0);
+ l_sButton.m_iWidth = l_sButton.m_iCenterWidth + l_sButton.m_psImgNormal[0].m_iWidth + l_sButton.m_psImgNormal[2].m_iWidth;
+ break;
+
+ case BUTTON_RADIO:
+ l_sButton.m_psImgNormal[0] = BitmapLoad("img/button_radio.bmp");
+ l_sButton.m_psImgHover[0] = BitmapLoad("img/button_radio_hover.bmp");
+ l_sButton.m_psImgPressed[0] = BitmapLoad("img/button_radio_pressed.bmp");
+
+ BitmapConvertWidth(&l_sButton.m_psImgNormal[0], f_iHeight);
+ BitmapConvertWidth(&l_sButton.m_psImgHover[0], f_iHeight);
+ BitmapConvertWidth(&l_sButton.m_psImgPressed[0], f_iHeight);
+
+ l_sButton.m_iCenterWidth = 0;
+ l_sButton.m_iHeight = f_iHeight;
+ l_sButton.m_iWidth = f_iWidth;
+ break;
+
+ default:
+ break;
+ }
+
+ l_sButton.m_bPressed = FALSE;
+ l_sButton.m_bHover = FALSE;
+
+ return l_sButton;
+
+} // ButtonCreate
+
+
+void ButtonClickRender(struct ButtonStruct *f_sButton)
+{
+ char l_pcTitle[BUTTON_MAX_TITLE];
+ struct BitmapStruct *l_sImgButton;
+ int l_iImageIdLeft, l_iImageIdCenter, l_iImageIdRight;
+ int l_iLen, l_iXOffset, l_iYOffset, l_iWidth;
+ struct ColorStruct l_sColor = {0, 0, 0};
+
+ // copy button attributes
+ int l_iCnWdt = f_sButton->m_iCenterWidth;
+ int l_iHeight = f_sButton->m_iHeight;
+ int l_iXPos = f_sButton->m_iXPos;
+ int l_iYPos = f_sButton->m_iYPos;
+
+ if (f_sButton->m_bPressed)
+ {
+ glColor3d(0.8, 0.9, 1);
+ }
+ else
+ {
+ glColor3d(1, 1, 1);
+ }
+
+ // get the right image struct
+ if (f_sButton->m_bHover)
+ {
+ l_sImgButton = f_sButton->m_psImgHover;
+ }
+ else
+ {
+ l_sImgButton = f_sButton->m_psImgNormal;
+ }
+
+ // copy buttom images
+ l_iImageIdLeft = l_sImgButton[0].m_iImageId;
+ l_iImageIdCenter = l_sImgButton[1].m_iImageId;
+ l_iImageIdRight = l_sImgButton[2].m_iImageId;
+
+ // copy button title
+ memcpy(&l_pcTitle, f_sButton->m_pcTitle, strlen(f_sButton->m_pcTitle));
+
+ // render left side of button
+ l_iWidth = l_sImgButton[0].m_iWidth;
+ BitmapRender(l_iXPos,
+ l_iYPos,
+ l_iWidth + 1,
+ l_iHeight,
+ l_iImageIdLeft);
+
+ // render right side of button
+ l_iWidth = l_sImgButton[2].m_iWidth;
+ BitmapRender(l_iXPos + l_iCnWdt + l_iWidth - 1,
+ l_iYPos,
+ l_iWidth,
+ l_iHeight,
+ l_iImageIdRight);
+
+ // render center of button
+ if (l_iCnWdt > 0)
+ {
+ BitmapRender(l_iXPos + l_iWidth - 1,
+ l_iYPos,
+ l_iCnWdt + 1,
+ l_iHeight,
+ l_iImageIdCenter);
+ }
+
+ l_iLen = (int)strlen(f_sButton->m_pcTitle);
+ l_iXOffset = (int)(0.5 * f_sButton->m_iWidth - 0.5 * l_iLen * FONT_SPACING);
+ l_iYOffset = (int)(0.5 * f_sButton->m_iHeight - 0.5 * FONT_HEIGHT);
+
+ glPrint(f_sButton->m_iXPos + l_iXOffset,
+ f_sButton->m_iYPos + l_iYOffset,
+ f_sButton->m_pcTitle,
+ l_sColor);
+
+} // ButtonClickRender
+
+
+void ButtonRadioRender(struct ButtonStruct *f_sButton)
+{
+ struct BitmapStruct *l_sImgButton;
+ int l_iXOffset, l_iYOffset, l_iImageRadioId, l_iImageEnabledId;
+
+ // copy button attributes
+ int l_iWidth = f_sButton->m_iWidth;
+ int l_iHeight = f_sButton->m_iHeight;
+ int l_iXPos = f_sButton->m_iXPos;
+ int l_iYPos = f_sButton->m_iYPos;
+ struct ColorStruct l_sColor = {0.2, 0.4, 0.8};
+
+ // get the right image struct
+ if (f_sButton->m_bHover)
+ {
+ l_sImgButton = f_sButton->m_psImgHover;
+ }
+ else
+ {
+ l_sImgButton = f_sButton->m_psImgNormal;
+ }
+
+ l_iImageRadioId = l_sImgButton[0].m_iImageId;
+ l_iImageEnabledId = f_sButton->m_psImgPressed[0].m_iImageId;
+
+ glColor3d(1, 1, 1);
+
+ // render the radio button
+ BitmapRender(l_iXPos, l_iYPos, l_iWidth, l_iHeight, l_iImageRadioId);
+
+ // render the enable-dot if button is pressed
+ if (f_sButton->m_bPressed)
+ {
+ BitmapRender(l_iXPos, l_iYPos, l_iWidth, l_iHeight, l_iImageEnabledId);
+ }
+
+ l_iXOffset = (int)f_sButton->m_iWidth;
+ l_iYOffset = (int)(0.5 * f_sButton->m_iHeight - 0.5 * FONT_HEIGHT);
+
+ glPrint(f_sButton->m_iXPos + l_iXOffset,
+ f_sButton->m_iYPos + l_iYOffset,
+ f_sButton->m_pcTitle,
+ l_sColor);
+
+} // ButtonRadioRender
+
+
+void ButtonRender(struct ButtonStruct *f_sButton)
+{
+ int l_iType = f_sButton->m_iType;
+
+ switch (l_iType)
+ {
+ case BUTTON_CLICK:
+ ButtonClickRender(f_sButton);
+ break;
+
+ case BUTTON_RADIO:
+ ButtonRadioRender(f_sButton);
+ break;
+
+ default:
+ break;
+ }
+
+} // ButtonRender
+
+
+void ButtonEnter(struct ButtonStruct *f_sButton)
+{
+ f_sButton->m_bHover = TRUE;
+
+} // ButtonHover
+
+
+void ButtonExit(struct ButtonStruct *f_sButton)
+{
+ f_sButton->m_bHover = FALSE;
+
+} // ButtonHover
+
+
+void ButtonClickPress(struct ButtonStruct *f_sButton)
+{
+ if (!f_sButton->m_bPressed) {
+ ButtonEnable(f_sButton);
+ }
+
+} // ButtonClickPress
+
+
+void ButtonRadioPress(struct ButtonStruct *f_sButton)
+{
+ int i = 0;
+
+ if (!f_sButton->m_bPressed)
+ {
+ ButtonEnable(f_sButton);
+ }
+
+} // ButtonClickPress
+
+
+void ButtonPress(struct ButtonStruct *f_sButton)
+{
+ int l_iType = f_sButton->m_iType;
+
+ switch (l_iType)
+ {
+ case BUTTON_CLICK:
+ ButtonClickPress(f_sButton);
+ break;
+
+ case BUTTON_RADIO:
+ ButtonRadioPress(f_sButton);
+ break;
+
+ default:
+ break;
+ }
+
+} // ButtonPress
+
+
+void ButtonClickRelease(struct ButtonStruct *f_sButton)
+{
+ ButtonDisable(f_sButton);
+
+} // ButtonClickRelease
+
+
+void ButtonRelease(struct ButtonStruct *f_sButton)
+{
+ int l_iType = f_sButton->m_iType;
+
+ switch (l_iType)
+ {
+ case BUTTON_CLICK:
+ ButtonClickRelease(f_sButton);
+ break;
+
+ case BUTTON_RADIO:
+ default:
+ break;
+ }
+
+} // ButtonRelease
+
+
+void ButtonEnable(struct ButtonStruct *f_sButton)
+{
+ f_sButton->m_bPressed = TRUE;
+
+} // ButtonEnable
+
+
+void ButtonDisable(struct ButtonStruct *f_sButton)
+{
+ f_sButton->m_bPressed = FALSE;
+
+} // ButtonDisable
diff --git a/matchblox/menu/button.h b/matchblox/menu/button.h
new file mode 100644
index 0000000..d8f1fe5
--- /dev/null
+++ b/matchblox/menu/button.h
@@ -0,0 +1,54 @@
+#ifndef _CBUTTON_H
+#define _CBUTTON_H
+
+#include "bitmap.h"
+
+#define BUTTON_MAX_TITLE 256
+#define BUTTON_MAX_IMGS 3
+#define BUTTON_CLICK_HEIGHT 49
+
+struct ButtonStruct {
+ int m_iXPos; // x positie
+ int m_iYPos; // y positie
+ int m_iCenterWidth; // breedte van middenstuk
+ int m_iWidth; // totale breedte
+ int m_iHeight; // totale hoogte
+ int m_bPressed; // pressed or not
+ int m_bHover; // mouse hovering or not
+ int m_iType; // button type
+ int m_iGroup; // group id for radio buttons
+ int m_iId; // button identifier
+
+ // button caption/title
+ char m_pcTitle[BUTTON_MAX_TITLE];
+
+ // button images
+ struct BitmapStruct m_psImgNormal[BUTTON_MAX_IMGS];
+ struct BitmapStruct m_psImgHover[BUTTON_MAX_IMGS];
+ struct BitmapStruct m_psImgPressed[BUTTON_MAX_IMGS];
+};
+
+enum ButtonType {
+ BUTTON_CLICK,
+ BUTTON_RADIO
+};
+
+enum ButtonGroup {
+ BUTTON_NO_GROUP,
+ BUTTON_GROUP1,
+ BUTTON_GROUP2,
+ BUTTON_GROUP3,
+ BUTTON_GROUP4
+};
+
+struct ButtonStruct ButtonCreate(int f_dXPos, int f_dYPos, int f_dCenterWidth, int f_dHeight, char *f_pcTitle, int f_iType, int f_iGroup, int f_iId);
+
+void ButtonRender(struct ButtonStruct *f_sButton);
+void ButtonEnter(struct ButtonStruct *f_sButton);
+void ButtonExit(struct ButtonStruct *f_sButton);
+void ButtonPress(struct ButtonStruct *f_sButton);
+void ButtonRelease(struct ButtonStruct *f_sButton);
+void ButtonEnable(struct ButtonStruct *f_sButton);
+void ButtonDisable(struct ButtonStruct *f_sButton);
+
+#endif
diff --git a/matchblox/menu/menu.c b/matchblox/menu/menu.c
new file mode 100644
index 0000000..9276850
--- /dev/null
+++ b/matchblox/menu/menu.c
@@ -0,0 +1,359 @@
+#ifdef G_OS_WIN32
+ #define WIN32_LEAN_AND_MEAN 1
+ #include <windows.h>
+#else
+ #define FALSE 0
+ #define TRUE !FALSE
+#endif
+
+#include <string.h>
+#include <GL/gl.h>
+#include <GL/glut.h>
+#include <string.h>
+
+#include "menu.h"
+#include "button.h"
+#include "font.h"
+
+#define MENU_MAX_BUTTONS 16
+
+enum MenuState {
+ MENU_OFF,
+ MENU_MAIN,
+ MENU_START,
+ MENU_OPTIONS
+};
+
+struct MenuStruct {
+ enum MenuState m_iMenuId;
+ int m_iButtonCount;
+ struct ButtonStruct m_sButtons[MENU_MAX_BUTTONS];
+};
+
+struct MenuStruct g_sMenuOff; // definition of the menu when it's disabled (empty menu)
+struct MenuStruct g_sMenuMain; // definition of the main menu
+struct MenuStruct g_sMenuStart; // definition of the start menu
+struct MenuStruct g_sMenuOptions; // definition of the options menu
+struct MenuStruct *g_pCurMenu; // current menu
+
+struct BitmapStruct g_sCursorImage; // bitmap struct of the cursor
+
+int g_iWinWidth;
+int g_iWinHeight;
+
+int g_iXPos; // last cursor pos
+int g_iYPos;
+
+
+void MenuEnableGroup(int f_iGroup)
+{
+ struct ButtonStruct l_sButton;
+ int l_iType, l_iGroup;
+ int i = 0;
+
+ // enable first radio button in this group
+ while (i < g_pCurMenu->m_iButtonCount)
+ {
+ l_sButton = g_pCurMenu->m_sButtons[i];
+ l_iType = l_sButton.m_iType;
+ l_iGroup = l_sButton.m_iGroup;
+
+ if (l_iType == BUTTON_RADIO && l_iGroup == f_iGroup)
+ {
+ ButtonEnable(&g_pCurMenu->m_sButtons[i]);
+ return;
+ }
+
+ i++;
+ }
+
+} // MenuEnableGroup
+
+
+void MenuAddButton(int f_dXPos, int f_dYPos, int f_dWidth, int f_dHeight, char *f_pcTitle, int f_iType, int f_iGroup)
+{
+ int i = g_pCurMenu->m_iButtonCount;
+
+ if (i > MENU_MAX_BUTTONS - 1) return;
+
+ // create the button with the right parameters
+ g_pCurMenu->m_sButtons[i] = ButtonCreate(f_dXPos, f_dYPos, f_dWidth, f_dHeight, f_pcTitle, f_iType, f_iGroup, i);
+ g_pCurMenu->m_iButtonCount = i + 1;
+
+} // MenuAddButton
+
+
+void MenuClear(void)
+{
+ g_pCurMenu->m_iButtonCount = 0;
+ memset(&g_pCurMenu->m_sButtons, 0, sizeof(g_pCurMenu->m_sButtons));
+
+} // MenuClear
+
+
+void MenuBuild (void)
+{
+ int l_iMenuId = g_pCurMenu->m_iMenuId;
+
+ switch (l_iMenuId)
+ {
+ default:
+ case MENU_OFF:
+ // no buttons
+ break;
+
+ case MENU_MAIN:
+ MenuAddButton(200, 150, 256, 128, "START", BUTTON_CLICK, BUTTON_NO_GROUP);
+ break;
+
+ case MENU_START:
+ MenuAddButton(50, 50, 250, 64, "Button 1", BUTTON_CLICK, BUTTON_NO_GROUP);
+ MenuAddButton(50, 150, 250, 64, "Button 2", BUTTON_CLICK, BUTTON_NO_GROUP);
+ MenuAddButton(350, 50, 64, 64, "Radio 1", BUTTON_RADIO, BUTTON_GROUP1);
+ MenuAddButton(350, 150, 64, 64, "Radio 2", BUTTON_RADIO, BUTTON_GROUP1);
+ MenuEnableGroup(BUTTON_GROUP1);
+
+ MenuAddButton(50, 250, 256, 64, "Button 3", BUTTON_CLICK, BUTTON_NO_GROUP);
+ MenuAddButton(50, 350, 256, 64, "Button 4", BUTTON_CLICK, BUTTON_NO_GROUP);
+ MenuAddButton(350, 250, 64, 64, "Radio A", BUTTON_RADIO, BUTTON_GROUP2);
+ MenuAddButton(350, 350, 64, 64, "Radio B", BUTTON_RADIO, BUTTON_GROUP2);
+ MenuEnableGroup(BUTTON_GROUP2);
+ break;
+
+ case MENU_OPTIONS:
+ MenuAddButton(50, 150, 250, 64, "Start", BUTTON_CLICK, BUTTON_NO_GROUP);
+ MenuAddButton(50, 250, 250, 64, "Back", BUTTON_CLICK, BUTTON_NO_GROUP);
+ MenuAddButton(350, 150, 64, 64, "Try first!", BUTTON_RADIO, BUTTON_GROUP1);
+ MenuAddButton(350, 250, 64, 64, "10 games", BUTTON_RADIO, BUTTON_GROUP1);
+ MenuEnableGroup(BUTTON_GROUP1);
+ break;
+ }
+
+} // MenuBuild
+
+
+void MenuNext(void)
+{
+ int l_iMenuId = g_pCurMenu->m_iMenuId;
+
+ l_iMenuId = (l_iMenuId + 1) % 4;
+
+ switch (l_iMenuId)
+ {
+ default:
+ case MENU_OFF: g_pCurMenu = &g_sMenuOff; break;
+ case MENU_MAIN: g_pCurMenu = &g_sMenuMain; break;
+ case MENU_START: g_pCurMenu = &g_sMenuStart; break;
+ case MENU_OPTIONS: g_pCurMenu = &g_sMenuOptions; break;
+ }
+
+} // MenuNext
+
+
+void MenuInit(int f_iWinWidth, int f_iWinHeight)
+{
+ // init menu props
+ g_iWinWidth = f_iWinWidth;
+ g_iWinHeight = f_iWinHeight;
+ g_iXPos = -100;
+ g_iYPos = -100;
+
+ // init main off
+ g_sMenuOff.m_iMenuId = MENU_OFF;
+ g_pCurMenu = &g_sMenuOff;
+ MenuBuild();
+
+ // init main menu
+ g_sMenuMain.m_iMenuId = MENU_MAIN;
+ g_pCurMenu = &g_sMenuMain;
+ MenuBuild();
+
+ // init start menu
+ g_sMenuStart.m_iMenuId = MENU_START;
+ g_pCurMenu = &g_sMenuStart;
+ MenuBuild();
+
+ // init options menu
+ g_sMenuOptions.m_iMenuId = MENU_OPTIONS;
+ g_pCurMenu = &g_sMenuOptions;
+ MenuBuild();
+
+ // init font
+ FontInit(f_iWinWidth, f_iWinHeight);
+
+ g_pCurMenu = &g_sMenuOff;
+
+ // load cursor image
+ g_sCursorImage = BitmapLoad("img/cursor.bmp");
+
+} // MenuInit
+
+
+void MenuRender(void)
+{
+ int i = 0;
+
+ glClearColor(0.9, 0.9, 0.9, 1);
+
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_TEXTURE_2D);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+
+ glLoadIdentity();
+ glOrtho(0, g_iWinWidth, g_iWinHeight, 0, 0, 1);
+ glMatrixMode(GL_MODELVIEW);
+
+ glEnable(GL_BLEND);
+
+ if (g_pCurMenu->m_iMenuId != MENU_OFF)
+ {
+ glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);
+
+ glColor3d(0.6, 0.6, 0.7);
+ glBegin(GL_TRIANGLE_STRIP);
+ glVertex2i(0, 0);
+ glVertex2i(g_iWinWidth, 0);
+ glVertex2i(0, g_iWinHeight);
+ glVertex2i(g_iWinWidth, g_iWinHeight);
+ glEnd();
+ }
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ // render the buttons of the current menu
+ for (i; i < g_pCurMenu->m_iButtonCount; i++)
+ {
+ glColor4d(1, 1, 1, 1);
+ ButtonRender(&g_pCurMenu->m_sButtons[i]);
+ }
+
+ // render cursor
+ glColor3d(1, 1, 1);
+ BitmapRender(g_iXPos,
+ g_iYPos,
+ 64, //g_sCursorImage.m_iWidth,
+ 64, //g_sCursorImage.m_iHeight,
+ g_sCursorImage.m_iImageId);
+
+ glDisable(GL_BLEND);
+
+ //restore the previous projection matrix
+ glMatrixMode(GL_PROJECTION);
+
+ glPopMatrix();
+
+} // MenuRender
+
+
+int MenuCollision(struct ButtonStruct *f_sButton, int f_iXPos, int f_iYPos)
+{
+ int l_bCollision;
+ int l_iButtonX, l_iButtonY;
+ int l_iButtonWidth, l_iButtonHeight;
+
+ l_iButtonX = f_sButton->m_iXPos;
+ l_iButtonY = f_sButton->m_iYPos;
+ l_iButtonWidth = f_sButton->m_iWidth;
+ l_iButtonHeight = f_sButton->m_iHeight;
+
+ l_bCollision = f_iXPos >= l_iButtonX;
+ l_bCollision &= f_iYPos >= l_iButtonY;
+ l_bCollision &= f_iXPos <= l_iButtonX + l_iButtonWidth;
+ l_bCollision &= f_iYPos <= l_iButtonY + l_iButtonHeight;
+
+ if (l_bCollision) return TRUE;
+ return FALSE;
+
+} // MenuCollision
+
+
+void MenuMouseClick(int f_iGlutButton, int f_iGlutState, int f_iXPos, int f_iYPos)
+{
+ int i = 0;
+ int l_iXPos, l_iYPos;
+ int l_iWidth, l_iHeight;
+ int l_iType, l_iId, l_iGroup;
+ struct ButtonStruct l_sButton;
+
+ // button released
+ if (f_iGlutButton == GLUT_LEFT_BUTTON && f_iGlutState == GLUT_UP)
+ {
+ // post a button released event to all buttons
+ for (i; i < g_pCurMenu->m_iButtonCount; i++)
+ {
+ l_iType = g_pCurMenu->m_sButtons[i].m_iType;
+ ButtonRelease(&g_pCurMenu->m_sButtons[i]);
+ }
+ }
+
+ // check if any button needs attention from the mouse
+ i = g_pCurMenu->m_iButtonCount;
+ for (i; i >= 0; i--)
+ {
+ l_sButton = g_pCurMenu->m_sButtons[i];
+ l_iXPos = l_sButton.m_iXPos;
+ l_iYPos = l_sButton.m_iYPos;
+ l_iWidth = l_sButton.m_iWidth;
+ l_iHeight = l_sButton.m_iHeight;
+ l_iType = l_sButton.m_iType;
+ l_iId = l_sButton.m_iId;
+ l_iGroup = l_sButton.m_iGroup;
+
+ if (MenuCollision(&l_sButton, f_iXPos, f_iYPos))
+ {
+ // button pressed?
+ if (f_iGlutButton == GLUT_LEFT_BUTTON && f_iGlutState == GLUT_DOWN)
+ {
+ ButtonPress(&g_pCurMenu->m_sButtons[i]);
+
+ if (l_iType == BUTTON_RADIO)
+ {
+ i = 0;
+ while (i < g_pCurMenu->m_iButtonCount)
+ {
+
+ if (l_iId != g_pCurMenu->m_sButtons[i].m_iId &&
+ l_iType == g_pCurMenu->m_sButtons[i].m_iType &&
+ l_iGroup == g_pCurMenu->m_sButtons[i].m_iGroup)
+ {
+ ButtonDisable(&g_pCurMenu->m_sButtons[i]);
+ }
+ i++;
+ }
+ }
+
+ return;
+ }
+ }
+ }
+
+} // MenuMouseClick
+
+
+void MenuMouseMove(int f_iXPos, int f_iYPos)
+{
+ int i = 0;
+ struct ButtonStruct l_sButton;
+
+ g_iXPos = f_iXPos;
+ g_iYPos = f_iYPos;
+
+ // check if any button needs attention from the mouse
+ for (i; i < g_pCurMenu->m_iButtonCount; i++)
+ {
+ l_sButton = g_pCurMenu->m_sButtons[i];
+
+ if (MenuCollision(&l_sButton, f_iXPos, f_iYPos))
+ {
+ ButtonEnter(&g_pCurMenu->m_sButtons[i]);
+ }
+ else // mouse leaves button
+ {
+ ButtonExit(&g_pCurMenu->m_sButtons[i]);
+ }
+ }
+
+} // MenuMouseMove
+
diff --git a/matchblox/menu/menu.h b/matchblox/menu/menu.h
new file mode 100644
index 0000000..0b4e95f
--- /dev/null
+++ b/matchblox/menu/menu.h
@@ -0,0 +1,10 @@
+#ifndef _CMENU_H
+#define _CMENU_H
+
+void MenuNext(void);
+void MenuInit(int f_iWinWidth, int f_iWinHeight);
+void MenuRender(void);
+void MenuMouseClick(int button, int state, int x, int y);
+void MenuMouseMove(int x, int y);
+
+#endif
diff --git a/matchblox/src/Makefile b/matchblox/src/Makefile
deleted file mode 100644
index e242a64..0000000
--- a/matchblox/src/Makefile
+++ /dev/null
@@ -1,299 +0,0 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
-# src/Makefile. Generated from Makefile.in by configure.
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-
-
-pkgdatadir = $(datadir)/matchblox
-pkglibdir = $(libdir)/matchblox
-pkgincludedir = $(includedir)/matchblox
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-subdir = src
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-SOURCES =
-DIST_SOURCES =
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = ${SHELL} /home/oliver/School/2iv55/matchblox/missing --run aclocal-1.10
-AMTAR = ${SHELL} /home/oliver/School/2iv55/matchblox/missing --run tar
-AUTOCONF = ${SHELL} /home/oliver/School/2iv55/matchblox/missing --run autoconf
-AUTOHEADER = ${SHELL} /home/oliver/School/2iv55/matchblox/missing --run autoheader
-AUTOMAKE = ${SHELL} /home/oliver/School/2iv55/matchblox/missing --run automake-1.10
-AWK = mawk
-CC = gcc
-CCDEPMODE = depmode=gcc3
-CFLAGS = -g -O2
-CPP = gcc -E
-CPPFLAGS =
-CYGPATH_W = echo
-DEFS = -DHAVE_CONFIG_H
-DEPDIR = .deps
-ECHO_C =
-ECHO_N = -n
-ECHO_T =
-EGREP = /bin/grep -E
-EXEEXT =
-GREP = /bin/grep
-INSTALL = /usr/bin/install -c
-INSTALL_DATA = ${INSTALL} -m 644
-INSTALL_PROGRAM = ${INSTALL}
-INSTALL_SCRIPT = ${INSTALL}
-INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
-LDFLAGS =
-LIBOBJS =
-LIBS =
-LTLIBOBJS =
-MAINT = #
-MAKEINFO = ${SHELL} /home/oliver/School/2iv55/matchblox/missing --run makeinfo
-MKDIR_P = /bin/mkdir -p
-OBJEXT = o
-PACKAGE = matchblox
-PACKAGE_BUGREPORT =
-PACKAGE_NAME = matchblox
-PACKAGE_STRING = matchblox 0.1
-PACKAGE_TARNAME = matchblox
-PACKAGE_VERSION = 0.1
-PATH_SEPARATOR = :
-SET_MAKE =
-SHELL = /bin/bash
-STRIP =
-VERSION = 0.1
-abs_builddir = /home/oliver/School/2iv55/matchblox/src
-abs_srcdir = /home/oliver/School/2iv55/matchblox/src
-abs_top_builddir = /home/oliver/School/2iv55/matchblox
-abs_top_srcdir = /home/oliver/School/2iv55/matchblox
-ac_ct_CC = gcc
-am__include = include
-am__leading_dot = .
-am__quote =
-am__tar = ${AMTAR} chof - "$$tardir"
-am__untar = ${AMTAR} xf -
-bindir = ${exec_prefix}/bin
-build_alias =
-builddir = .
-datadir = ${datarootdir}
-datarootdir = ${prefix}/share
-docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
-dvidir = ${docdir}
-exec_prefix = ${prefix}
-host_alias =
-htmldir = ${docdir}
-includedir = ${prefix}/include
-infodir = ${datarootdir}/info
-install_sh = $(SHELL) /home/oliver/School/2iv55/matchblox/install-sh
-libdir = ${exec_prefix}/lib
-libexecdir = ${exec_prefix}/libexec
-localedir = ${datarootdir}/locale
-localstatedir = ${prefix}/var
-mandir = ${datarootdir}/man
-mkdir_p = /bin/mkdir -p
-oldincludedir = /usr/include
-pdfdir = ${docdir}
-prefix = /usr/local
-program_transform_name = s,x,x,
-psdir = ${docdir}
-sbindir = ${exec_prefix}/sbin
-sharedstatedir = ${prefix}/com
-srcdir = .
-sysconfdir = ${prefix}/etc
-target_alias =
-top_builddir = ..
-top_srcdir = ..
-AM_CPPFLAGS = \
- -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
- -DPACKAGE_SRC_DIR=\""$(srcdir)"\" \
- -DPACKAGE_DATA_DIR=\""$(datadir)"\"
-
-AM_CFLAGS = \
- -Wall\
- -g
-
-all: all-am
-
-.SUFFIXES:
-$(srcdir)/Makefile.in: # $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: # $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): # $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-tags: TAGS
-TAGS:
-
-ctags: CTAGS
-CTAGS:
-
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
- fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
- else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic mostlyclean-am
-
-distclean: distclean-am
- -rm -f Makefile
-distclean-am: clean-am distclean-generic
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-am
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-info: install-info-am
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-ps: install-ps-am
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-generic
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am:
-
-.MAKE: install-am install-strip
-
-.PHONY: all all-am check check-am clean clean-generic distclean \
- distclean-generic distdir dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-info install-info-am install-man \
- install-pdf install-pdf-am install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/matchblox/src/Makefile.am b/matchblox/src/Makefile.am
deleted file mode 100644
index 63a41a4..0000000
--- a/matchblox/src/Makefile.am
+++ /dev/null
@@ -1,13 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-## Created by Anjuta
-
-AM_CPPFLAGS = \
- -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
- -DPACKAGE_SRC_DIR=\""$(srcdir)"\" \
- -DPACKAGE_DATA_DIR=\""$(datadir)"\"
-
-AM_CFLAGS =\
- -Wall\
- -g
-
diff --git a/matchblox/src/Makefile.in b/matchblox/src/Makefile.in
deleted file mode 100644
index 836c24f..0000000
--- a/matchblox/src/Makefile.in
+++ /dev/null
@@ -1,299 +0,0 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-subdir = src
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-SOURCES =
-DIST_SOURCES =
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-OBJEXT = @OBJEXT@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build_alias = @build_alias@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host_alias = @host_alias@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-AM_CPPFLAGS = \
- -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
- -DPACKAGE_SRC_DIR=\""$(srcdir)"\" \
- -DPACKAGE_DATA_DIR=\""$(datadir)"\"
-
-AM_CFLAGS = \
- -Wall\
- -g
-
-all: all-am
-
-.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-tags: TAGS
-TAGS:
-
-ctags: CTAGS
-CTAGS:
-
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
- fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
- else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic mostlyclean-am
-
-distclean: distclean-am
- -rm -f Makefile
-distclean-am: clean-am distclean-generic
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-am
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-info: install-info-am
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-ps: install-ps-am
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-generic
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am:
-
-.MAKE: install-am install-strip
-
-.PHONY: all all-am check check-am clean clean-generic distclean \
- distclean-generic distdir dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-info install-info-am install-man \
- install-pdf install-pdf-am install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/matchblox/src/main.c b/matchblox/src/main.c
deleted file mode 100644
index 4d1afb5..0000000
--- a/matchblox/src/main.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
-/*
- * main.c
- *
- * Maik, Dennis, Wilrik & Oliver
- *
- * Copyright (C) 2008
- *
- * main.c 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 3 of the License, or
- * (at your option) any later version.
- *
- * main.c 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-
-#include "opengl.h"
-
-int main()
-{
- renderer_main();
- printf("Hello world\n");
- return (0);
-}
diff --git a/matchblox/src/renderer_opengl.c b/matchblox/src/renderer_opengl.c
deleted file mode 100644
index bc6d773..0000000
--- a/matchblox/src/renderer_opengl.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/***************************************************************************
- * renderer_opengl.c
- *
- * Thu Mar 20 15:42:48 2008
- * Copyright 2008 Oliver
- * <o.m.schinagl@student.tue.nl>
- ****************************************************************************/
-
-/*
- * 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 of the License, 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 Library 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
- */
-
-
-
-/* redblue_stereo.c - demo of stereo for red/blue filter stereo glasses */
-
-/* by Walter Vannini (walterv@jps.net, waltervannini@hotmail.com) */
-
-/* In stereo mode, the object is drawn in red for the left eye
- and blue for the right eye. Viewing the scene with red/blue
- filter stereo glasses should give a sense of stereo 3D.
- glColorMask is used to control update of the red and blue
- channel. glFrustum is used to setup two different view frustums
- for each eye based on eye separation. */
-
-/* Copyright (c) Walter Vannini, 1998. */
-
-/* This program is freely distributable without licensing fees and is
- provided without guarantee or warrantee expressed or implied. This
- program is -not- in the public domain. */
-
-#include <stdlib.h>
-#include <math.h>
-#include <GL/glut.h>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-void init(void);
-void KeyboardFunc(unsigned char key, int x, int y);
-void MenuFunc(int value);
-void IdleFunc(void);
-void ReshapeFunc(int w, int h);
-void DisplayFunc(void);
-
-
-struct ProgramState
-{
- int w;
- int h;
- GLdouble RotationY;
- double eye;
- double zscreen;
- double znear;
- double zfar;
- double RotationIncrement;
- int solidmode;
-};
-struct ProgramState ps;
-
-const double PIXELS_PER_INCH = 100.0;
-
-void init(void)
-{
- GLfloat mat_ambient[] = {0.2,0.0,0.2,1.0} ;
- GLfloat mat_diffuse[] = {0.7,0.0,0.7,1.0} ;
- GLfloat mat_specular[] = {0.1,0.0,0.1,1.0} ;
- GLfloat mat_shininess[]={20.0};
-
- GLfloat light_position[]={0.0,5.0,20.0,1.0};
-
- GLfloat light_ambient0[]= {1.0,0.0,0.0,1.0};
- GLfloat light_diffuse0[]= {1.0,0.0,0.0,1.0};
- GLfloat light_specular0[]={1.0,0.0,0.0,1.0};
-
- GLfloat light_ambient1[]= {0.0,0.0,1.0,1.0};
- GLfloat light_diffuse1[]= {0.0,0.0,1.0,1.0};
- GLfloat light_specular1[]={0.0,0.0,1.0,1.0};
-
- glDisable(GL_DITHER);
- glClearColor(0.0, 0.0, 0.0, 1.0);
- glShadeModel(GL_SMOOTH);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_NORMALIZE);
- glEnable(GL_CULL_FACE);
- glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
-
-
- glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
- glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
- glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
-
- glLightfv(GL_LIGHT0, GL_POSITION, light_position);
- glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient0);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse0);
- glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular0);
-
- glLightfv(GL_LIGHT1, GL_POSITION, light_position);
- glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient1);
- glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse1);
- glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular1);
- glEnable(GL_LIGHTING);
-
- ps.eye=0.80;
- ps.zscreen = 10.0;
- ps.znear = 7.0;
- ps.zfar = 13.0;
- ps.RotationY = 0.0;
- ps.RotationIncrement = 0.1;
- ps.solidmode = 1;
-}
-
-void KeyboardFunc(unsigned char key, int x, int y)
-{
- switch(key)
- {
- case 27: /* escape */
- case 'q':
- case 'Q':
- exit(0);
- break;
- case 's': /* stereo */
- ps.eye = 1.20;
- break;
- case '1':
- ps.solidmode = 1;
- glFrontFace(GL_CCW);
- break;
- case '2':
- ps.solidmode = 2;
- glFrontFace(GL_CCW);
- break;
- case '3':
- ps.solidmode = 3;
- /* The teapot polygons face the wrong way. Sigh. */
- glFrontFace(GL_CW);
- break;
- case '4':
- ps.solidmode = 4;
- glFrontFace(GL_CCW);
- break;
- case 'm': /* mono */
- ps.eye = 0.0;
- break;
- }
-}
-
-void MenuFunc(int value)
-{
- KeyboardFunc(value, 0, 0);
-}
-
-void IdleFunc(void)
-{
- ps.RotationY += ps.RotationIncrement;
- glutPostRedisplay();
-}
-
-void ReshapeFunc(int w, int h)
-{
- glViewport(0,0, w, h);
- ps.w = w;
- ps.h = h;
-}
-
-void DisplayFunc(void)
-{
- double xfactor=1.0, yfactor=1.0;
- double Eye =0.0;
- int i;
-
- if(ps.w < ps.h)
- {
- xfactor = 1.0;
- yfactor = ps.h/ps.w;
- }
- else if(ps.h < ps.w)
- {
- xfactor = ps.w/ps.h;
- yfactor = 1.0;
- }
-
- glClear(GL_COLOR_BUFFER_BIT);
- for(i=0;i<2;i++)
- {
- glEnable(GL_LIGHT0 + i);
- glClear(GL_DEPTH_BUFFER_BIT);
- if(i==0) /* left eye - RED */
- {
- Eye = ps.eye;
- glColorMask(GL_TRUE,GL_FALSE,GL_FALSE,GL_TRUE);
- }
- else /* if(i==1) right eye - BLUE */
- {
- Eye = -ps.eye;
- glColorMask(GL_FALSE,GL_FALSE,GL_TRUE,GL_TRUE);
- }
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum(
- (-(ps.w/(2.0*PIXELS_PER_INCH))+Eye) *(ps.znear/ps.zscreen)*xfactor,
- (ps.w/(2.0*PIXELS_PER_INCH)+Eye) *(ps.znear/ps.zscreen)*xfactor,
- -(ps.h/(2.0*PIXELS_PER_INCH))*(ps.znear/ps.zscreen)*yfactor,
- (ps.h/(2.0*PIXELS_PER_INCH))*(ps.znear/ps.zscreen)*yfactor,
- ps.znear, ps.zfar);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(Eye,0.0,0.0);
- glTranslated(0,0,-ps.zscreen);
-
- switch(ps.solidmode)
- {
- case 1:
- {
- glTranslated(cos(ps.RotationY*M_PI/180.0),
- 0, -sin(ps.RotationY*M_PI/180.0) );
- glRotated(ps.RotationY, 0.0,0.1,0.0);
- glPushMatrix();
- glScalef(0.5,0.5,0.5);
- glutSolidDodecahedron();
- glPopMatrix();
- break;
- }
- case 2:
- {
- glTranslated(cos(ps.RotationY*M_PI/180.0),
- 0, -sin(ps.RotationY*M_PI/180.0) );
- glRotated(ps.RotationY, 0.0,0.1,0.0);
- glutSolidIcosahedron();
- break;
- }
- case 3:
- {
- glRotated(60.0, 1 , 0, 0);
- glTranslated(cos(ps.RotationY*M_PI/180.0),
- 0, -sin(ps.RotationY*M_PI/180.0) );
- glRotated(ps.RotationY, 0.0,0.1,0.0);
- glutSolidTeapot(1.0);
- break;
- }
- case 4:
- {
- glRotated(60.0, 1, 0, 0);
- glTranslated(cos(ps.RotationY *M_PI/180),
- 0, -sin(ps.RotationY *M_PI/180) );
- glRotated(ps.RotationY, 0.0, 0.1, 0.0);
- glutSolidTorus(0.2, 0.5, 5.0, 5.0);
- break;
- }
- }
- glDisable(GL_LIGHT0 + i);
- }
- glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
- glutSwapBuffers();
-}
-void
-VisibilityFunc(int vis)
-{
- if (vis == GLUT_VISIBLE) {
- glutIdleFunc(IdleFunc);
- } else {
- glutIdleFunc(NULL);
- }
-}
-
-int renderer_main(void)
-{
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA );
- ps.w = 512;
- ps.h = 512;
- glutInitWindowSize(ps.w, ps.h);
- glutInitWindowPosition(100,100);
-
- glutCreateWindow(argv[0]);
- init();
- glutVisibilityFunc(VisibilityFunc);
- glutDisplayFunc(DisplayFunc);
- glutReshapeFunc(ReshapeFunc);
- glutKeyboardFunc(KeyboardFunc);
- glutCreateMenu(MenuFunc);
- glutAddMenuEntry("Stereo", 's');
- glutAddMenuEntry("Mono", 'm');
- glutAddMenuEntry("Dodecahedron", '1');
- glutAddMenuEntry("Icosahedron", '2');
- glutAddMenuEntry("Teapot", '3');
- glutAddMenuEntry("Solar system", '4');
- glutAttachMenu(GLUT_RIGHT_BUTTON);
- glutMainLoop();
-
- return 0;
-}
diff --git a/matchblox/src/renderer_opengl.h b/matchblox/src/renderer_opengl.h
deleted file mode 100644
index ca50b59..0000000
--- a/matchblox/src/renderer_opengl.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/***************************************************************************
- * renderer_opengl.h
- *
- * Thu Mar 20 15:43:12 2008
- * Copyright 2008 Oliver
- * <o.m.schinagl@student.tue.nl>
- ****************************************************************************/
-
-/*
- * 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 of the License, 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 Library 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
- */
-
- int renderer_main(void);
diff --git a/matchblox/typedefs.h b/matchblox/typedefs.h
new file mode 100644
index 0000000..0262c14
--- /dev/null
+++ b/matchblox/typedefs.h
@@ -0,0 +1,128 @@
+#ifndef TYPEDEFS_H
+
+#define TYPEDEFS_H
+
+#include <vector>
+#include <limits>
+
+typedef struct bb
+{
+ bb() {
+ //init a bounding box with the min values set to max double and visa versa
+ m_dLeft = m_dBottom = m_dFront = std::numeric_limits<double>::max();
+ m_dRight = m_dTop = m_dBack = -std::numeric_limits<double>::max();
+ }
+
+ double m_dLeft, //min x
+ m_dBottom, //min y
+ m_dFront, //min z
+ m_dRight, //max x
+ m_dTop, //max y
+ m_dBack; //max z
+
+} BoundingBox_t;
+
+typedef struct vec3d
+{
+ double x, y, z;
+
+ //constructors
+ vec3d()
+ { x=0.0, y=0.0, z=0.0; }
+ vec3d(double fx, double fy, double fz)
+ { x=fx, y=fy, z=fz; }
+ vec3d(const vec3d &clone)
+ { x=clone.x; y=clone.y; z=clone.z; }
+
+ inline vec3d& operator=(const vec3d &rhs)
+ { x=rhs.x; y=rhs.y; z=rhs.z; return *this; }
+ inline vec3d& operator+=(const vec3d &rhs)
+ { x+=rhs.x; y+=rhs.y; z+=rhs.z; return *this; }
+ inline vec3d& operator-=(const vec3d &rhs)
+ { x-=rhs.x; y-=rhs.y; z-=rhs.z; return *this; }
+ inline vec3d& operator*=(const vec3d &rhs)
+ { x*=rhs.x; y*=rhs.y; z*=rhs.z; return *this; }
+ inline vec3d& operator*=(const double &scal)
+ { x*=scal; y*=scal; z*=scal; return *this; }
+
+ inline const vec3d& operator+(const vec3d &rhs)
+ { return vec3d(*this) += rhs; }
+ inline const vec3d& operator-(const vec3d &rhs)
+ { return vec3d(*this) -= rhs; }
+ inline const vec3d& operator*(const vec3d &rhs)
+ { return vec3d(*this) *= rhs; }
+ inline const vec3d& operator*(const double &scal)
+ { return vec3d(*this) *= scal; }
+} Vect3D_t;
+
+
+
+inline void UpdBBox(BoundingBox_t &B, Vect3D_t &V)
+{
+ if (V.x < B.m_dLeft)
+ B.m_dLeft = V.x;
+ else if (V.x > B.m_dRight)
+ B.m_dRight = V.x;
+ if (V.y < B.m_dBottom)
+ B.m_dBottom = V.y;
+ else if (V.y > B.m_dTop)
+ B.m_dTop = V.y;
+ if (V.z < B.m_dFront)
+ B.m_dFront = V.z;
+ else if (V.z > B.m_dBack)
+ B.m_dBack = V.z;
+};
+
+typedef struct triangle
+{
+ int v1, n1, t1,
+ v2, n2, t2,
+ v3, n3, t3;
+} Triangle_t;
+
+typedef struct mat
+{
+ GLfloat m_fAmb[4],
+ m_fDif[4],
+ m_fSpec[4],
+ m_fEmi[4],
+ m_fShin;
+
+ //default constructor
+ mat()
+ {
+ m_fAmb[0] = m_fAmb[1] = m_fAmb[2] = 0.7f; m_fAmb[3] = 1.0f;
+ m_fDif[0] = m_fDif[1] = m_fDif[3] = 0.7f; m_fDif[3] = 1.0f;
+ m_fSpec[0] = m_fSpec[1] = m_fSpec[2] = m_fSpec[3] = 1.0f;
+ m_fEmi[0] = m_fEmi[1] = m_fEmi[2] = 0.0f; m_fEmi[3] = 1.0f;
+ m_fShin = 128.0f;
+ }
+ //for convenience
+ inline void setAmb(float r, float g, float b, float a)
+ { m_fAmb[0] = r; m_fAmb[1] = g; m_fAmb[2] = b; m_fAmb[3] = a; }
+ inline void setDif(float r, float g, float b, float a)
+ { m_fDif[0] = r; m_fDif[1] = g; m_fDif[2] = b; m_fDif[3] = a; }
+ inline void setSpec(float r, float g, float b, float a)
+ { m_fSpec[0] = r; m_fSpec[1] = g; m_fSpec[2] = b; m_fSpec[3] = a; }
+ inline void setEmi(float r, float g, float b, float a)
+ { m_fEmi[0] = r; m_fEmi[1] = g; m_fEmi[2] = b; m_fEmi[3] = a; }
+
+} MatProps_t;
+/*
+typedef struct facegroup
+{
+ MatProps_t m_material;
+ std::vector<Face_t> m_faces;
+} FaceGroup_t;
+*/
+
+typedef struct geom
+{
+ std::vector<Vect3D_t> m_verts,
+ m_norms,
+ m_texs;
+ std::vector<Triangle_t> m_triangles;
+} Geometry_t;
+
+#endif //TYPEDEFS_H
+