@@ -2,7 +2,7 @@ CC=g++ | |||
FLAGS=-Wall -g | |||
INCLUDE=-I. | |||
LIBS=-lassimp | |||
LIBS=-lGL -lglut -lGLU -lGLEW -lassimp | |||
TARGET=IN55.exe | |||
@@ -17,7 +17,7 @@ OBJECTS=$(SOURCES:.cpp=.o) | |||
$(TARGET): $(OBJECTS) *.h | |||
@echo "Builing the whole project" | |||
$(CC) $(OBJECTS) -lGL -lglut -lGLU $(LIBS) -o $(TARGET) | |||
$(CC) $(OBJECTS) $(LIBS) -o $(TARGET) | |||
%.o: %.cpp | |||
@echo "Compiling .cpp files" |
@@ -4,6 +4,10 @@ | |||
* Beerware licensed software - 2015 | |||
*/ | |||
#include <iostream> | |||
#include <fstream> | |||
#include <string> | |||
#include <list> | |||
#include <GL/glew.h> | |||
#include <GL/glut.h> | |||
#include <GL/gl.h> | |||
@@ -15,6 +19,10 @@ SceneHandler scene; | |||
Camera c; | |||
std::list<GLuint> shaderList; | |||
GLuint shaderProg; | |||
float d_angle_x =0.0f; | |||
float d_angle_y =0.0f; | |||
@@ -24,6 +32,56 @@ int yorigin = 0; | |||
bool is_l_clicked = false; | |||
bool is_r_clicked = false; | |||
bool AddShader(GLenum ShaderType, const char* pFilename) | |||
{ | |||
std::string s; | |||
std::ifstream f(pFilename); | |||
if (f.is_open()) { | |||
std::string line; | |||
while (getline(f, line)) { | |||
s.append(line); | |||
s.append("\n"); | |||
} | |||
f.close(); | |||
} else { | |||
std::cerr << "Error reading file " << pFilename << "\n"; | |||
return false; | |||
} | |||
GLuint ShaderObj = glCreateShader(ShaderType); | |||
if (ShaderObj == 0) { | |||
std::cerr << "Error creating shader type " << ShaderType << "\n"; | |||
return false; | |||
} | |||
// Save the shader object - will be deleted in the destructor | |||
shaderList.push_back(ShaderObj); | |||
const GLchar* p[1]; | |||
p[0] = s.c_str(); | |||
GLint Lengths[1] = { (GLint)s.size() }; | |||
glShaderSource(ShaderObj, 1, p, Lengths); | |||
glCompileShader(ShaderObj); | |||
GLint success; | |||
glGetShaderiv(ShaderObj, GL_COMPILE_STATUS, &success); | |||
if (!success) { | |||
GLchar InfoLog[1024]; | |||
glGetShaderInfoLog(ShaderObj, 1024, NULL, InfoLog); | |||
std::cerr << "Error compiling '" << pFilename << "': '" << InfoLog << "'\n"; | |||
return false; | |||
} | |||
glAttachShader(shaderProg, ShaderObj); | |||
return true; | |||
} | |||
/* Initialize OpenGL */ | |||
void initGL() { | |||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque | |||
@@ -32,8 +90,8 @@ void initGL() { | |||
glEnable(GL_LIGHT0); // Uses default lighting parameters | |||
glEnable(GL_CULL_FACE); | |||
glEnable(GL_DEPTH_TEST); // Enable depth testing | |||
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); | |||
glEnable(GL_NORMALIZE); | |||
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); | |||
glEnable(GL_NORMALIZE); | |||
glDepthFunc(GL_LEQUAL); // Set the type of depth-test | |||
glShadeModel(GL_SMOOTH); // Enable smooth shading | |||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Nice perspective corrections | |||
@@ -94,59 +152,59 @@ void keyInput(unsigned char key, int x, int y){ | |||
void specialInput(int key, int x, int y){ | |||
Vec3 newPos; | |||
switch(key){ | |||
case GLUT_KEY_UP : | |||
newPos = c.getPos(); | |||
newPos.y+=0.1; | |||
c.setPos(newPos);break; | |||
case GLUT_KEY_UP : | |||
newPos = c.getPos(); | |||
newPos.y+=0.1; | |||
c.setPos(newPos);break; | |||
case GLUT_KEY_DOWN : | |||
newPos = c.getPos(); | |||
newPos.y-=0.1; | |||
c.setPos(newPos);break; | |||
case GLUT_KEY_RIGHT : | |||
newPos = c.getPos(); | |||
newPos.x+=0.1; | |||
c.setPos(newPos);break; | |||
newPos = c.getPos(); | |||
newPos.y-=0.1; | |||
c.setPos(newPos);break; | |||
case GLUT_KEY_RIGHT : | |||
newPos = c.getPos(); | |||
newPos.x+=0.1; | |||
c.setPos(newPos);break; | |||
case GLUT_KEY_LEFT : | |||
newPos = c.getPos(); | |||
newPos.x-=0.1; | |||
c.setPos(newPos);break; | |||
newPos = c.getPos(); | |||
newPos.x-=0.1; | |||
c.setPos(newPos);break; | |||
default : break; | |||
} | |||
} | |||
/* Manage mouse input */ | |||
/* Manage mouse input */ | |||
void mouseInput(int button, int state, int x, int y){ | |||
Vec3 newPos; | |||
switch(button){ | |||
case GLUT_LEFT_BUTTON : | |||
if(state==GLUT_UP){ | |||
is_l_clicked=false; | |||
}else if(state == GLUT_DOWN){ | |||
is_l_clicked=true; | |||
xorigin=x; | |||
} | |||
break; | |||
case GLUT_RIGHT_BUTTON : | |||
if(state==GLUT_UP){ | |||
is_r_clicked=false; | |||
}else if(state == GLUT_DOWN){ | |||
is_r_clicked=true; | |||
yorigin=y; | |||
} | |||
break; | |||
case GLUT_LEFT_BUTTON : | |||
if(state==GLUT_UP){ | |||
is_l_clicked=false; | |||
}else if(state == GLUT_DOWN){ | |||
is_l_clicked=true; | |||
xorigin=x; | |||
} | |||
break; | |||
case GLUT_RIGHT_BUTTON : | |||
if(state==GLUT_UP){ | |||
is_r_clicked=false; | |||
}else if(state == GLUT_DOWN){ | |||
is_r_clicked=true; | |||
yorigin=y; | |||
} | |||
break; | |||
case 3 : | |||
newPos = c.getPos(); | |||
newPos.z-=0.1; | |||
c.setPos(newPos);break; | |||
newPos = c.getPos(); | |||
newPos.z-=0.1; | |||
c.setPos(newPos);break; | |||
case 4 : | |||
newPos = c.getPos(); | |||
newPos.z+=0.1; | |||
c.setPos(newPos);break; | |||
newPos = c.getPos(); | |||
newPos.z+=0.1; | |||
c.setPos(newPos);break; | |||
default : break; | |||
} | |||
} | |||
/* Manage mouse move */ | |||
/* Manage mouse move */ | |||
void mouseMoveInput(int x, int y){ | |||
Vec3 newOri; | |||
if(is_l_clicked){ | |||
@@ -186,6 +244,7 @@ int main(int argc, char** argv) | |||
glutInitWindowSize(640, 480); | |||
glutInitWindowPosition(50, 50); | |||
glutCreateWindow("IN55 - Animation rendering"); | |||
glewInit(); | |||
glutKeyboardFunc(keyInput); | |||
glutSpecialFunc(specialInput); | |||
glutMouseFunc(mouseInput); | |||
@@ -194,6 +253,15 @@ int main(int argc, char** argv) | |||
glutReshapeFunc(reshape); | |||
initGL(); | |||
glutTimerFunc(0, timer, 0); | |||
std::cout << "GUY\n\n\n"; | |||
shaderProg = glCreateProgram(); | |||
if (shaderProg == 0) { | |||
std::cerr << "Error creating shader program\n"; | |||
return 1; | |||
} | |||
if (!AddShader(GL_VERTEX_SHADER, "shader.vs")) { | |||
AddShader(GL_VERTEX_SHADER, "shader_legacy.vs"); | |||
} | |||
glutMainLoop(); | |||
return 0; | |||
} |
@@ -55,19 +55,16 @@ void Mesh::render(bool anim) { | |||
Vertice *v = this->getVertex(index); | |||
aiMatrix4x4 t; | |||
for (int k = 0; k < v->getBoneNumber(); k++) { | |||
t += v->getBonesWeight(k) * boneStateList[this->getBoneIndex(v->getBonesID(k))]; | |||
t = t + v->getBonesWeight(k) * boneStateList[this->getBoneIndex(v->getBonesID(k))]; | |||
} | |||
std::cout << "Mat: " << t.a1 << t.a2 << t.a3 << t.a4 << "\n"; | |||
std::cout << " " << t.b1 << t.b2 << t.b3 << t.b4 << "\n"; | |||
std::cout << " " << t.c1 << t.c2 << t.c3 << t.c4 << "\n"; | |||
std::cout << " " << t.d1 << t.d2 << t.d3 << t.d4 << "\n"; | |||
glMultMatrixf(&t.Transpose().a1); | |||
// std::cout << t << "\n"; | |||
glMultMatrixf(&t.a1); | |||
} | |||
// glPopMatrix(); | |||
if (this->getNormal(index) != NULL) { | |||
glNormal3fv(&this->getNormal(index)->x); | |||
} | |||
glVertex3fv(&(this->getVertex(index)->getPosition()).x); | |||
// glPopMatrix(); | |||
} | |||
glEnd(); | |||
} | |||
@@ -102,8 +99,6 @@ void CalcInterpolatedPosition(aiVector3D& Out, float AnimationTime, BoneAnim* bo | |||
unsigned int NextPositionIndex = (PositionIndex + 1); | |||
float d = boneAnim->getTrans(NextPositionIndex).mTime - boneAnim->getTrans(PositionIndex).mTime; | |||
float f = (AnimationTime - (float)boneAnim->getTrans(PositionIndex).mTime) / d; | |||
std::cout << "AnimationTime: " << AnimationTime << "\n"; | |||
std::cout << "f: " << f << "\n"; | |||
// assert(f >= 0.0f && f <= 1.0f); | |||
const aiVector3D& StartPositionV = boneAnim->getTrans(PositionIndex).mValue; | |||
const aiVector3D& EndPositionV = boneAnim->getTrans(NextPositionIndex).mValue; | |||
@@ -166,8 +161,7 @@ void Mesh::updateBoneStateList(float AnimationTime, const aiNode* pNode, const a | |||
int BoneIndex = -1; | |||
if ((BoneIndex = getBoneIndex(NodeName)) != -1) { | |||
//boneStateList[BoneIndex] = GlobalTransformation * getBone(BoneIndex)->getOffset(); | |||
boneStateList[BoneIndex] = GlobalTransformation; | |||
boneStateList[BoneIndex] = GlobalTransformation * getBone(BoneIndex)->getOffset(); | |||
} | |||
for (unsigned int i = 0 ; i < pNode->mNumChildren ; i++) { |
@@ -129,7 +129,7 @@ void SceneHandler::render() { | |||
glTranslatef( -scene_center.x, -scene_center.y, -scene_center.z ); | |||
// angle += 0.9; | |||
angle += 0.5; | |||
glRotatef(angle, 0, 1, 0); | |||
// add root node transform matrix |
@@ -0,0 +1,33 @@ | |||
#version 330 | |||
layout (location = 0) in vec3 Position; | |||
layout (location = 1) in vec2 TexCoord; | |||
layout (location = 2) in vec3 Normal; | |||
layout (location = 3) in ivec4 BoneIDs; | |||
layout (location = 4) in vec4 Weights; | |||
out vec2 TexCoord0; | |||
out vec3 Normal0; | |||
out vec3 WorldPos0; | |||
const int MAX_BONES = 100; | |||
uniform mat4 gWVP; | |||
uniform mat4 gWorld; | |||
uniform mat4 gBones[MAX_BONES]; | |||
void main() | |||
{ | |||
mat4 BoneTransform = gBones[BoneIDs[0]] * Weights[0]; | |||
BoneTransform += gBones[BoneIDs[1]] * Weights[1]; | |||
BoneTransform += gBones[BoneIDs[2]] * Weights[2]; | |||
BoneTransform += gBones[BoneIDs[3]] * Weights[3]; | |||
vec4 PosL = BoneTransform * vec4(Position, 1.0); | |||
gl_Position = gWVP * PosL; | |||
TexCoord0 = TexCoord; | |||
vec4 NormalL = BoneTransform * vec4(Normal, 0.0); | |||
Normal0 = (gWorld * NormalL).xyz; | |||
WorldPos0 = (gWorld * PosL).xyz; | |||
} | |||
@@ -0,0 +1,35 @@ | |||
#version 120 | |||
// FIXME | |||
layout (location = 0) in vec3 Position; | |||
layout (location = 1) in vec2 TexCoord; | |||
layout (location = 2) in vec3 Normal; | |||
layout (location = 3) in ivec4 BoneIDs; | |||
layout (location = 4) in vec4 Weights; | |||
out vec2 TexCoord0; | |||
out vec3 Normal0; | |||
out vec3 WorldPos0; | |||
const int MAX_BONES = 100; | |||
uniform mat4 gWVP; | |||
uniform mat4 gWorld; | |||
uniform mat4 gBones[MAX_BONES]; | |||
void main() | |||
{ | |||
mat4 BoneTransform = gBones[BoneIDs[0]] * Weights[0]; | |||
BoneTransform += gBones[BoneIDs[1]] * Weights[1]; | |||
BoneTransform += gBones[BoneIDs[2]] * Weights[2]; | |||
BoneTransform += gBones[BoneIDs[3]] * Weights[3]; | |||
vec4 PosL = BoneTransform * vec4(Position, 1.0); | |||
gl_Position = gWVP * PosL; | |||
TexCoord0 = TexCoord; | |||
vec4 NormalL = BoneTransform * vec4(Normal, 0.0); | |||
Normal0 = (gWorld * NormalL).xyz; | |||
WorldPos0 = (gWorld * PosL).xyz; | |||
} | |||
@@ -36,7 +36,7 @@ aiMatrix4x4 operator*( float n, aiMatrix4x4 m ) { | |||
); | |||
} | |||
aiMatrix4x4 operator+=( aiMatrix4x4 m1, aiMatrix4x4 m2 ) { | |||
aiMatrix4x4 operator+( aiMatrix4x4 m1, aiMatrix4x4 m2 ) { | |||
return aiMatrix4x4( | |||
m1.a1+m2.a1, m1.a2+m2.a2, m1.a3+m2.a3, m1.a4+m2.a4, | |||
m1.b1+m2.b1, m1.b2+m2.b2, m1.b3+m2.b3, m1.b4+m2.b4, | |||
@@ -51,3 +51,10 @@ aiVector3D getPosition( aiMatrix4x4 mat ) { | |||
aiVector3D getScale( aiMatrix4x4 mat ) { | |||
return aiVector3D(mat.a1, mat.b2, mat.c3); | |||
} | |||
std::ostream& operator<<(std::ostream& os, const aiMatrix4x4& m) { | |||
return os << | |||
"Mat: " << m.a1 << " " << m.a2 << " " << m.a3 << " " << m.a4 << "\n" << | |||
" " << m.b1 << " " << m.b2 << " " << m.b3 << " " << m.b4 << "\n" << | |||
" " << m.c1 << " " << m.c2 << " " << m.c3 << " " << m.c4 << "\n" << | |||
" " << m.d1 << " " << m.d2 << " " << m.d3 << " " << m.d4 << "\n"; | |||
} |
@@ -1,6 +1,8 @@ | |||
#ifndef __UTILS_H__ | |||
#define __UTILS_H__ | |||
#include <iostream> | |||
#include <assimp/cimport.h> | |||
#include <assimp/scene.h> | |||
#include <assimp/postprocess.h> | |||
@@ -12,7 +14,8 @@ aiQuaternion operator*( float num, aiQuaternion v ); | |||
aiVector3D getPosition( aiMatrix4x4 mat ); | |||
aiVector3D getScale( aiMatrix4x4 mat ); | |||
aiMatrix4x4 operator*( float num, aiMatrix4x4 m ); | |||
aiMatrix4x4 operator+=( aiMatrix4x4 m1, aiMatrix4x4 m2 ); | |||
aiMatrix4x4 operator+( aiMatrix4x4 m1, aiMatrix4x4 m2 ); | |||
std::ostream& operator<<(std::ostream& os, const aiMatrix4x4& m); | |||
#endif | |||