Merge branch 'multiple-objects'

This commit is contained in:
Luca Conte 2024-06-10 11:13:34 +02:00
commit 3db8817187
6 changed files with 605 additions and 333 deletions

40
obj/Xblock.obj Normal file
View File

@ -0,0 +1,40 @@
# Blender 4.1.1
# www.blender.org
mtllib Xblock.mtl
o Cube
v 1.740000 0.130000 -0.150000
v 1.740000 -0.130000 -0.150000
v 1.740000 0.130000 0.150000
v 1.740000 -0.130000 0.150000
v -1.740000 0.130000 -0.150000
v -1.740000 -0.130000 -0.150000
v -1.740000 0.130000 0.150000
v -1.740000 -0.130000 0.150000
vn -0.0000 1.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vt 0.625000 0.500000
vt 0.875000 0.500000
vt 0.875000 0.750000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.125000 0.500000
vt 0.375000 0.500000
vt 0.125000 0.750000
s 0
usemtl Material
f 1/1/1 5/2/1 7/3/1 3/4/1
f 4/5/2 3/4/2 7/6/2 8/7/2
f 8/8/3 7/9/3 5/10/3 6/11/3
f 6/12/4 2/13/4 4/5/4 8/14/4
f 2/13/5 1/1/5 3/4/5 4/5/5
f 6/11/6 5/10/6 1/1/6 2/13/6

40
obj/Yblock.obj Normal file
View File

@ -0,0 +1,40 @@
# Blender 4.1.1
# www.blender.org
mtllib Yblock.mtl
o Cube
v 0.230000 0.130000 -1.230000
v 0.230000 -0.130000 -1.230000
v 0.230000 0.130000 1.230000
v 0.230000 -0.130000 1.230000
v -0.230000 0.130000 -1.230000
v -0.230000 -0.130000 -1.230000
v -0.230000 0.130000 1.230000
v -0.230000 -0.130000 1.230000
vn -0.0000 1.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vt 0.625000 0.500000
vt 0.875000 0.500000
vt 0.875000 0.750000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.125000 0.500000
vt 0.375000 0.500000
vt 0.125000 0.750000
s 0
usemtl Material
f 1/1/1 5/2/1 7/3/1 3/4/1
f 4/5/2 3/4/2 7/6/2 8/7/2
f 8/8/3 7/9/3 5/10/3 6/11/3
f 6/12/4 2/13/4 4/5/4 8/14/4
f 2/13/5 1/1/5 3/4/5 4/5/5
f 6/11/6 5/10/6 1/1/6 2/13/6

40
obj/Yblock_rotated.obj Normal file
View File

@ -0,0 +1,40 @@
# Blender 4.1.1
# www.blender.org
mtllib Yblock_rotated.mtl
o Cube
v 1.231565 1.164580 -0.150000
v 1.395188 0.962522 -0.150000
v 1.231565 1.164580 0.150000
v 1.395188 0.962522 0.150000
v -1.395188 -0.962522 -0.150000
v -1.231565 -1.164580 -0.150000
v -1.395188 -0.962522 0.150000
v -1.231565 -1.164580 0.150000
vn -0.6293 0.7771 -0.0000
vn -0.0000 -0.0000 1.0000
vn -0.7771 -0.6293 -0.0000
vn 0.6293 -0.7771 -0.0000
vn 0.7771 0.6293 -0.0000
vn -0.0000 -0.0000 -1.0000
vt 0.625000 0.500000
vt 0.875000 0.500000
vt 0.875000 0.750000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.125000 0.500000
vt 0.375000 0.500000
vt 0.125000 0.750000
s 0
usemtl Material
f 1/1/1 5/2/1 7/3/1 3/4/1
f 4/5/2 3/4/2 7/6/2 8/7/2
f 8/8/3 7/9/3 5/10/3 6/11/3
f 6/12/4 2/13/4 4/5/4 8/14/4
f 2/13/5 1/1/5 3/4/5 4/5/5
f 6/11/6 5/10/6 1/1/6 2/13/6

