PDA

View Full Version : Choosing the proper field of view



sueyllam
09-29-2014, 10:37 AM
I have the following program from a tutorial on the net, and it is supposed to display a robot arm that you can control with the Keyboard.
When it runs it displays nothing just the black background, however when I hit the space bar it prints in the command window the proper data.
So I am assuming everything get clipped, but cannot determine why is it the improper field of view set to 45 degree. Not sure how to get the robot within the clip region for the given data, any clues?
The shaders are really simple. The fragment shader simply passes the color through and the vertex shader multiplies the modeling-viewing matrices
by the vertices passed to it.



#include <iostream>
#include <vector>
#include <stack>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <stdio.h>

#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>

using namespace std;

const int WIDTH = 800;
const int HEIGHT = 600;

// Define a helpful macro for handling offsets into buffer objects
#define BUFFER_OFFSET( offset ) ((GLvoid*) (offset))
#define ARRAY_COUNT(array) (sizeof(array)/sizeof(array[0]))

GLuint InitShader(const char* vShaderFile, const char* fShaderFile);

GLuint positionAttrib;
GLuint colorAttrib;

GLuint modelToCameraMatrixUnif;
GLuint cameraToClipMatrixUnif;

glm::mat4 cameraToClipMatrix(0.0f);

float CalcFrustumScale(float fFovDeg)
{
const float degToRad = 3.14159f * 2.0f / 360.0f;
float fFovRad = fFovDeg * degToRad;
return 1.0f / tan(fFovRad / 2.0f);
}

const float fFrustumScale = CalcFrustumScale(45.0f);

const int numberOfVertices = 24;

#define RED_COLOR 1.0f, 0.0f, 0.0f, 1.0f
#define GREEN_COLOR 0.0f, 1.0f, 0.0f, 1.0f
#define BLUE_COLOR 0.0f, 0.0f, 1.0f, 1.0f

#define YELLOW_COLOR 1.0f, 1.0f, 0.0f, 1.0f
#define CYAN_COLOR 0.0f, 1.0f, 1.0f, 1.0f
#define MAGENTA_COLOR 1.0f, 0.0f, 1.0f, 1.0f

const float vertexData[] =
{
//Front
+1.0f, +1.0f, +1.0f,
+1.0f, -1.0f, +1.0f,
-1.0f, -1.0f, +1.0f,
-1.0f, +1.0f, +1.0f,

//Top
+1.0f, +1.0f, +1.0f,
-1.0f, +1.0f, +1.0f,
-1.0f, +1.0f, -1.0f,
+1.0f, +1.0f, -1.0f,

//Left
+1.0f, +1.0f, +1.0f,
+1.0f, +1.0f, -1.0f,
+1.0f, -1.0f, -1.0f,
+1.0f, -1.0f, +1.0f,

//Back
+1.0f, +1.0f, -1.0f,
-1.0f, +1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
+1.0f, -1.0f, -1.0f,

//Bottom
+1.0f, -1.0f, +1.0f,
+1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, +1.0f,

//Right
-1.0f, +1.0f, +1.0f,
-1.0f, -1.0f, +1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, +1.0f, -1.0f,


GREEN_COLOR,
GREEN_COLOR,
GREEN_COLOR,
GREEN_COLOR,

BLUE_COLOR,
BLUE_COLOR,
BLUE_COLOR,
BLUE_COLOR,

RED_COLOR,
RED_COLOR,
RED_COLOR,
RED_COLOR,

YELLOW_COLOR,
YELLOW_COLOR,
YELLOW_COLOR,
YELLOW_COLOR,

CYAN_COLOR,
CYAN_COLOR,
CYAN_COLOR,
CYAN_COLOR,

MAGENTA_COLOR,
MAGENTA_COLOR,
MAGENTA_COLOR,
MAGENTA_COLOR,
};

const GLshort indexData[] =
{
0, 1, 2,
2, 3, 0,

4, 5, 6,
6, 7, 4,

8, 9, 10,
10, 11, 8,

12, 13, 14,
14, 15, 12,

16, 17, 18,
18, 19, 16,

20, 21, 22,
22, 23, 20,
};

GLuint vertexBufferObject;
GLuint indexBufferObject;
GLuint vao;

inline float DegToRad(float fAngDeg)
{
const float fDegToRad = 3.14159f * 2.0f / 360.0f;
return fAngDeg * fDegToRad;
}

inline float Clamp(float fValue, float fMinValue, float fMaxValue)
{
if(fValue < fMinValue)
return fMinValue;

if(fValue > fMaxValue)
return fMaxValue;

return fValue;
}

glm::mat3 RotateX(float fAngDeg)
{
float fAngRad = DegToRad(fAngDeg);
float fCos = cosf(fAngRad);
float fSin = sinf(fAngRad);

glm::mat3 theMat(1.0f);
theMat[1].y = fCos; theMat[2].y = -fSin;
theMat[1].z = fSin; theMat[2].z = fCos;
return theMat;
}

glm::mat3 RotateY(float fAngDeg)
{
float fAngRad = DegToRad(fAngDeg);
float fCos = cosf(fAngRad);
float fSin = sinf(fAngRad);

glm::mat3 theMat(1.0f);
theMat[0].x = fCos; theMat[2].x = fSin;
theMat[0].z = -fSin; theMat[2].z = fCos;
return theMat;
}

glm::mat3 RotateZ(float fAngDeg)
{
float fAngRad = DegToRad(fAngDeg);
float fCos = cosf(fAngRad);
float fSin = sinf(fAngRad);

glm::mat3 theMat(1.0f);
theMat[0].x = fCos; theMat[1].x = -fSin;
theMat[0].y = fSin; theMat[1].y = fCos;
return theMat;
}

