#include "ThGlutRenderer.h"
using namespace Th;
//-------------------------------------------------------------
IMPLEMENT_IS_DERIVED_FROM(GlutRenderer)
IMPLEMENT_STATIC_RTTI_MEMBER(GlutRenderer, Renderer)
//-------------------------------------------------------------
GlutRenderer::GlutRenderer(int iWidth,int iHeight) : Renderer(iWidth, iHeight)
{ }
//-------------------------------------------------------------
GlutRenderer::GlutRenderer(int iWidth, int iHeight, const Color& rkBGColor)
:
Renderer(iWidth, iHeight)
{
SetBackgroundColor(rkBGColor);
glEnable(GL_DEPTH_TEST);
}
//-------------------------------------------------------------
void GlutRenderer::SetBackgroundColor(const Color& rkBackgroundColor)
{
glClearColor(rkBackgroundColor.r, rkBackgroundColor.g, rkBackgroundColor.b, rkBackgroundColor.a);
}
//-------------------------------------------------------------
void GlutRenderer::RenderSphere(const Vector3& rfCenter, const Real& rfRadius)
{
glPushAttrib(GL_ALL_ATTRIB_BITS);
glDisable(GL_TEXTURE_2D);
glPushMatrix();
glTranslatef(rfCenter.x,rfCenter.y, rfCenter.z);
glutWireSphere(rfRadius, 10,10);
glPopMatrix();
glPopAttrib();
}
//-------------------------------------------------------------
void GlutRenderer::DisplayBackBuffer()
{
glFlush();
glutSwapBuffers();
}
//-------------------------------------------------------------
void GlutRenderer::ClearBuffers()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
//-------------------------------------------------------------
void GlutRenderer::RenderPoint(const Vector3& rkPoint)
{
glBegin(GL_POINTS);
glVertex3fv(rkPoint.v);
glEnd();
}
//-------------------------------------------------------------
void GlutRenderer::RenderLine(const Vector3& rkStart, const Vector3& rkEnd)
{
glBegin(GL_LINES);
glVertex3fv(rkStart.v);
glVertex3fv(rkEnd.v);
glEnd();
}
//-------------------------------------------------------------
void GlutRenderer::Render(const PointMesh* pkPointMesh)
{
//Create model->world 4x4 matrix: remember, OpenGl stores
//the data in row-vector notation
GLfloat fScale = pkPointMesh->WorldScale();
const Vector3& kTrans = pkPointMesh->WorldTranslate();
const Matrix3& kRot = pkPointMesh->WorldRotate();
GLfloat afModelToWorld[16] = {
fScale*kRot[0][0], fScale*kRot[1][0], fScale*kRot[2][0], 0.0f,
fScale*kRot[0][1], fScale*kRot[1][1], fScale*kRot[2][1], 0.0f,
fScale*kRot[0][1], fScale*kRot[1][2], fScale*kRot[2][2], 0.0f,
kTrans.x, kTrans.y, kTrans.z , 1.0f
};
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glMultMatrixf(afModelToWorld);
glBegin(GL_POINTS);
const Vector3* const akVertices = pkPointMesh->Vertices();
for (int iIndex = 0; iIndex < pkPointMesh->VertexCount(); iIndex++)
{
glVertex3fv(akVertices[iIndex].v);
}
glEnd();
glPopMatrix();
}
//-------------------------------------------------------------
void GlutRenderer::Render(const MD2Object* pkMD2Object)
{
static int siFrame = 0;
static float sfTime = 0.0f;
static int siAnimTime = 30;
PlaceInWorld(pkMD2Object);
const MD2Object::MD2Header& rkHeader = pkMD2Object->Header();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
PlaceInWorld(pkMD2Object);
const Vector3* akVertices = pkMD2Object->Vertices();
static int iCurrFrame = 0;
if (siFrame >= siAnimTime)
{
iCurrFrame++;
siFrame = 0;
sfTime = 0.0f;
}
if (iCurrFrame >= rkHeader.iNumFrames-1)
iCurrFrame = 0;
//Get Triangles & Texture coords
const MD2Object::MD2Triangle* akTriangle = pkMD2Object->Triangles();
const MD2Object::MD2TextureCoord* akTexture = pkMD2Object->TextureCoords();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//Render triangles
glBegin(GL_TRIANGLES);
for (int iIndex = 0; iIndex < rkHeader.iNumTriangles; iIndex++)
{
int iLookUp1 = akTriangle[iIndex].iVertexIndex[0]+iCurrFrame*rkHeader.iNumVertices;
int iLookUp2 = akTriangle[iIndex].iVertexIndex[0]+(iCurrFrame+1)*rkHeader.iNumVertices;
glTexCoord2f(((float)akTexture[akTriangle[iIndex].iTextureIndex[0]].sU) / (float)rkHeader.iSkinWidth,
((float)akTexture[akTriangle[iIndex].iTextureIndex[0]].sV) / (float)rkHeader.iSkinHeight);
glVertex3f( (1.0f-sfTime)*akVertices[iLookUp1].x + sfTime*akVertices[iLookUp2].x,
(1.0f-sfTime)*akVertices[iLookUp1].y + sfTime*akVertices[iLookUp2].y,
(1.0f-sfTime)*akVertices[iLookUp1].z + sfTime*akVertices[iLookUp2].z);
iLookUp1 = akTriangle[iIndex].iVertexIndex[1]+iCurrFrame*rkHeader.iNumVertices;
iLookUp2 = akTriangle[iIndex].iVertexIndex[1]+(iCurrFrame+1)*rkHeader.iNumVertices;
glTexCoord2f(((float)akTexture[akTriangle[iIndex].iTextureIndex[1]].sU) / (float)rkHeader.iSkinWidth,
((float)akTexture[akTriangle[iIndex].iTextureIndex[1]].sV) / (float)rkHeader.iSkinHeight);
glVertex3f( (1.0f-sfTime)*akVertices[iLookUp1].x + sfTime*akVertices[iLookUp2].x,
(1.0f-sfTime)*akVertices[iLookUp1].y + sfTime*akVertices[iLookUp2].y,
(1.0f-sfTime)*akVertices[iLookUp1].z + sfTime*akVertices[iLookUp2].z);
iLookUp1 = akTriangle[iIndex].iVertexIndex[2]+iCurrFrame*rkHeader.iNumVertices;
iLookUp2 = akTriangle[iIndex].iVertexIndex[2]+(iCurrFrame+1)*rkHeader.iNumVertices;
glTexCoord2f(((float)akTexture[akTriangle[iIndex].iTextureIndex[2]].sU) / (float)rkHeader.iSkinWidth,
((float)akTexture[akTriangle[iIndex].iTextureIndex[2]].sV) / (float)rkHeader.iSkinHeight);
glVertex3f( (1.0f-sfTime)*akVertices[iLookUp1].x + sfTime*akVertices[iLookUp2].x,
(1.0f-sfTime)*akVertices[iLookUp1].y + sfTime*akVertices[iLookUp2].y,
(1.0f-sfTime)*akVertices[iLookUp1].z + sfTime*akVertices[iLookUp2].z);
}
glEnd();
glPopMatrix();
siFrame++;
sfTime += 1.0f/(float)siAnimTime;
}
//-------------------------------------------------------------
void GlutRenderer::PlaceInWorld(const Geometry* pkObject)
{
assert(pkObject != NULL);
GLfloat fScale = pkObject->WorldScale();
const Vector3& kTrans = pkObject->WorldTranslate();
const Matrix3& kRot = pkObject->WorldRotate();
GLfloat afModelToWorld[16] = {
fScale*kRot[0][0], fScale*kRot[1][0], fScale*kRot[2][0], 0.0f,
fScale*kRot[0][1], fScale*kRot[1][1], fScale*kRot[2][1], 0.0f,
fScale*kRot[0][1], fScale*kRot[1][2], fScale*kRot[2][2], 0.0f,
kTrans.x, kTrans.y, kTrans.z , 1.0f
};
glMultMatrixf(afModelToWorld);
}
//-------------------------------------------------------------