40
obj/Zblock.obj Normal file
View File

@ -0,0 +1,40 @@
# Blender 4.1.1
# www.blender.org
mtllib Zblock.mtl
o Cube
v 0.280000 1.000000 -0.170000
v 0.280000 -1.000000 -0.170000
v 0.280000 1.000000 0.170000
v 0.280000 -1.000000 0.170000
v -0.280000 1.000000 -0.170000
v -0.280000 -1.000000 -0.170000
v -0.280000 1.000000 0.170000
v -0.280000 -1.000000 0.170000
vn -0.0000 1.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vt 0.625000 0.500000
vt 0.875000 0.500000
vt 0.875000 0.750000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.125000 0.500000
vt 0.375000 0.500000
vt 0.125000 0.750000
s 0
usemtl Material
f 1/1/1 5/2/1 7/3/1 3/4/1
f 4/5/2 3/4/2 7/6/2 8/7/2
f 8/8/3 7/9/3 5/10/3 6/11/3
f 6/12/4 2/13/4 4/5/4 8/14/4
f 2/13/5 1/1/5 3/4/5 4/5/5
f 6/11/6 5/10/6 1/1/6 2/13/6

View File

@ -5,7 +5,7 @@
#include "vertexShader.c" #include "vertexShader.c"
#include "fragmentShader.c" #include "fragmentShader.c"
#include "objectHandler.c"
#include "matrixMath.h" #include "matrixMath.h"
#include "transformation.h" #include "transformation.h"
#include "wavefrontobj.h" #include "wavefrontobj.h"
@ -19,7 +19,6 @@
#include <stdbool.h> #include <stdbool.h>
GLuint program; GLuint program;
GLuint vao;
#define NUM_TEXTURES 5 #define NUM_TEXTURES 5
@ -33,14 +32,14 @@ int flipFlag = 1;
GLuint textures[NUM_TEXTURES]; GLuint textures[NUM_TEXTURES];
char* textureFiles[NUM_TEXTURES] = { char* textureFiles[NUM_TEXTURES] = {
"../texture/earth/day.png", "../texture/earth/day.png",
"../texture/earth/night.png", "../texture/earth/night.png",
"../texture/earth/clouds.png", "../texture/earth/clouds.png",
"../texture/earth/ocean_mask.png", "../texture/earth/ocean_mask.png",
"../texture/earth/normal.png" "../texture/earth/normal.png"
}; };
int numFaces = 0; ObjectData* objectData;
bool exitRequested = false; bool exitRequested = false;
@ -57,412 +56,397 @@ GLfloat step = 0.0f;
const GLfloat pi = 3.14159f; const GLfloat pi = 3.14159f;
vec3 cameraPosition = {0.0f, 3.0f, 5.5f}; vec3 cameraPosition = {0.0f, 3.0f, 5.5f};
vec3 objectPosition = {0.0f, 0.0f, 0.0f};
GLfloat radius = 1.0f;
char* defaultModel = "../obj/monkey.obj"; int numModels = 0;
char* model; char* models[] = {
"../obj/Xblock.obj",
"../obj/Yblock.obj",
"../obj/Yblock_rotated.obj",
"../obj/Zblock.obj",
};
// input handler for camera movement /**
* Input handler for camera movement.
* */
void handleInputs(double deltaTime) { void handleInputs(double deltaTime) {
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
cameraPosition.z += deltaTime * 10; cameraPosition.z += deltaTime * 10;
} }
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
cameraPosition.z -= deltaTime * 10; cameraPosition.z -= deltaTime * 10;
} }
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
cameraPosition.x += deltaTime * 10; cameraPosition.x += deltaTime * 10;
} }
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
cameraPosition.x -= deltaTime * 10; cameraPosition.x -= deltaTime * 10;
} }
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_F) == GLFW_PRESS) {
cameraPosition.y += deltaTime * 10; cameraPosition.y += deltaTime * 10;
} }
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS) {
cameraPosition.y -= deltaTime * 10; cameraPosition.y -= deltaTime * 10;
} }
if (glfwGetKey(window, GLFW_KEY_L) == GLFW_PRESS) {
objectPosition.x += deltaTime * 10;
}
if (glfwGetKey(window, GLFW_KEY_J) == GLFW_PRESS) {
objectPosition.x -= deltaTime * 10;
}
if (glfwGetKey(window, GLFW_KEY_I) == GLFW_PRESS) {
objectPosition.z += deltaTime * 10;
}
if (glfwGetKey(window, GLFW_KEY_K) == GLFW_PRESS) {
objectPosition.z -= deltaTime * 10;
}
if (glfwGetKey(window, GLFW_KEY_O) == GLFW_PRESS) {
radius += deltaTime * 10;
}
if (glfwGetKey(window, GLFW_KEY_U) == GLFW_PRESS) {
radius -= deltaTime * 10;
}
} }
// input handler to quit with ESC // input handler to quit with ESC
void keyboardHandler(GLFWwindow* window, int key, int scancode, int action, int mods) { void keyboardHandler(GLFWwindow* window, int key, int scancode, int action, int mods) {
if (action == GLFW_PRESS) { if (action == GLFW_PRESS) {
if (key == GLFW_KEY_ESCAPE) { if (key == GLFW_KEY_ESCAPE) {
exitRequested = true; exitRequested = true;
} }
} }
} }
/**
* Loads textures.
*/
void loadTexture(char* textureFile, GLuint* texture) { void loadTexture(char* textureFile, GLuint* texture) {
int width, height, nrChannels; int width, height, nrChannels;
unsigned char* image = stbi_load(textureFile, &width, &height, &nrChannels, 0); unsigned char* image = stbi_load(textureFile, &width, &height, &nrChannels, 0);
// default: 3 channels, RGB // default: 3 channels, RGB
GLenum channelFormats[] = { GLenum channelFormats[] = {
0, 0,
GL_RED, GL_RED,
GL_RG, GL_RG,
GL_RGB, GL_RGB,
GL_RGBA GL_RGBA
}; };
GLenum format = channelFormats[nrChannels]; GLenum format = channelFormats[nrChannels];
glGenTextures(1, texture); glGenTextures(1, texture);
glBindTexture(GL_TEXTURE_2D, *texture); glBindTexture(GL_TEXTURE_2D, *texture);
printf("%s - %d\n", textureFile, nrChannels); printf("%s - %d\n", textureFile, nrChannels);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, format, GL_UNSIGNED_BYTE, image); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, format, GL_UNSIGNED_BYTE, image);
// load texture using previously determined format ----- ^^^^^^ // load texture using previously determined format ----- ^^^^^^
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
stbi_image_free(image); stbi_image_free(image);
} }
void init(void) { void init(void) {
// create and compile vertex shader // create and compile vertex shader
const GLchar *vertexTextConst = vertexShader_glsl; const GLchar *vertexTextConst = vertexShader_glsl;
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexTextConst, &vertexShader_glsl_len); glShaderSource(vertexShader, 1, &vertexTextConst, &vertexShader_glsl_len);
glCompileShader(vertexShader); glCompileShader(vertexShader);
GLint status; GLint status;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status); glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
if (!status) { if (!status) {
printf("Error compiling vertex shader: "); printf("Error compiling vertex shader: ");
GLchar infoLog[1024]; GLchar infoLog[1024];
glGetShaderInfoLog(vertexShader, 1024, NULL, infoLog); glGetShaderInfoLog(vertexShader, 1024, NULL, infoLog);
printf("%s",infoLog); printf("%s",infoLog);
exit(1); exit(1);
} }
vertexTextConst = NULL; vertexTextConst = NULL;
// create and compile fragment shader
const GLchar *fragmentTextConst = fragmentShader_glsl;
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentTextConst, &fragmentShader_glsl_len);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);
if (!status) {
printf("Error compiling fragment shader: ");
GLchar infoLog[1024];
glGetShaderInfoLog(fragmentShader, 1024, NULL, infoLog);
printf("%s",infoLog);
exit(1);
}
// create and link shader program
program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (!status) {
printf("Error linking program: ");
GLchar infoLog[1024];
glGetProgramInfoLog(program, 1024, NULL, infoLog);
printf("%s",infoLog);
exit(1);
}
glValidateProgram(program);
glGetProgramiv(program, GL_VALIDATE_STATUS, &status);
// create and compile fragment shader if (!status) {
printf("Error validating program: ");
const GLchar *fragmentTextConst = fragmentShader_glsl; GLchar infoLog[1024];
glGetProgramInfoLog(program, 1024, NULL, infoLog);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); printf("%s",infoLog);
glShaderSource(fragmentShader, 1, &fragmentTextConst, &fragmentShader_glsl_len); exit(1);
glCompileShader(fragmentShader); }
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);
if (!status) {
printf("Error compiling fragment shader: ");
GLchar infoLog[1024];
glGetShaderInfoLog(fragmentShader, 1024, NULL, infoLog);
printf("%s",infoLog);
exit(1);
}
// create and link shader program
program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (!status) {
printf("Error linking program: ");
GLchar infoLog[1024];
glGetProgramInfoLog(program, 1024, NULL, infoLog);
printf("%s",infoLog);
exit(1);
}
glValidateProgram(program);
glGetProgramiv(program, GL_VALIDATE_STATUS, &status); // --------------- READ MODEL FILES
//objectData = readObjFiles(&models, numModels);
char* c = "../obj/Yblock.obj";
objectData = readSingleObjFile(&c, 10, &numModels);
printf("\nAmount %d\n", numModels);
fflush(stdout);
/*
objectData = malloc(numModels * sizeof(ObjectData));
for (int i = 0; i < numModels; i++) {
if (!status) { glGenVertexArrays(1, &objData->vao);
printf("Error validating program: "); glGenBuffers(1, &objData->vbo);
GLchar infoLog[1024];
glGetProgramInfoLog(program, 1024, NULL, infoLog);
printf("%s",infoLog);
exit(1);
}
glBindVertexArray(objData->vao);
glBindBuffer(GL_ARRAY_BUFFER, objData->vbo);
glBufferData(GL_ARRAY_BUFFER, objData->object.numFaces * 3 * sizeof(Vertex), objData->object.vertices, GL_STATIC_DRAW);
// --------------- READ MODEL FILE glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0);
ParsedObjFile teapot = readObjFile(model); glEnableVertexAttribArray(0);
numFaces = teapot.length; glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
// write faces to buffer glBindVertexArray(0);
GLuint triangleVertexBufferObject;
glGenBuffers(1, &triangleVertexBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, teapot.length * sizeof(face), teapot.faces, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
objectData[i] = objData;
}
*/
stbi_set_flip_vertically_on_load(flipFlag); stbi_set_flip_vertically_on_load(flipFlag);
// -------------- READ TEXTURE FILES // -------------- READ TEXTURE FILES
for (int i = 0; i < NUM_TEXTURES; i++) { for (int i = 0; i < NUM_TEXTURES; i++) {
loadTexture(textureFiles[i], &textures[i]); loadTexture(textureFiles[i], &textures[i]);
} }
// ENABLE BACKFACE CULLING
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);
// create vertex array object // ENABLE DEPTH BUFFER
glGenVertexArrays(1, &vao); glEnable(GL_DEPTH_TEST);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBufferObject);
// vertex positions glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glVertexAttribPointer(
0,
3,
GL_FLOAT,
GL_FALSE,
sizeof(vertex),
0
);
glEnableVertexAttribArray(0);
// vertex normals
glVertexAttribPointer(
1,
3,
GL_FLOAT,
GL_FALSE,
sizeof(vertex),
(void*) offsetof(vertex, normal)
);
glEnableVertexAttribArray(1);
// vertex texture coordinates
glVertexAttribPointer(
2,
2,
GL_FLOAT,
GL_FALSE,
sizeof(vertex),
(void*) offsetof(vertex, texture)
);
glEnableVertexAttribArray(2);
// face tangents
glVertexAttribPointer(
3,
3,
GL_FLOAT,
GL_FALSE,
sizeof(vertex),
(void*) offsetof(vertex, tangent)
);
glEnableVertexAttribArray(3);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// ENABLE BACKFACE CULLING
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);
// ENABLE DEPTH BUFFER
glEnable(GL_DEPTH_TEST);
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
} }
void updateStats() { void updateStats() {
printf("\rFPS: %.1f", framesSinceUpdate / timeSinceUpdate); printf("\rFPS: %.1f", framesSinceUpdate / timeSinceUpdate);
printf(" - Camera Position: [%f, %f, %f]", cameraPosition.x, cameraPosition.y, cameraPosition.z); printf(" - Camera Position: [%f, %f, %f]", cameraPosition.x, cameraPosition.y, cameraPosition.z);
fflush(stdout); fflush(stdout);
} }
/**
* Main draw function.
*/
void draw(void) { void draw(void) {
// FPS Counter // FPS Counter
framesSinceUpdate++; framesSinceUpdate++;
double deltaTime = glfwGetTime(); double deltaTime = glfwGetTime();
timeSinceUpdate += deltaTime; timeSinceUpdate += deltaTime;
glfwSetTime(0.0f); glfwSetTime(0.0f);
if (timeSinceUpdate >= timeBetweenUpdates) { if (timeSinceUpdate >= timeBetweenUpdates) {
updateStats(); updateStats();
timeSinceUpdate = 0.0f; timeSinceUpdate = 0.0f;
framesSinceUpdate = 0; framesSinceUpdate = 0;
} }
// camera movement // camera movement
handleInputs(deltaTime); handleInputs(deltaTime);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program); glUseProgram(program);
glBindVertexArray(vao);
// step for rotations // step for rotations
// counts up to 1.0 and then resets back to 0.0 forever // counts up to 1.0 and then resets back to 0.0 forever
step += deltaTime / 15; step += deltaTime / 15;
if (step > 1.0f) step -= 1.0f; if (step > 1.0f) step -= 1.0f;
if (step < 0.0f) step += 1.0f; if (step < 0.0f) step += 1.0f;
// step multiplied by pi * 2 for use in rotation and trig functions // step multiplied by pi * 2 for use in rotation and trig functions
GLfloat stepi = step * pi * 2; GLfloat stepi = step * pi * 2;
// ------------- VIEWING TRANSFORMATION -------------------
vec3 origin = {0.0f, 0.0f, 0.0f};
vec3 up = {0.0f, 1.0f, 0.0f};
// ------------- MODEL TRANSFORMATION --------------------- mat4 viewingTransformation;
// SCALE -> ROTATE -> TRANSLATE lookAt(&viewingTransformation, &cameraPosition, &origin, &up);
mat4 modelTransformation; // -------------- PROJECTION TRANSFORMATION ----------------
identity(&modelTransformation); mat4 projectionTransformation;
GLfloat near = 0.1f;
GLfloat far = 20.0f;
perspectiveProjection(&projectionTransformation, near, far);
rotateY(&modelTransformation, &modelTransformation, stepi * 2); // -------------- NORMALISATION TRANSFORMATION -------------
rotateZ(&modelTransformation, &modelTransformation, -23.5f / 180 * pi); mat4 normalisationTransformation;
GLfloat fovy = pi / 2;
normalisedDeviceCoordinatesFov(&normalisationTransformation, fovy, aspectRatio, near, far);
// ------------- VIEWING TRANSFORMATION ------------------- mat4 projection;
vec3 origin = {0.0f, 0.0f, 0.0f}; identity(&projection);
vec3 up = {0.0f, 1.0f, 0.0f}; multiply(&projection, &projectionTransformation, &projection);
multiply(&projection, &normalisationTransformation, &projection);
mat4 viewingTransformation; // ------------- DRAW EACH OBJECT SEPARATELY ----------------
lookAt(&viewingTransformation, &cameraPosition, &origin, &up); for (int i = 0; i < numModels; i++) {
// Reset model transformation for each object
mat4 modelTransformation;
identity(&modelTransformation);
// Apply object-specific transformations
vec3 v = {
(GLfloat)i*2+objectPosition.x,
0.0f+objectPosition.y,
0.0f+objectPosition.z
};
translate(&modelTransformation, &modelTransformation, &v);
mat4 modelView;
identity(&modelView);
multiply(&modelView, &modelTransformation, &modelView);
multiply(&modelView, &viewingTransformation, &modelView);
// -------------- PROJECTION TRANSFORMATION ---------------- // calculate matrix for normals
mat4 projectionTransformation; mat3 normalModelView;
GLfloat near = 0.1f; mat3From4(&normalModelView, &modelView);
GLfloat far = 20.0f; mat3Inverse(&normalModelView, &normalModelView);
perspectiveProjection(&projectionTransformation, near, far); mat3Transpose(&normalModelView, &normalModelView);
// send transformation matrix to shader
glUniformMatrix4fv(glGetUniformLocation(program, "modelView"), 1, GL_FALSE, (GLfloat*)&modelView);
glUniformMatrix3fv(glGetUniformLocation(program, "normalModelView"), 1, GL_FALSE, (GLfloat*)&normalModelView);
glUniformMatrix4fv(glGetUniformLocation(program, "projection"), 1, GL_FALSE, (GLfloat*)&projection);
// SET MATERIAL DATA
glUniform1f(glGetUniformLocation(program, "shininess"), 60.0f * 4.0f);
// -------------- NORMALISATION TRANSFORMATION ------------- // SET LIGHT DATA
mat4 normalisationTransformation; glUniform4f(glGetUniformLocation(program, "lightColor"), 1.0f, 1.0f, 1.0f, 1.0f);
GLfloat fovy = pi / 2; glUniform4f(glGetUniformLocation(program, "ambientLight"), 0.05f, 0.05f, 0.05f, 1.0f);
normalisedDeviceCoordinatesFov(&normalisationTransformation, fovy, aspectRatio, near, far);
// BIND TEXTURES
GLuint textureLocation;
textureLocation = glGetUniformLocation(program, "day");
glUniform1i(textureLocation, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[DAY]);
mat4 modelView; textureLocation = glGetUniformLocation(program, "night");
identity(&modelView); glUniform1i(textureLocation, 1);
multiply(&modelView, &modelTransformation, &modelView); glActiveTexture(GL_TEXTURE1);
multiply(&modelView, &viewingTransformation, &modelView); glBindTexture(GL_TEXTURE_2D, textures[NIGHT]);
mat4 projection; textureLocation = glGetUniformLocation(program, "clouds");
identity(&projection); glUniform1i(textureLocation, 2);
multiply(&projection, &projectionTransformation, &projection); glActiveTexture(GL_TEXTURE2);
multiply(&projection, &normalisationTransformation, &projection); glBindTexture(GL_TEXTURE_2D, textures[CLOUDS]);
// calculate matrix for normals textureLocation = glGetUniformLocation(program, "ocean");
mat3 normalModelView; glUniform1i(textureLocation, 3);
mat3From4(&normalModelView, &modelView); glActiveTexture(GL_TEXTURE3);
mat3Inverse(&normalModelView, &normalModelView); glBindTexture(GL_TEXTURE_2D, textures[OCEAN]);
mat3Transpose(&normalModelView, &normalModelView);
// send transformation matrix to shader textureLocation = glGetUniformLocation(program, "normalMap");
glUniformMatrix4fv(glGetUniformLocation(program, "modelView"), 1, GL_FALSE, (GLfloat*)&modelView); glUniform1i(textureLocation, 4);
glUniformMatrix3fv(glGetUniformLocation(program, "normalModelView"), 1, GL_FALSE, (GLfloat*)&normalModelView); glActiveTexture(GL_TEXTURE4);
glUniformMatrix4fv(glGetUniformLocation(program, "projection"), 1, GL_FALSE, (GLfloat*)&projection); glBindTexture(GL_TEXTURE_2D, textures[NORMAL]);
// draw each object separately
vec4 lightPosition = {cos(stepi) * 1000.0f, 0.0f, sin(stepi) * 1000.0f, 1.0f}; glBindVertexArray(objectData[i].vao);
multiplyAny((GLfloat *)&lightPosition, (GLfloat *)&viewingTransformation, (GLfloat *)&lightPosition, 4, 4, 1); glDrawArrays(GL_TRIANGLES, 0, objectData[i].object.length * 3);
}
glUniform3f(glGetUniformLocation(program, "lightPosition"), lightPosition.x, lightPosition.y, lightPosition.z);
// SET MATERIAL DATA
glUniform1f(glGetUniformLocation(program, "shininess"), 60.0f * 4.0f);
// SET LIGHT DATA
glUniform4f(glGetUniformLocation(program, "lightColor"), 1.0f, 1.0f, 1.0f, 1.0f);
glUniform4f(glGetUniformLocation(program, "ambientLight"), 0.05f, 0.05f, 0.05f, 1.0f);
// BIND TEXTURES
GLuint textureLocation;
textureLocation = glGetUniformLocation(program, "day");
glUniform1i(textureLocation, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[DAY]);
textureLocation = glGetUniformLocation(program, "night");
glUniform1i(textureLocation, 1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures[NIGHT]);
textureLocation = glGetUniformLocation(program, "clouds");
glUniform1i(textureLocation, 2);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, textures[CLOUDS]);
textureLocation = glGetUniformLocation(program, "ocean");
glUniform1i(textureLocation, 3);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, textures[OCEAN]);
textureLocation = glGetUniformLocation(program, "normalMap");
glUniform1i(textureLocation, 4);
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, textures[NORMAL]);
// draw!!1
glDrawArrays(GL_TRIANGLES, 0, numFaces * 3);
} }
// change viewport size and adjust aspect ratio when changing window size /**
* Changes viewport size and adjust aspect ratio when changing window size
*/
void framebuffer_size_callback(GLFWwindow *window, int width, int height) { void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
aspectRatio = (float)width / height; aspectRatio = (float)width / height;
} }
/**
* Main function.
*/
int main(int argc, char **argv) { int main(int argc, char **argv) {
// initialise window
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
if (argc >= 2) { window = glfwCreateWindow(700, 700, "Computergrafik 1", NULL, NULL);
model = argv[1];
} else {
model = defaultModel;
}
// initialise window
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(700, 700, "Computergrafik 1", NULL, NULL); if (!window) {
printf("Failed to create window\n");
glfwTerminate();
return -1;
}
if (!window) { glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
printf("Failed to create window\n"); glfwMakeContextCurrent(window);
glfwTerminate();
return -1;
}
// disable framerate cap
glfwSwapInterval(0);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); // register keyboard event handler
glfwMakeContextCurrent(window); glfwSetKeyCallback(window, keyboardHandler);
// disable framerate cap // initialise glew
glfwSwapInterval(0); glewInit();
// register keyboard event handler printf("OpenGL version supported by this platform (%s):\n", glGetString(GL_VERSION));
glfwSetKeyCallback(window, keyboardHandler);
// initialise glew init();
glewInit(); // exit when window should close or exit is requested (ESC)
while (!glfwWindowShouldClose(window) && !exitRequested) {
draw();
printf("OpenGL version supported by this platform (%s):\n", glGetString(GL_VERSION)); glfwSwapBuffers(window);
glfwPollEvents();
}
init(); glfwTerminate();
// exit when window should close or exit is requested (ESC) return 0;
while (!glfwWindowShouldClose(window) && !exitRequested) { }
draw();
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}