class MatrixStack
{
public:
MatrixStack()
: m_currMat(1.0f)
{
}

const glm::mat4 &Top()
{
return m_currMat;
}

void RotateX(float fAngDeg)
{
m_currMat = m_currMat * glm::mat4(::RotateX(fAngDeg));
}

void RotateY(float fAngDeg)
{
m_currMat = m_currMat * glm::mat4(::RotateY(fAngDeg));
}

void RotateZ(float fAngDeg)
{
m_currMat = m_currMat * glm::mat4(::RotateZ(fAngDeg));
}

void Scale(const glm::vec3 &scaleVec)
{
glm::mat4 scaleMat(1.0f);
scaleMat[0].x = scaleVec.x;
scaleMat[1].y = scaleVec.y;
scaleMat[2].z = scaleVec.z;

m_currMat = m_currMat * scaleMat;
}

void Translate(const glm::vec3 &offsetVec)
{
glm::mat4 translateMat(1.0f);
translateMat[3] = glm::vec4(offsetVec, 1.0f);

m_currMat = m_currMat * translateMat;
}

void Push()
{
m_matrices.push(m_currMat);
}

void Pop()
{
m_currMat = m_matrices.top();
m_matrices.pop();
}

private:
glm::mat4 m_currMat;
std::stack<glm::mat4> m_matrices;
};

class Hierarchy
{
public:
Hierarchy()
: posBase(glm::vec3(3.0f, -5.0f, -40.0f))
, angBase(-45.0f)
, posBaseLeft(glm::vec3(2.0f, 0.0f, 0.0f))
, posBaseRight(glm::vec3(-2.0f, 0.0f, 0.0f))
, scaleBaseZ(3.0f)
, angUpperArm(-33.75f)
, sizeUpperArm(9.0f)
, posLowerArm(glm::vec3(0.0f, 0.0f, 8.0f))
, angLowerArm(146.25f)
, lenLowerArm(5.0f)
, widthLowerArm(1.5f)
, posWrist(glm::vec3(0.0f, 0.0f, 5.0f))
, angWristRoll(0.0f)
, angWristPitch(67.5f)
, lenWrist(2.0f)
, widthWrist(2.0f)
, posLeftFinger(glm::vec3(1.0f, 0.0f, 1.0f))
, posRightFinger(glm::vec3(-1.0f, 0.0f, 1.0f))
, angFingerOpen(180.0f)
, lenFinger(2.0f)
, widthFinger(0.5f)
, angLowerFinger(45.0f)
{}

void Draw()
{
MatrixStack modelToCameraStack;

// glBindVertexArray(vao);

modelToCameraStack.Translate(posBase);
modelToCameraStack.RotateY(angBase);

//Draw left base.
{
modelToCameraStack.Push();
modelToCameraStack.Translate(posBaseLeft);
modelToCameraStack.Scale(glm::vec3(1.0f, 1.0f, scaleBaseZ));
glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);
modelToCameraStack.Pop();
}

//Draw right base.
{
modelToCameraStack.Push();
modelToCameraStack.Translate(posBaseRight);
modelToCameraStack.Scale(glm::vec3(1.0f, 1.0f, scaleBaseZ));
glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);
modelToCameraStack.Pop();
}

//Draw main arm.
DrawUpperArm(modelToCameraStack);

// glBindVertexArray(0);
//glUseProgram(0);
}

#define STANDARD_ANGLE_INCREMENT 11.25f
#define SMALL_ANGLE_INCREMENT 9.0f

void AdjBase(bool bIncrement)
{
angBase += bIncrement ? STANDARD_ANGLE_INCREMENT : -STANDARD_ANGLE_INCREMENT;
angBase = fmodf(angBase, 360.0f);
}

void AdjUpperArm(bool bIncrement)
{
angUpperArm += bIncrement ? STANDARD_ANGLE_INCREMENT : -STANDARD_ANGLE_INCREMENT;
angUpperArm = Clamp(angUpperArm, -90.0f, 0.0f);
}

void AdjLowerArm(bool bIncrement)
{
angLowerArm += bIncrement ? STANDARD_ANGLE_INCREMENT : -STANDARD_ANGLE_INCREMENT;
angLowerArm = Clamp(angLowerArm, 0.0f, 146.25f);
}

void AdjWristPitch(bool bIncrement)
{
angWristPitch += bIncrement ? STANDARD_ANGLE_INCREMENT : -STANDARD_ANGLE_INCREMENT;
angWristPitch = Clamp(angWristPitch, 0.0f, 90.0f);
}

void AdjWristRoll(bool bIncrement)
{
angWristRoll += bIncrement ? STANDARD_ANGLE_INCREMENT : -STANDARD_ANGLE_INCREMENT;
angWristRoll = fmodf(angWristRoll, 360.0f);
}

void AdjFingerOpen(bool bIncrement)
{
angFingerOpen += bIncrement ? SMALL_ANGLE_INCREMENT : -SMALL_ANGLE_INCREMENT;
angFingerOpen = Clamp(angFingerOpen, 9.0f, 180.0f);
}

void WritePose()
{
printf("angBase:\t%f\n", angBase);
printf("angUpperArm:\t%f\n", angUpperArm);
printf("angLowerArm:\t%f\n", angLowerArm);
printf("angWristPitch:\t%f\n", angWristPitch);
printf("angWristRoll:\t%f\n", angWristRoll);
printf("angFingerOpen:\t%f\n", angFingerOpen);
printf("\n");
}

