View 3D model in OpenGL

In this homework, you will learn the transformation of model and 3D viewing.
You need to download and link glm(OpenGL Mathematics) for matrix expression and calculation. You will be given a file – Tris.txt which contains the vertex coordinates of each triangleand its corresponding colors. The first line is the number of triangles.

And then you need to render 6 figures of different views.
You need to use keyboard to control the switch between different results. When you press “1”,
the window will show the result of first figure and “2” for the second one and so on.
The followings are the parameters:
1) Orthographic projection:

left right bottom top near far
-8 8 -6 6 1 100

Camera transformation:

Eye position Optical center View-up vector
x y z x y z x y z
0 0 10 0 0 0 0 1 0

2) Orthographic projection:

left right bottom top near far
-4 4 -3 3 1 100

Camera transformation:

Eye position Optical center View-up vector
x y z x y z x y z
0 10 0 0 0 0 1 0 2

3) Model Transformation:
Translate (-1) in y-direction.
Orthographic projection:

left right bottom top near far
-4 4 -3 3 1 100

Camera transformation:

Eye position Optical center View-up vector
x y z x y z x y z
0 10 0 0 0 0 1 0 2

4) Model Transformation:
Translate (-1) in y-direction.
Perspective projection:

field of view aspect near far
20 degree 4/3 1 100

Camera transformation:

Eye position Optical center View-up vector
x y z x y z x y z
0 0 20 0 0 0 1 1 0

5) Model Transformation:
Translate (-1) in y-direction.
Perspective projection:

field of view aspect near far
30 degree 4/3 1 100

Camera transformation:

Eye position Optical center View-up vector

 

x y z x y z x y z
10 10 10 0 0 0 0 1 0

6) Model Transformation:
1. Rotate 45 degrees about x-axis.
2. Translate (-1) in y-direction.
Perspective projection:

field of view aspect near far
70 degree 4/3 1 100

Camera transformation:

Eye position Optical center View-up vector
x y z x y z x y z
3 3 3 0 0 0 0 1 0

The results look like these:

 Solution

 main.cpp

#include “utilVisualizer.h”

int main(intargc, char **argv) {

// insert code here…

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);

glutInitWindowSize(640, 480);

glutReshapeFunc(reshape);

//Change here with your name and surname as indicated in the instruction pdf

glutCreateWindow(“Titoloprovvisorio”);

glutDisplayFunc(display);

glutKeyboardFunc(keyboardFunction);

init();

glutMainLoop();

return 0;

} 

utilVisualizer.h

#ifndefutilVisualizer_h

#define utilVisualizer_h

#include <iostream>

#include <vector>

#include <string>

#include <fstream>

#ifdef __APPLE__

#include <GLUT/GLUT.h>

#include <OpenGL/OpenGL.h>

#include <OpenGL/glext.h>

#else

#include <GL/glew.h>

#include <GL/gl.h>

#include <GL/glut.h>

#include <GL/glext.h>

#endif

#include <stdio.h>

#include <stdlib.h>

// Include GLM

#include “glm/glm/glm.hpp”

#include “glm/glm/gtc/matrix_transform.hpp”

#include “glm/glm/gtx/transform.hpp”

using namespace glm;

using namespace std;

enumcameraOptions{OPT1, OPT2, OPT3, OPT4, OPT5, OPT6};

//void setUpDisplay();

intnumTs;

int option;

//the id of the shader program

GLuintprogram_id;

struct triangle{

vec3 V1;

vec3 V2;

vec3 V3;

vec4 colorV1;

vec4 colorV2;

vec4 colorV3;

};

vector<triangle> mesh;

voidloadMesh(string fileName){

ifstreamreadF;

readF.open(fileName);

if(!readF.is_open()){

cerr<< “Unable to open file “<<fileName.c_str()<<endl;

exit(-2);

}

readF>>numTs;

if(numTs==0){

cerr<< ” Invalid number of primitives”<<endl;

exit(-2);

}

for(unsigned int ii=0; ii<numTs; ii++){

triangle aux;

//intauxI = 0;

readF>> aux.V1[0];

readF>> aux.V1[1];

readF>> aux.V1[2];

readF>> aux.colorV1[0];

readF>> aux.colorV1[1];

readF>> aux.colorV1[2];

readF>> aux.colorV1[3];

readF>> aux.V2[0];

readF>> aux.V2[1];

readF>> aux.V2[2];

readF>> aux.colorV2[0];

readF>> aux.colorV2[1];

readF>> aux.colorV2[2];

readF>> aux.colorV2[3];

readF>> aux.V3[0];

readF>> aux.V3[1];

readF>> aux.V3[2];

readF>> aux.colorV3[0];

readF>> aux.colorV3[1];

readF>> aux.colorV3[2];

readF>> aux.colorV3[3];

mesh.push_back(aux);

}

}