128
src/objectHandler.c Normal file
View File

@ -0,0 +1,128 @@
#include "wavefrontobj.h"
#include <GL/glew.h>
#include <stdlib.h>
typedef struct {
GLuint vao;
GLuint vbo;
ParsedObjFile object;
} ObjectData;
/**
* Loads an object.
* Basically generates vbo and vao for an object and saving them in the ObjectData struct.
*/
void load_object(ObjectData* objectData) {
// write faces to buffer
//GLuint triangleVertexBufferObject;
glGenBuffers(1, &objectData->vbo);
glBindBuffer(GL_ARRAY_BUFFER, objectData->vbo);
glBufferData(GL_ARRAY_BUFFER, objectData->object.length * sizeof(face), objectData->object.faces, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// create vertex array object
glGenVertexArrays(1, &objectData->vao);
glBindVertexArray(objectData->vao);
glBindBuffer(GL_ARRAY_BUFFER, objectData->vao);
// vertex positions
glVertexAttribPointer(
0,
3,
GL_FLOAT,
GL_FALSE,
sizeof(vertex),
0
);
glEnableVertexAttribArray(0);
// vertex normals
glVertexAttribPointer(
1,
3,
GL_FLOAT,
GL_FALSE,
sizeof(vertex),
(void*) offsetof(vertex, normal)
);
glEnableVertexAttribArray(1);
// vertex texture coordinates
glVertexAttribPointer(
2,
2,
GL_FLOAT,
GL_FALSE,
sizeof(vertex),
(void*) offsetof(vertex, texture)
);
glEnableVertexAttribArray(2);
// face tangents
glVertexAttribPointer(
3,
3,
GL_FLOAT,
GL_FALSE,
sizeof(vertex),
(void*) offsetof(vertex, tangent)
);
glEnableVertexAttribArray(3);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
/**
* Takes a string-pointer, a number of files to read and a number to store the added objects to
* Returns an array of objects.
*/
ObjectData* readObjFiles(char** path, int numModels, int* count) {
ObjectData* objects = (ObjectData*) malloc(sizeof(ObjectData) * numModels);
*count += numModels;
if (!objects) {
printf("ERROR in objectHandler: Failed to allocate memory for objects\n");
return NULL;
}
for (int i = 0; i < numModels; ++i) {
objects[i].object = readObjFile(path[i]);
load_object(&objects[i]);
}
return objects;
}
/**
* Takes a single object and reads it a certain number of times.
* Returns an array of objects.
*/
ObjectData* readSingleObjFile(char** path, int numModels, int* count) {
ObjectData* objects = (ObjectData*) malloc(sizeof(ObjectData) * numModels);
*count += numModels;
if (!objects) {
printf("ERROR in objectHandler: Failed to allocate memory for objects\n");
fflush(stdout);
return NULL;
}
for (int i = 0; i < numModels; ++i) {
objects[i].object = readObjFile(*path);
load_object(&objects[i]);
*count++;
}
return objects;
}
/**
* Draw call for a single object.
* Used to clean up the draw calls in Main().
*/
void draw_object(ObjectData* objectData) {
glBindVertexArray(objectData->vao);
glDrawArrays(GL_TRIANGLES, 0, objectData->object.length * 3); // Annahme: Jedes face hat 3 vertices
glBindVertexArray(0);
}