private:
void DrawFingers(MatrixStack &modelToCameraStack)
{
//Draw left finger
modelToCameraStack.Push();
modelToCameraStack.Translate(posLeftFinger);
modelToCameraStack.RotateY(angFingerOpen);

modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, lenFinger / 2.0f));
modelToCameraStack.Scale(glm::vec3(widthFinger / 2.0f, widthFinger/ 2.0f, lenFinger / 2.0f));
glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);
modelToCameraStack.Pop();

{
//Draw left lower finger
modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, lenFinger));
modelToCameraStack.RotateY(-angLowerFinger);

modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, lenFinger / 2.0f));
modelToCameraStack.Scale(glm::vec3(widthFinger / 2.0f, widthFinger/ 2.0f, lenFinger / 2.0f));
glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);
modelToCameraStack.Pop();

modelToCameraStack.Pop();
}

modelToCameraStack.Pop();

//Draw right finger
modelToCameraStack.Push();
modelToCameraStack.Translate(posRightFinger);
modelToCameraStack.RotateY(-angFingerOpen);

modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, lenFinger / 2.0f));
modelToCameraStack.Scale(glm::vec3(widthFinger / 2.0f, widthFinger/ 2.0f, lenFinger / 2.0f));
glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);
modelToCameraStack.Pop();

{
//Draw right lower finger
modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, lenFinger));
modelToCameraStack.RotateY(angLowerFinger);

modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, lenFinger / 2.0f));
modelToCameraStack.Scale(glm::vec3(widthFinger / 2.0f, widthFinger/ 2.0f, lenFinger / 2.0f));
glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);
modelToCameraStack.Pop();

modelToCameraStack.Pop();
}

modelToCameraStack.Pop();
}

void DrawWrist(MatrixStack &modelToCameraStack)
{
modelToCameraStack.Push();
modelToCameraStack.Translate(posWrist);
modelToCameraStack.RotateZ(angWristRoll);
modelToCameraStack.RotateX(angWristPitch);

modelToCameraStack.Push();
modelToCameraStack.Scale(glm::vec3(widthWrist / 2.0f, widthWrist/ 2.0f, lenWrist / 2.0f));
glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);
modelToCameraStack.Pop();

DrawFingers(modelToCameraStack);

modelToCameraStack.Pop();
}

void DrawLowerArm(MatrixStack &modelToCameraStack)
{
modelToCameraStack.Push();
modelToCameraStack.Translate(posLowerArm);
modelToCameraStack.RotateX(angLowerArm);

modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, lenLowerArm / 2.0f));
modelToCameraStack.Scale(glm::vec3(widthLowerArm / 2.0f, widthLowerArm / 2.0f, lenLowerArm / 2.0f));
glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);
modelToCameraStack.Pop();

DrawWrist(modelToCameraStack);

modelToCameraStack.Pop();
}

void DrawUpperArm(MatrixStack &modelToCameraStack)
{
modelToCameraStack.Push();
modelToCameraStack.RotateX(angUpperArm);

{
modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, (sizeUpperArm / 2.0f) - 1.0f));
modelToCameraStack.Scale(glm::vec3(1.0f, 1.0f, sizeUpperArm / 2.0f));
glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);
modelToCameraStack.Pop();
}

DrawLowerArm(modelToCameraStack);

modelToCameraStack.Pop();
}

glm::vec3 posBase;
float angBase;

glm::vec3 posBaseLeft, posBaseRight;
float scaleBaseZ;

float angUpperArm;
float sizeUpperArm;

glm::vec3 posLowerArm;
float angLowerArm;
float lenLowerArm;
float widthLowerArm;

glm::vec3 posWrist;
float angWristRoll;
float angWristPitch;
float lenWrist;
float widthWrist;

glm::vec3 posLeftFinger, posRightFinger;
float angFingerOpen;
float lenFinger;
float widthFinger;
float angLowerFinger;
};


Hierarchy g_armature;

//Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
void
OnInit( void )
{
glGenBuffers(1, &vertexBufferObject);

glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);

glGenBuffers(1, &indexBufferObject);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexData), indexData, GL_STATIC_DRAW);

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

size_t colorDataOffset = sizeof(float) * 3 * numberOfVertices;
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glEnableVertexAttribArray(positionAttrib);
glEnableVertexAttribArray(colorAttrib);
glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);

// Load shaders and use the resulting shader program
GLuint program = InitShader( "vshader07_1.glsl", "fshader07_1.glsl" );
positionAttrib = glGetAttribLocation(program, "position");
colorAttrib = glGetAttribLocation(program, "color");

modelToCameraMatrixUnif = glGetUniformLocation(program, "modelToCameraMatrix");
cameraToClipMatrixUnif = glGetUniformLocation(program, "cameraToClipMatrix");

float fzNear = 1.0f; float fzFar = 100.0f;

cameraToClipMatrix[0].x = fFrustumScale;
cameraToClipMatrix[1].y = fFrustumScale;
cameraToClipMatrix[2].z = (fzFar + fzNear) / (fzNear - fzFar);
cameraToClipMatrix[2].w = -1.0f;
cameraToClipMatrix[3].z = (2 * fzFar * fzNear) / (fzNear - fzFar);

glUniformMatrix4fv(cameraToClipMatrixUnif, 1, GL_FALSE, glm::value_ptr(cameraToClipMatrix));
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CW);

glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL);
glDepthRange(0.0f, 1.0f);
}
void OnShutdown() {
cout<<"Shutdown successfull"<<endl;
}
void OnResize(int nw, int nh) {
cameraToClipMatrix[0].x = fFrustumScale * (nh / (float)nw);
cameraToClipMatrix[1].y = fFrustumScale;

glUniformMatrix4fv(cameraToClipMatrixUnif, 1, GL_FALSE, glm::value_ptr(cameraToClipMatrix));

glViewport(0, 0, (GLsizei) nw, (GLsizei) nh);
}
void OnRender() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

g_armature.Draw();

glutSwapBuffers();
glutPostRedisplay();
}

//----------------------------------------------------------------------------

void
keyboard( unsigned char key, int x, int y )
{
static bool bDepthClampingActive = false;
switch (key)
{
case 27:
glutLeaveMainLoop();
return;
case 'a': g_armature.AdjBase(true); break;
case 'd': g_armature.AdjBase(false); break;
case 'w': g_armature.AdjUpperArm(false); break;
case 's': g_armature.AdjUpperArm(true); break;
case 'r': g_armature.AdjLowerArm(false); break;
case 'f': g_armature.AdjLowerArm(true); break;
case 't': g_armature.AdjWristPitch(false); break;
case 'g': g_armature.AdjWristPitch(true); break;
case 'z': g_armature.AdjWristRoll(true); break;
case 'c': g_armature.AdjWristRoll(false); break;
case 'q': g_armature.AdjFingerOpen(true); break;
case 'e': g_armature.AdjFingerOpen(false); break;
case 32: g_armature.WritePose(); break;
}
}

//----------------------------------------------------------------------------

int
main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE |
GLUT_RGBA);
glutInitContextVersion (3, 3);
glutInitContextFlags (GLUT_CORE_PROFILE | GLUT_DEBUG);
glutInitContextProfile(GLUT_FORWARD_COMPATIBLE);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("Getting started Drawing A Triangle");
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err){
cerr<<"Error: "<<glewGetErrorString(err)<<endl;
} else {
if (GLEW_VERSION_3_3)
{
cout<<"Driver supports OpenGL 3.3\nDetails:"<<endl;
}
}
OnInit();
glutCloseFunc(OnShutdown);
glutDisplayFunc(OnRender);
glutReshapeFunc(OnResize);
glutKeyboardFunc( keyboard );
glutMainLoop();
return 0;
}

sueyllam
09-29-2014, 10:26 PM
Well, printing the 2 vertices (-1,-1,-1,1) and (+1,+1,+1,1) by the matrices in the code and printing out the results after dividing by W, it does not seem that clipping
happens at all, everything is within NDC [-1,1]^3.
So it is really brcoming more obscure what the problem is? Any clues what possibly can go wrong to get a window with just black background?

1456

sueyllam
09-29-2014, 11:26 PM
Well to make things worse, I rewrote the code using good old deprecated GL2 and I got the robot displayed. Everything is the same except changing drawElements to Begin End with a loop inside to display vertices of TRIANGLES.

Here is the GL 2 code working:




#include <iostream>
#include <vector>
#include <stack>
#include <GL/freeglut.h>
#include <stdio.h>

#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>

using namespace std;

const int WIDTH = 600;
const int HEIGHT = 600;

// Define a helpful macro for handling offsets into buffer objects
#define BUFFER_OFFSET( offset ) ((GLvoid*) (offset))
#define ARRAY_COUNT(array) (sizeof(array)/sizeof(array[0]))

GLuint modelToCameraMatrixUnif;
GLuint cameraToClipMatrixUnif;

glm::mat4 cameraToClipMatrix(0.0f);

float CalcFrustumScale(float fFovDeg)
{
const float degToRad = 3.14159f * 2.0f / 360.0f;
float fFovRad = fFovDeg * degToRad;
return 1.0f / tan(fFovRad / 2.0f);
}

const float fFrustumScale = CalcFrustumScale(45.0f);

const int numberOfVertices = 24;

#define RED_COLOR 1.0f, 0.0f, 0.0f, 1.0f
#define GREEN_COLOR 0.0f, 1.0f, 0.0f, 1.0f
#define BLUE_COLOR 0.0f, 0.0f, 1.0f, 1.0f

#define YELLOW_COLOR 1.0f, 1.0f, 0.0f, 1.0f
#define CYAN_COLOR 0.0f, 1.0f, 1.0f, 1.0f
#define MAGENTA_COLOR 1.0f, 0.0f, 1.0f, 1.0f

const float vertexData[] =
{
//Front
+1.0f, +1.0f, +1.0f,
+1.0f, -1.0f, +1.0f,
-1.0f, -1.0f, +1.0f,
-1.0f, +1.0f, +1.0f,

//Top
+1.0f, +1.0f, +1.0f,
-1.0f, +1.0f, +1.0f,
-1.0f, +1.0f, -1.0f,
+1.0f, +1.0f, -1.0f,

//Left
+1.0f, +1.0f, +1.0f,
+1.0f, +1.0f, -1.0f,
+1.0f, -1.0f, -1.0f,
+1.0f, -1.0f, +1.0f,

//Back
+1.0f, +1.0f, -1.0f,
-1.0f, +1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
+1.0f, -1.0f, -1.0f,

//Bottom
+1.0f, -1.0f, +1.0f,
+1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, +1.0f,

//Right
-1.0f, +1.0f, +1.0f,
-1.0f, -1.0f, +1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, +1.0f, -1.0f,


GREEN_COLOR,
GREEN_COLOR,
GREEN_COLOR,
GREEN_COLOR,

BLUE_COLOR,
BLUE_COLOR,
BLUE_COLOR,
BLUE_COLOR,

RED_COLOR,
RED_COLOR,
RED_COLOR,
RED_COLOR,

YELLOW_COLOR,
YELLOW_COLOR,
YELLOW_COLOR,
YELLOW_COLOR,

CYAN_COLOR,
CYAN_COLOR,
CYAN_COLOR,
CYAN_COLOR,

MAGENTA_COLOR,
MAGENTA_COLOR,
MAGENTA_COLOR,
MAGENTA_COLOR,
};