voidinit(){

loadMesh(“Tris.txt”);

option = cameraOptions::OPT1;

glEnable(GL_DEPTH_TEST);

glClearColor(0.0, 0.0, 0.0, 1.0);

}

voiddrawObject(){

for (unsigned int ii=0; ii<numTs; ii++) {

triangletodraw = mesh.at(ii);

glBegin(GL_TRIANGLES);

glColor4f(todraw.colorV1[0], todraw.colorV1[1], todraw.colorV1[2], todraw.colorV1[3]);

glVertex3f(todraw.V1[0], todraw.V1[1], todraw.V1[2]);

glColor4f(todraw.colorV2[0], todraw.colorV2[1], todraw.colorV2[2], todraw.colorV2[3]);

glVertex3f(todraw.V2[0], todraw.V2[1], todraw.V2[2]);

glColor4f(todraw.colorV3[0], todraw.colorV3[1], todraw.colorV3[2], todraw.colorV3[3]);

glVertex3f(todraw.V3[0], todraw.V3[1], todraw.V3[2]);

glEnd();

}

}

void display(){

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

switch (option) {

casecameraOptions::OPT1:

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-8.0, 8.0, -6.0, 6.0, 1.0, 100.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

break;

casecameraOptions::OPT2 :

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-4.0, 4.0, -3.0, 3.0, 1.0, 100.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.0);

break;

casecameraOptions::OPT3 :

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-4.0, 4.0, -3.0, 3.0, 1.0, 100.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(10.0, 10.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

glTranslatef(0.0, -1.0, 0.0);

//

break;

casecameraOptions::OPT4:

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluPerspective(20.0, 4.0/3.0, 1.0, 100.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0);

glTranslatef(0.0, -1.0, 0.0);

//

break;

casecameraOptions::OPT5:

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluPerspective(30.0, 4.0/3.0, 1.0, 100.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(10.0, 10.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

glTranslatef(0.0, -1.0, 0.0);

break;

casecameraOptions::OPT6:

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluPerspective(70.0, 4.0/3.0, 1.0, 100.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(3.0, 3.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

glRotatef(45.0, 1.0, 0.0, 0.0);

glTranslatef(0.0, -1.0, 0.0);

break;

default:

break;

}

drawObject();

glutSwapBuffers();

}

voidkeyboardFunction(unsigned char key, int mx, int my){

switch (key) {

case ‘1’:

option = cameraOptions::OPT1;

break;

case ‘2’:

option = cameraOptions::OPT2;

break;

case ‘3’:

option = cameraOptions::OPT3;

break;

case ‘4’:

option = cameraOptions::OPT4;

break;

case ‘5’:

option = cameraOptions::OPT5;

break;

case ‘6’:

option = cameraOptions::OPT6;

break;

case ‘Q’:

case ‘q’:

case 27:

exit(0);

default:

break;

}

glutPostRedisplay();

}

void reshape(int width, int height){

glViewport(0, 0, width, height);

}

#endif /* utilVisualizer_h */ 

utilVisualizerShader.h

#ifndefutilVisualizerShader_h

#define utilVisualizeShaderr_h

#include <iostream>

#include <vector>

#include <string>

#include <fstream>

#ifdef __APPLE__

#include <GLUT/GLUT.h>

#include <OpenGL/OpenGL.h>

#include <OpenGL/glext.h>

#else

#include <GL/glew.h>

#include <GL/gl.h>

#include <GL/glut.h>

#include <GL/glext.h>

#endif

#include <stdio.h>

#include <stdlib.h>

// Include GLM

#include “glm/glm/glm.hpp”

#include “glm/glm/gtc/matrix_transform.hpp”

#include “glm/glm/gtx/transform.hpp”

using namespace glm;

using namespace std;

enumcameraOptions{OPT1, OPT2, OPT3, OPT4, OPT5, OPT6};

//void setUpDisplay();

intnumTs;

int option;

//the id of the shader program

GLuintprogram_id;

struct triangle{

vec3 V1;

vec3 V2;

vec3 V3;

vec4 colorV1;

vec4 colorV2;

vec4 colorV3;

};

vector<triangle> mesh;

vector<GLfloat>g_vertex_buffer_data;

GLfloat *vertices;

GLfloatlight_diffuse[] = {1.0, 1.0, 1.0, 1.0};

GLfloatlight_position[] = {1.0, 1.0, 1.0, 0.0};

voidloadMesh(string fileName){

ifstreamreadF;

readF.open(fileName);

if(!readF.is_open()){

cerr<< “Unable to open file “<<fileName.c_str()<<endl;

exit(-2);

}

readF>>numTs;

if(numTs==0){

cerr<< ” Invalid number of primitives”<<endl;

exit(-2);

}

for(unsigned int ii=0; ii<numTs; ii++){

triangle aux;

//intauxI = 0;

readF>> aux.V1[0];

readF>> aux.V1[1];

readF>> aux.V1[2];

readF>> aux.colorV1[0];

readF>> aux.colorV1[1];

readF>> aux.colorV1[2];

readF>> aux.colorV1[3];

readF>> aux.V2[0];

readF>> aux.V2[1];

readF>> aux.V2[2];

readF>> aux.colorV2[0];

readF>> aux.colorV2[1];

readF>> aux.colorV2[2];

readF>> aux.colorV2[3];

readF>> aux.V3[0];

readF>> aux.V3[1];

readF>> aux.V3[2];

readF>> aux.colorV3[0];

readF>> aux.colorV3[1];

readF>> aux.colorV3[2];

readF>> aux.colorV3[3];

mesh.push_back(aux);

for(unsigned intkk=0; kk<3;kk++)

g_vertex_buffer_data.push_back(aux.V1[kk]);

for(unsigned intkk=0; kk<3;kk++)

g_vertex_buffer_data.push_back(aux.V2[kk]);

for(unsigned intkk=0; kk<3;kk++)

g_vertex_buffer_data.push_back(aux.V2[kk]);

}

}

char *textFileRead(char *fn){

FILE* fp;

char *content = NULL;

longint count = 0;

if(fn != NULL){

fp = fopen(fn, “rt”);

if(fp!=NULL){

fseek(fp, 0, SEEK_END);

count = ftell(fp);

rewind(fp);

if(count > 0){

content = (char*)malloc(sizeof(char)*(count+1));

count = fread(content, sizeof(char), count, fp);

content[count] = ‘\0’;

}

fclose(fp);

}

}

return content;

}

GLuintLoadShaders(const char * vertex_file_path,const char * fragment_file_path){

// Create the shaders

GLuintVertexShaderID = glCreateShader(GL_VERTEX_SHADER);

GLuintFragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

// Read the Vertex Shader code from the file

std::stringVertexShaderCode;

std::ifstreamVertexShaderStream(vertex_file_path, std::ios::in);

if(VertexShaderStream.is_open()){

std::string Line = “”;

while(getline(VertexShaderStream, Line))

VertexShaderCode += “\n” + Line;

VertexShaderStream.close();

}else{

printf(“Impossible to open %s. Are you in the right directory ? Don’t forget to read the FAQ !\n”, vertex_file_path);

getchar();

return 0;

}

// Read the Fragment Shader code from the file

std::stringFragmentShaderCode;

std::ifstreamFragmentShaderStream(fragment_file_path, std::ios::in);

if(FragmentShaderStream.is_open()){

std::string Line = “”;

while(getline(FragmentShaderStream, Line))

FragmentShaderCode += “\n” + Line;

FragmentShaderStream.close();

}

GLint Result = GL_FALSE;

intInfoLogLength;

// Compile Vertex Shader

//printf(“Compiling shader : %s\n”, vertex_file_path);

charconst * VertexSourcePointer = VertexShaderCode.c_str();

glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);

glCompileShader(VertexShaderID);

// Check Vertex Shader

glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);

glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);

if ( InfoLogLength> 0 ){

std::vector<char>VertexShaderErrorMessage(InfoLogLength+1);

glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);

printf(“%s\n”, &VertexShaderErrorMessage[0]);

}

// Compile Fragment Shader

//printf(“Compiling shader : %s\n”, fragment_file_path);

charconst * FragmentSourcePointer = FragmentShaderCode.c_str();

glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);