const GLshort indexData[] =
{
0, 1, 2,
2, 3, 0,

4, 5, 6,
6, 7, 4,

8, 9, 10,
10, 11, 8,

12, 13, 14,
14, 15, 12,

16, 17, 18,
18, 19, 16,

20, 21, 22,
22, 23, 20,
};

inline float DegToRad(float fAngDeg)
{
const float fDegToRad = 3.14159f * 2.0f / 360.0f;
return fAngDeg * fDegToRad;
}

inline float Clamp(float fValue, float fMinValue, float fMaxValue)
{
if(fValue < fMinValue)
return fMinValue;

if(fValue > fMaxValue)
return fMaxValue;

return fValue;
}

glm::mat3 RotateX(float fAngDeg)
{
float fAngRad = DegToRad(fAngDeg);
float fCos = cosf(fAngRad);
float fSin = sinf(fAngRad);

glm::mat3 theMat(1.0f);
theMat[1].y = fCos; theMat[2].y = -fSin;
theMat[1].z = fSin; theMat[2].z = fCos;
return theMat;
}

glm::mat3 RotateY(float fAngDeg)
{
float fAngRad = DegToRad(fAngDeg);
float fCos = cosf(fAngRad);
float fSin = sinf(fAngRad);

glm::mat3 theMat(1.0f);
theMat[0].x = fCos; theMat[2].x = fSin;
theMat[0].z = -fSin; theMat[2].z = fCos;
return theMat;
}

glm::mat3 RotateZ(float fAngDeg)
{
float fAngRad = DegToRad(fAngDeg);
float fCos = cosf(fAngRad);
float fSin = sinf(fAngRad);

glm::mat3 theMat(1.0f);
theMat[0].x = fCos; theMat[1].x = -fSin;
theMat[0].y = fSin; theMat[1].y = fCos;
return theMat;
}

class MatrixStack
{
public:
MatrixStack()
: m_currMat(1.0f)
{
}

const glm::mat4 &Top()
{
return m_currMat;
}

void RotateX(float fAngDeg)
{
m_currMat = m_currMat * glm::mat4(::RotateX(fAngDeg));
}

void RotateY(float fAngDeg)
{
m_currMat = m_currMat * glm::mat4(::RotateY(fAngDeg));
}

void RotateZ(float fAngDeg)
{
m_currMat = m_currMat * glm::mat4(::RotateZ(fAngDeg));
}

void Scale(const glm::vec3 &scaleVec)
{
glm::mat4 scaleMat(1.0f);
scaleMat[0].x = scaleVec.x;
scaleMat[1].y = scaleVec.y;
scaleMat[2].z = scaleVec.z;

m_currMat = m_currMat * scaleMat;
}

void Translate(const glm::vec3 &offsetVec)
{
glm::mat4 translateMat(1.0f);
translateMat[3] = glm::vec4(offsetVec, 1.0f);

m_currMat = m_currMat * translateMat;
}

void Push()
{
m_matrices.push(m_currMat);
}

void Pop()
{
m_currMat = m_matrices.top();
m_matrices.pop();
}

private:
glm::mat4 m_currMat;
std::stack<glm::mat4> m_matrices;
};

class Hierarchy
{
public:
Hierarchy()
: posBase(glm::vec3(3.0f, -5.0f, -40.0f))
, angBase(-45.0f)
, posBaseLeft(glm::vec3(2.0f, 0.0f, 0.0f))
, posBaseRight(glm::vec3(-2.0f, 0.0f, 0.0f))
, scaleBaseZ(3.0f)
, angUpperArm(-33.75f)
, sizeUpperArm(9.0f)
, posLowerArm(glm::vec3(0.0f, 0.0f, 8.0f))
, angLowerArm(146.25f)
, lenLowerArm(5.0f)
, widthLowerArm(1.5f)
, posWrist(glm::vec3(0.0f, 0.0f, 5.0f))
, angWristRoll(0.0f)
, angWristPitch(67.5f)
, lenWrist(2.0f)
, widthWrist(2.0f)
, posLeftFinger(glm::vec3(1.0f, 0.0f, 1.0f))
, posRightFinger(glm::vec3(-1.0f, 0.0f, 1.0f))
, angFingerOpen(180.0f)
, lenFinger(2.0f)
, widthFinger(0.5f)
, angLowerFinger(45.0f)
{}

void Draw()
{
MatrixStack modelToCameraStack;


modelToCameraStack.Translate(posBase);
modelToCameraStack.RotateY(angBase);

//Draw left base.
{
modelToCameraStack.Push();
modelToCameraStack.Translate(posBaseLeft);
modelToCameraStack.Scale(glm::vec3(1.0f, 1.0f, scaleBaseZ));
// glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
// glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);

glBegin(GL_TRIANGLES);
for (int i=0; i<ARRAY_COUNT(indexData); i++) {
glColor3f(vertexData[3*24+indexData[i]*4], vertexData[3*24+indexData[i]*4+1], vertexData[3*24+indexData[i]*2]);
glm::vec4 temp = glm::vec4(vertexData[indexData[i]*3], vertexData[indexData[i]*3+1], vertexData[indexData[i]*3+2], 1.0);
glm::vec4 tempc = modelToCameraStack.Top() * temp;
glm::vec4 tempn = cameraToClipMatrix * tempc;
glVertex3f(tempn[0]/tempn[3], tempn[1]/tempn[3], tempn[2]/tempn[3]);
}
glEnd();
modelToCameraStack.Pop();
}

//Draw right base.
{
modelToCameraStack.Push();
modelToCameraStack.Translate(posBaseRight);
modelToCameraStack.Scale(glm::vec3(1.0f, 1.0f, scaleBaseZ));
// glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
// glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);

glBegin(GL_TRIANGLES);
for (int i=0; i<ARRAY_COUNT(indexData); i++) {
glColor3f(vertexData[3*24+indexData[i]*4], vertexData[3*24+indexData[i]*4+1], vertexData[3*24+indexData[i]*2]);
glm::vec4 temp = glm::vec4(vertexData[indexData[i]*3], vertexData[indexData[i]*3+1], vertexData[indexData[i]*3+2], 1.0);
glm::vec4 tempc = modelToCameraStack.Top() * temp;
glm::vec4 tempn = cameraToClipMatrix * tempc;
glVertex3f(tempn[0]/tempn[3], tempn[1]/tempn[3], tempn[2]/tempn[3]);
}
glEnd();

modelToCameraStack.Pop();
}

//Draw main arm.
DrawUpperArm(modelToCameraStack);

// glBindVertexArray(0);
//glUseProgram(0);
}

#define STANDARD_ANGLE_INCREMENT 11.25f
#define SMALL_ANGLE_INCREMENT 9.0f

void AdjBase(bool bIncrement)
{
angBase += bIncrement ? STANDARD_ANGLE_INCREMENT : -STANDARD_ANGLE_INCREMENT;
angBase = fmodf(angBase, 360.0f);
}

void AdjUpperArm(bool bIncrement)
{
angUpperArm += bIncrement ? STANDARD_ANGLE_INCREMENT : -STANDARD_ANGLE_INCREMENT;
angUpperArm = Clamp(angUpperArm, -90.0f, 0.0f);
}

void AdjLowerArm(bool bIncrement)
{
angLowerArm += bIncrement ? STANDARD_ANGLE_INCREMENT : -STANDARD_ANGLE_INCREMENT;
angLowerArm = Clamp(angLowerArm, 0.0f, 146.25f);
}

void AdjWristPitch(bool bIncrement)
{
angWristPitch += bIncrement ? STANDARD_ANGLE_INCREMENT : -STANDARD_ANGLE_INCREMENT;
angWristPitch = Clamp(angWristPitch, 0.0f, 90.0f);
}

void AdjWristRoll(bool bIncrement)
{
angWristRoll += bIncrement ? STANDARD_ANGLE_INCREMENT : -STANDARD_ANGLE_INCREMENT;
angWristRoll = fmodf(angWristRoll, 360.0f);
}

void AdjFingerOpen(bool bIncrement)
{
angFingerOpen += bIncrement ? SMALL_ANGLE_INCREMENT : -SMALL_ANGLE_INCREMENT;
angFingerOpen = Clamp(angFingerOpen, 9.0f, 180.0f);
}

void WritePose()
{
printf("angBase:\t%f\n", angBase);
printf("angUpperArm:\t%f\n", angUpperArm);
printf("angLowerArm:\t%f\n", angLowerArm);
printf("angWristPitch:\t%f\n", angWristPitch);
printf("angWristRoll:\t%f\n", angWristRoll);
printf("angFingerOpen:\t%f\n", angFingerOpen);
printf("\n");
}

private:
void DrawFingers(MatrixStack &modelToCameraStack)
{
//Draw left finger
modelToCameraStack.Push();
modelToCameraStack.Translate(posLeftFinger);
modelToCameraStack.RotateY(angFingerOpen);

modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, lenFinger / 2.0f));
modelToCameraStack.Scale(glm::vec3(widthFinger / 2.0f, widthFinger/ 2.0f, lenFinger / 2.0f));
// glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
// glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);

glBegin(GL_TRIANGLES);
for (int i=0; i<ARRAY_COUNT(indexData); i++) {
glColor3f(vertexData[3*24+indexData[i]*4], vertexData[3*24+indexData[i]*4+1], vertexData[3*24+indexData[i]*2]);
glm::vec4 temp = glm::vec4(vertexData[indexData[i]*3], vertexData[indexData[i]*3+1], vertexData[indexData[i]*3+2], 1.0);
glm::vec4 tempc = modelToCameraStack.Top() * temp;
glm::vec4 tempn = cameraToClipMatrix * tempc;
glVertex3f(tempn[0]/tempn[3], tempn[1]/tempn[3], tempn[2]/tempn[3]);
}
glEnd();

modelToCameraStack.Pop();

{
//Draw left lower finger
modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, lenFinger));
modelToCameraStack.RotateY(-angLowerFinger);

modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, lenFinger / 2.0f));
modelToCameraStack.Scale(glm::vec3(widthFinger / 2.0f, widthFinger/ 2.0f, lenFinger / 2.0f));
// glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
// glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);