glCompileShader(FragmentShaderID);

// Check Fragment Shader

glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);

glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);

if ( InfoLogLength> 0 ){

std::vector<char>FragmentShaderErrorMessage(InfoLogLength+1);

glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);

printf(“%s\n”, &FragmentShaderErrorMessage[0]);

}

// Link the program

//printf(“Linking program\n”);

GLuintProgramID = glCreateProgram();

glAttachShader(ProgramID, VertexShaderID);

glAttachShader(ProgramID, FragmentShaderID);

glLinkProgram(ProgramID);

// Check the program

glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);

glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);

if ( InfoLogLength> 0 ){

std::vector<char>ProgramErrorMessage(InfoLogLength+1);

glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);

printf(“%s\n”, &ProgramErrorMessage[0]);

}

glDetachShader(ProgramID, VertexShaderID);

glDetachShader(ProgramID, FragmentShaderID);

glDeleteShader(VertexShaderID);

glDeleteShader(FragmentShaderID);

returnProgramID;

}

voidinit(){

loadMesh(“../../Homework3/Tris.txt”);

option = cameraOptions::OPT1;

glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);

glEnable(GL_LIGHT0);

glEnable(GL_DEPTH_TEST);

glClearColor(0.0, 0.0, 0.0, 1.0);

// Set them to the correct path