glBegin(GL_TRIANGLES);
for (int i=0; i<ARRAY_COUNT(indexData); i++) {
glColor3f(vertexData[3*24+indexData[i]*4], vertexData[3*24+indexData[i]*4+1], vertexData[3*24+indexData[i]*2]);
glm::vec4 temp = glm::vec4(vertexData[indexData[i]*3], vertexData[indexData[i]*3+1], vertexData[indexData[i]*3+2], 1.0);
glm::vec4 tempc = modelToCameraStack.Top() * temp;
glm::vec4 tempn = cameraToClipMatrix * tempc;
glVertex3f(tempn[0]/tempn[3], tempn[1]/tempn[3], tempn[2]/tempn[3]);
}
glEnd();

modelToCameraStack.Pop();

modelToCameraStack.Pop();
}

modelToCameraStack.Pop();

//Draw right finger
modelToCameraStack.Push();
modelToCameraStack.Translate(posRightFinger);
modelToCameraStack.RotateY(-angFingerOpen);

modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, lenFinger / 2.0f));
modelToCameraStack.Scale(glm::vec3(widthFinger / 2.0f, widthFinger/ 2.0f, lenFinger / 2.0f));
// glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
// glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);

glBegin(GL_TRIANGLES);
for (int i=0; i<ARRAY_COUNT(indexData); i++) {
glColor3f(vertexData[3*24+indexData[i]*4], vertexData[3*24+indexData[i]*4+1], vertexData[3*24+indexData[i]*2]);
glm::vec4 temp = glm::vec4(vertexData[indexData[i]*3], vertexData[indexData[i]*3+1], vertexData[indexData[i]*3+2], 1.0);
glm::vec4 tempc = modelToCameraStack.Top() * temp;
glm::vec4 tempn = cameraToClipMatrix * tempc;
glVertex3f(tempn[0]/tempn[3], tempn[1]/tempn[3], tempn[2]/tempn[3]);
}
glEnd();

modelToCameraStack.Pop();

{
//Draw right lower finger
modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, lenFinger));
modelToCameraStack.RotateY(angLowerFinger);

modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, lenFinger / 2.0f));
modelToCameraStack.Scale(glm::vec3(widthFinger / 2.0f, widthFinger/ 2.0f, lenFinger / 2.0f));
// glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
// glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);

glBegin(GL_TRIANGLES);
for (int i=0; i<ARRAY_COUNT(indexData); i++) {
glColor3f(vertexData[3*24+indexData[i]*4], vertexData[3*24+indexData[i]*4+1], vertexData[3*24+indexData[i]*2]);
glm::vec4 temp = glm::vec4(vertexData[indexData[i]*3], vertexData[indexData[i]*3+1], vertexData[indexData[i]*3+2], 1.0);
glm::vec4 tempc = modelToCameraStack.Top() * temp;
glm::vec4 tempn = cameraToClipMatrix * tempc;
glVertex3f(tempn[0]/tempn[3], tempn[1]/tempn[3], tempn[2]/tempn[3]);
}
glEnd();

modelToCameraStack.Pop();

modelToCameraStack.Pop();
}

modelToCameraStack.Pop();
}

void DrawWrist(MatrixStack &modelToCameraStack)
{
modelToCameraStack.Push();
modelToCameraStack.Translate(posWrist);
modelToCameraStack.RotateZ(angWristRoll);
modelToCameraStack.RotateX(angWristPitch);

modelToCameraStack.Push();
modelToCameraStack.Scale(glm::vec3(widthWrist / 2.0f, widthWrist/ 2.0f, lenWrist / 2.0f));
// glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
// glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);

glBegin(GL_TRIANGLES);
for (int i=0; i<ARRAY_COUNT(indexData); i++) {
glColor3f(vertexData[3*24+indexData[i]*4], vertexData[3*24+indexData[i]*4+1], vertexData[3*24+indexData[i]*2]);
glm::vec4 temp = glm::vec4(vertexData[indexData[i]*3], vertexData[indexData[i]*3+1], vertexData[indexData[i]*3+2], 1.0);
glm::vec4 tempc = modelToCameraStack.Top() * temp;
glm::vec4 tempn = cameraToClipMatrix * tempc;
glVertex3f(tempn[0]/tempn[3], tempn[1]/tempn[3], tempn[2]/tempn[3]);
}
glEnd();

modelToCameraStack.Pop();

DrawFingers(modelToCameraStack);

modelToCameraStack.Pop();
}

void DrawLowerArm(MatrixStack &modelToCameraStack)
{
modelToCameraStack.Push();
modelToCameraStack.Translate(posLowerArm);
modelToCameraStack.RotateX(angLowerArm);

modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, lenLowerArm / 2.0f));
modelToCameraStack.Scale(glm::vec3(widthLowerArm / 2.0f, widthLowerArm / 2.0f, lenLowerArm / 2.0f));
// glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
// glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);

glBegin(GL_TRIANGLES);
for (int i=0; i<ARRAY_COUNT(indexData); i++) {
glColor3f(vertexData[3*24+indexData[i]*4], vertexData[3*24+indexData[i]*4+1], vertexData[3*24+indexData[i]*2]);
glm::vec4 temp = glm::vec4(vertexData[indexData[i]*3], vertexData[indexData[i]*3+1], vertexData[indexData[i]*3+2], 1.0);
glm::vec4 tempc = modelToCameraStack.Top() * temp;
glm::vec4 tempn = cameraToClipMatrix * tempc;
glVertex3f(tempn[0]/tempn[3], tempn[1]/tempn[3], tempn[2]/tempn[3]);
}
glEnd();

modelToCameraStack.Pop();

DrawWrist(modelToCameraStack);

modelToCameraStack.Pop();
}