program_id = LoadShaders(“../trisShader.vert”, “../trisShader.frag”);

vertices = new GLfloat[g_vertex_buffer_data.size()];

for(unsigned int ii=0; ii<g_vertex_buffer_data.size(); ii++)

vertices[ii] = g_vertex_buffer_data.at(ii);

}

void display(){

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

for(unsigned int ii=0; ii<numTs; ii++){

mat4projectionMatrix, viewMatrix, modelMatrix, MVP, transla, rota;

GLuintMatrixID = glGetUniformLocation(program_id, “MVP”);

switch (option) {

casecameraOptions::OPT1:

projectionMatrix = ortho(-8.0, 8.0, -6.0, 6.0, 1.0, 100.0);

viewMatrix = lookAt(vec3(0.0,0.0,10.0), vec3(0,0,0), vec3(0.0,1.0, 0.0));

modelMatrix = translate(vec3(0.0, 0.0, 0.0));//mat4(1.0, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0, 0.0,  0.0, 0.0, 1.0, 0.0,  0.0, 0.0, 0.0, 1.0);

MVP = projectionMatrix*viewMatrix*modelMatrix;

break;

casecameraOptions::OPT2 :

projectionMatrix = ortho(-4.0, 4.0, -3.0, 3.0, 1.0, 100.0);

viewMatrix = lookAt(vec3(0.0,10.0,0.0), vec3(0,0,0), vec3(1.0,0.0, 2.0));

modelMatrix = translate(vec3(0.0, 0.0, 0.0));

MVP = projectionMatrix*viewMatrix*modelMatrix;

break;

casecameraOptions::OPT3 :

projectionMatrix = ortho(-4.0, 4.0, -3.0, 3.0, 1.0, 100.0);

viewMatrix = lookAt(vec3(0.0,10.0,10.0), vec3(0,0,0), vec3(0.0,1.0, 0.0));

modelMatrix = translate(vec3(0.0, -1.0, 0.0));

MVP = projectionMatrix*viewMatrix*modelMatrix;

break;

casecameraOptions::OPT4:

projectionMatrix = perspective(20.0, 4.0/3.0, 1.0, 100.0);

viewMatrix = lookAt(vec3(0.0,0.0,20.0), vec3(0,0,0), vec3(1.0,1.0, 0.0));

modelMatrix = translate(vec3(0.0, -1.0, 0.0));

MVP = projectionMatrix*viewMatrix*modelMatrix;

break;

casecameraOptions::OPT5:

projectionMatrix = perspective(30.0, 4.0/3.0, 1.0, 100.0);

viewMatrix = lookAt(vec3(10.0,10.0,10.0), vec3(0,0,0), vec3(0.0,1.0, 0.0));

modelMatrix = translate(vec3(0.0, -1.0, 0.0));

MVP = projectionMatrix*viewMatrix*modelMatrix;

break;

casecameraOptions::OPT6:

projectionMatrix = perspective(70.0, 4.0/3.0, 1.0, 100.0);

viewMatrix = lookAt(vec3(3.0,3.0,3.0), vec3(0,0,0), vec3(0.0,1.0, 0.0));

transla = translate(mat4(1.0f), vec3(0.0f, -1.0f, 0.0f));

rota = rotate(45.0f, vec3(1.0f, 0.0f, 0.0f));

modelMatrix = rota*transla;

MVP = projectionMatrix*viewMatrix*modelMatrix;

break;

default:

break;

}

GLuintvertexbuffer;

glGenBuffers(1, &vertexbuffer);

glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

glBufferData(GL_ARRAY_BUFFER, mesh.size()*9*sizeof(float), vertices, GL_STATIC_DRAW);

glUseProgram(program_id);

glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

glEnableVertexAttribArray(0);

glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

glVertexAttribPointer(

0,                  // attribute. No particular reason for 0, but must match the layout in the shader.

3,                  // size

GL_FLOAT,           // type

GL_FALSE,           // normalized?

0,                  // stride

(void*)0            // array buffer offset

);

glDrawArrays(GL_TRIANGLES, 0, mesh.size()*9);

glDisableVertexAttribArray(0);

}

glutSwapBuffers();

}

voidkeyboardFunction(unsigned char key, int mx, int my){

switch (key) {

case ‘1’:

option = cameraOptions::OPT1;

break;

case ‘2’:

option = cameraOptions::OPT2;

break;

case ‘3’:

option = cameraOptions::OPT3;

break;

case ‘4’:

option = cameraOptions::OPT4;

break;

case ‘5’:

option = cameraOptions::OPT5;

break;

case ‘6’:

option = cameraOptions::OPT6;

break;

case ‘Q’:

case ‘q’:

case 27:

exit(0);

default:

break;

}

glutPostRedisplay();

}

void reshape(int width, int height){

glViewport(0, 0, width, height);

}

#endif /* utilVisualizerShader_h */