void DrawUpperArm(MatrixStack &modelToCameraStack)
{
modelToCameraStack.Push();
modelToCameraStack.RotateX(angUpperArm);

{
modelToCameraStack.Push();
modelToCameraStack.Translate(glm::vec3(0.0f, 0.0f, (sizeUpperArm / 2.0f) - 1.0f));
modelToCameraStack.Scale(glm::vec3(1.0f, 1.0f, sizeUpperArm / 2.0f));
// glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelToCameraStack.Top()));
// glDrawElements(GL_TRIANGLES, ARRAY_COUNT(indexData), GL_UNSIGNED_SHORT, 0);

glBegin(GL_TRIANGLES);
for (int i=0; i<ARRAY_COUNT(indexData); i++) {
glColor3f(vertexData[3*24+indexData[i]*4], vertexData[3*24+indexData[i]*4+1], vertexData[3*24+indexData[i]*2]);
glm::vec4 temp = glm::vec4(vertexData[indexData[i]*3], vertexData[indexData[i]*3+1], vertexData[indexData[i]*3+2], 1.0);
glm::vec4 tempc = modelToCameraStack.Top() * temp;
glm::vec4 tempn = cameraToClipMatrix * tempc;
glVertex3f(tempn[0]/tempn[3], tempn[1]/tempn[3], tempn[2]/tempn[3]);
}
glEnd();

modelToCameraStack.Pop();
}

DrawLowerArm(modelToCameraStack);

modelToCameraStack.Pop();
}

glm::vec3 posBase;
float angBase;

glm::vec3 posBaseLeft, posBaseRight;
float scaleBaseZ;

float angUpperArm;
float sizeUpperArm;

glm::vec3 posLowerArm;
float angLowerArm;
float lenLowerArm;
float widthLowerArm;

glm::vec3 posWrist;
float angWristRoll;
float angWristPitch;
float lenWrist;
float widthWrist;

glm::vec3 posLeftFinger, posRightFinger;
float angFingerOpen;
float lenFinger;
float widthFinger;
float angLowerFinger;
};


Hierarchy g_armature;

//Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
void
OnInit( void )
{
float fzNear = 1.0f; float fzFar = 100.0f;

cameraToClipMatrix[0].x = fFrustumScale;
cameraToClipMatrix[1].y = fFrustumScale;
cameraToClipMatrix[2].z = (fzFar + fzNear) / (fzNear - fzFar);
cameraToClipMatrix[2].w = -1.0f;
cameraToClipMatrix[3].z = (2 * fzFar * fzNear) / (fzNear - fzFar);

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CW);

glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL);
glDepthRange(0.0f, 1.0f);
}
void OnShutdown() {
cout<<"Shutdown successfull"<<endl;
}
void OnResize(int nw, int nh) {
cameraToClipMatrix[0].x = fFrustumScale * (nh / (float)nw);
cameraToClipMatrix[1].y = fFrustumScale;

glViewport(0, 0, (GLsizei) nw, (GLsizei) nh);
}
void OnRender() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

g_armature.Draw();

glutSwapBuffers();
glutPostRedisplay();
}

//----------------------------------------------------------------------------

void
keyboard( unsigned char key, int x, int y )
{
switch (key)
{
case 27:
glutLeaveMainLoop();
return;
case 'a': g_armature.AdjBase(true); break;
case 'd': g_armature.AdjBase(false); break;
case 'w': g_armature.AdjUpperArm(false); break;
case 's': g_armature.AdjUpperArm(true); break;
case 'r': g_armature.AdjLowerArm(false); break;
case 'f': g_armature.AdjLowerArm(true); break;
case 't': g_armature.AdjWristPitch(false); break;
case 'g': g_armature.AdjWristPitch(true); break;
case 'z': g_armature.AdjWristRoll(true); break;
case 'c': g_armature.AdjWristRoll(false); break;
case 'q': g_armature.AdjFingerOpen(true); break;
case 'e': g_armature.AdjFingerOpen(false); break;
case 32: g_armature.WritePose(); break;
}
}

//----------------------------------------------------------------------------

int
main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE |
GLUT_RGBA);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("Getting started Drawing A Triangle");
OnInit();
glutCloseFunc(OnShutdown);
glutDisplayFunc(OnRender);
glutReshapeFunc(OnResize);
glutKeyboardFunc( keyboard );
glutMainLoop();
return 0;
}



and I got the robot as;

1457

Now that I am more confused, I think I should suspect the shaders, but they are simple, here they are in case anyone can find something wrong with them:




#version 330

layout(location = 0) in vec4 position;
layout(location = 1) in vec4 color;

smooth out vec4 theColor;

uniform mat4 cameraToClipMatrix;
uniform mat4 modelToCameraMatrix;

void main()
{
vec4 cameraPos = modelToCameraMatrix * position;
gl_Position = cameraToClipMatrix * cameraPos;
theColor = color;
}



and the fragment shader:




#version 330

smooth in vec4 theColor;

out vec4 outputColor;

void main()
{
outputColor = theColor;
}

sueyllam
10-02-2014, 03:25 AM
I finally found the bug, it was stupid, in the OnInit function the following chunk of cod

size_t colorDataOffset = sizeof(float) * 3 * numberOfVertices;
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glEnableVertexAttribArray(positionAttrib);
glEnableVertexAttribArray(colorAttrib);
glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);

should move after The Calls to InitShader and glGetAttribLocation.
I admit it was stupid from my part, but it is also stupid from the part of openGL, the calls to glVertexAttribPointer with uninitialized values should fail too. It made it very difficult to locate by just getting the balck screen