From 14ff26f1e300f3774376fc06378340e481ca6705 Mon Sep 17 00:00:00 2001 From: Luca Conte Date: Thu, 25 Apr 2024 16:39:08 +0200 Subject: [PATCH] teapot baby --- u06-2/fragmentShader.glsl | 4 +- u06-2/main.c | 196 ++++++++++---------------------------- u06-2/vertexShader.glsl | 8 +- u06-2/wavefrontobj.c | 88 ++++++++++++++++- u06-2/wavefrontobj.h | 8 +- 5 files changed, 147 insertions(+), 157 deletions(-) diff --git a/u06-2/fragmentShader.glsl b/u06-2/fragmentShader.glsl index 20348df..a909333 100644 --- a/u06-2/fragmentShader.glsl +++ b/u06-2/fragmentShader.glsl @@ -1,5 +1,5 @@ #version 330 core -uniform vec3 color; +in vec3 normal; void main() { - gl_FragColor = vec4(color, 1.0); + gl_FragColor = vec4(normal, 1.0); } \ No newline at end of file diff --git a/u06-2/main.c b/u06-2/main.c index abd322a..3100b00 100644 --- a/u06-2/main.c +++ b/u06-2/main.c @@ -19,7 +19,8 @@ GLuint program; GLuint vao; -GLuint cubeIndicesBufferObject; + +int numFaces = 0; bool exitRequested = false; @@ -30,51 +31,9 @@ GLfloat aspectRatio = 1.0f; GLfloat step = 0.0f; const GLfloat pi = 3.14159f; -vec3 cameraPosition = {0.0f, 0.0f, 2.0f}; - -GLfloat cube[] = { - 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, -1.0f, - 1.0f, -1.0f, 1.0f, - 1.0f, -1.0f, -1.0f, - -1.0f, 1.0f, 1.0f, - -1.0f, 1.0f, -1.0f, - -1.0f, -1.0f, 1.0f, - -1.0f, -1.0f, -1.0f -}; - -GLfloat ground[] = { - 1.0f, 0.0f, 1.0f, - 1.0f, 0.0f, -1.0f, - -1.0f, 0.0f, 0.0f, - -1.0f, 0.0f, -1.0f -}; - -GLuint cubeIndices[] = { - 0, 1, 2, - 1, 3, 2, - - 1, 7, 3, - 1, 5, 7, - - 4, 6, 5, - 5, 6, 7, - - 0, 2, 4, - 4, 2, 6, - - 7, 6, 3, - 6, 2, 3, - - 4, 5, 1, - 4, 1, 0 -}; - -GLuint groundIndices[] = { - 0, 1, 2, - 1, 3, 2 -}; +vec3 cameraPosition = {4.0f, 2.0f, 0.0f}; +// input handler for camera movement void handleInputs(void) { if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { cameraPosition.z += 0.02f; @@ -90,6 +49,7 @@ void handleInputs(void) { } } +// input handler to quit with ESC void keyboardHandler(GLFWwindow* window, int key, int scancode, int action, int mods) { if (action == GLFW_PRESS) { if (key == GLFW_KEY_ESCAPE) { @@ -98,6 +58,7 @@ void keyboardHandler(GLFWwindow* window, int key, int scancode, int action, int } } + void init(void) { // create and compile vertex shader const GLchar *vertexTextConst = vertexShader_glsl; @@ -165,12 +126,15 @@ void init(void) { } + // --------------- READ teapot.obj ParsedObjFile teapot = readObjFile("teapot.obj"); + numFaces = teapot.length; + // write teapot faces to buffer GLuint triangleVertexBufferObject; glGenBuffers(1, &triangleVertexBufferObject); glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBufferObject); - glBufferData(GL_ARRAY_BUFFER, sizeof(cube), cube, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, teapot.length * sizeof(face), teapot.faces, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -178,102 +142,68 @@ void init(void) { glGenVertexArrays(1, &vao); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBufferObject); + + // vertex positions glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, - sizeof(GLfloat) * 3, + sizeof(vertex), 0 ); glEnableVertexAttribArray(0); + + // vertex normals + glVertexAttribPointer( + 1, + 3, + GL_FLOAT, + GL_FALSE, + sizeof(vertex), + (void*) sizeof(vec3) + ); + glEnableVertexAttribArray(1); + glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); // ENABLE BACKFACE CULLING - glFrontFace(GL_CW); + glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); + // ENABLE DEPTH BUFFER + glEnable(GL_DEPTH_TEST); - // ENABLE RESTARTING - glEnable(GL_PRIMITIVE_RESTART); - glPrimitiveRestartIndex(RESTART); - - // DEFINE INDEX ARRAY FOR ELEMENT DRAWING - glGenBuffers(1, &cubeIndicesBufferObject); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cubeIndicesBufferObject); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndices), cubeIndices, GL_STATIC_DRAW); - - - glClearColor(0.1f, 0.1f, 0.1f, 1.0f); -} - -void drawCube(vec3* position, vec3* scaleVec, vec3* rotateVec) { - mat4 modelTransformation; - - identity(&modelTransformation); - - scale(&modelTransformation, &modelTransformation, scaleVec); - - rotateX(&modelTransformation, &modelTransformation, rotateVec->x); - rotateY(&modelTransformation, &modelTransformation, rotateVec->y); - rotateZ(&modelTransformation, &modelTransformation, rotateVec->z); - - translate(&modelTransformation, &modelTransformation, position); - - - glUniformMatrix4fv(glGetUniformLocation(program, "modelTransformation"), 1, GL_FALSE, (GLfloat*)&modelTransformation); - - glUniform3f(glGetUniformLocation(program, "color"), 1.0f, 0.0f, 0.0f); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)(0 * sizeof(GLuint))); - - glUniform3f(glGetUniformLocation(program, "color"), 1.0f, 1.0f, 0.0f); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)(6 * sizeof(GLuint))); - - glUniform3f(glGetUniformLocation(program, "color"), 1.0f, 1.0f, 1.0f); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)(12 * sizeof(GLuint))); - - glUniform3f(glGetUniformLocation(program, "color"), 0.0f, 1.0f, 1.0f); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)(18 * sizeof(GLuint))); - - glUniform3f(glGetUniformLocation(program, "color"), 0.0f, 0.0f, 1.0f); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)(24 * sizeof(GLuint))); - - glUniform3f(glGetUniformLocation(program, "color"), 1.0f, 0.0f, 1.0f); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)(30 * sizeof(GLuint))); + glClearColor(0.1f, 0.1f, 0.3f, 1.0f); } void draw(void) { + // camera movement handleInputs(); - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(program); glBindVertexArray(vao); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cubeIndicesBufferObject); + // step for rotations + // counts up to 1.0 and then resets back to 0.0 forever step += 0.002f; if (step > 1.0f) step -= 1.0f; + + // step multiplied by pi * 2 for use in rotation and trig functions GLfloat stepi = step * pi * 2; // ------------- MODEL TRANSFORMATION --------------------- // SCALE -> ROTATE -> TRANSLATE - // GLfloat cubePosition[3] = {0.0f, -2.0f, 0.0f}; - // GLfloat cubeScale[3] = {4.0f, 0.2f, 4.0f}; - - // GLfloat modelTransformation[16]; - // identity(modelTransformation); - // scale(modelTransformation, modelTransformation, cubeScale); - - // rotateY(modelTransformation, modelTransformation, stepi); - // rotateX(modelTransformation, modelTransformation, stepi + 1.0f); - // rotateZ(modelTransformation, modelTransformation, stepi + 0.5f); - - // translate(modelTransformation, modelTransformation, cubePosition); + mat4 modelTransformation; + identity(&modelTransformation); + rotateY(&modelTransformation, &modelTransformation, stepi); // ------------- VIEWING TRANSFORMATION ------------------- @@ -302,32 +232,21 @@ void draw(void) { mat4 globalTransformation; identity(&globalTransformation); + // V * P * N * M + // (right to left because it's more intuitive in my opinion) + multiply(&globalTransformation, &modelTransformation, &globalTransformation); multiply(&globalTransformation, &viewingTransformation, &globalTransformation); multiply(&globalTransformation, &projectionTransformation, &globalTransformation); multiply(&globalTransformation, &normalisationTransformation, &globalTransformation); + // send transformation matrix to shader glUniformMatrix4fv(glGetUniformLocation(program, "globalTransformation"), 1, GL_FALSE, (GLfloat*)&globalTransformation); - vec3 position = {0.0f, -3.0f, 0.0f}; - vec3 scaleVec = {3.0f, 0.1f, 3.0f}; - vec3 rotateVec = {0.0f, 0.0f, 0.0f}; - drawCube(&position, &scaleVec, &rotateVec); - - position.y = -2.8f; - scaleVec.x = 2.0f; - scaleVec.z = 2.0f; - rotateVec.x = pi; - drawCube(&position, &scaleVec, &rotateVec); - - position.y = -2.4f; - scaleVec.x = 1.0f; - scaleVec.y = 0.3f; - scaleVec.z = 1.0f; - rotateVec.x = 0; - rotateVec.y = stepi * 2; - drawCube(&position, &scaleVec, &rotateVec); + // draw!!1 + glDrawArrays(GL_TRIANGLES, 0, numFaces * 3); } +// change viewport size and adjust aspect ratio when changing window size void framebuffer_size_callback(GLFWwindow *window, int width, int height) { glViewport(0, 0, width, height); aspectRatio = (float)width / height; @@ -335,27 +254,7 @@ void framebuffer_size_callback(GLFWwindow *window, int width, int height) { int main(void) { - // GLfloat test[16] = { - // 1.0f, 2.0f, 3.0f, 4.0f, - // 5.0f, 6.0f, 7.0f, 8.0f, - // 9.0f, 1.0f, 2.0f, 3.0f, - // 4.0f, 5.0f, 6.0f, 7.0f - // }; - // transpose(test, test); - - // GLfloat test2[16] = { - // 0.0f, 1.0f, 0.0f, 1.0f, - // 1.0f, 2.0f, 1.0f, 2.0f, - // 2.0f, 3.0f, 2.0f, 3.0f, - // 3.0f, 4.0f, 3.0f, 4.0f - // }; - // transpose(test2, test2); - - // multiply(test, test, test2); - // mat4Print(test); - - // return 0; - + // initialise window glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); @@ -376,13 +275,14 @@ int main(void) { // register keyboard event handler glfwSetKeyCallback(window, keyboardHandler); + // initialise glew glewInit(); printf("OpenGL version supported by this platform (%s):\n", glGetString(GL_VERSION)); - init(); + // exit when window should close or exit is requested (ESC) while (!glfwWindowShouldClose(window) && !exitRequested) { draw(); diff --git a/u06-2/vertexShader.glsl b/u06-2/vertexShader.glsl index 6fcf2c8..83dacc8 100644 --- a/u06-2/vertexShader.glsl +++ b/u06-2/vertexShader.glsl @@ -1,8 +1,10 @@ #version 330 core layout (location = 0) in vec3 aPosition; +layout (location = 1) in vec3 aNormal; uniform mat4 globalTransformation; -uniform mat4 modelTransformation; +// uniform mat4 modelTransformation; +out vec3 normal; void main() { - // color = aPosition / 2 + vec3(0.5, 0.5, 0.5); - gl_Position = globalTransformation * modelTransformation * vec4(aPosition, 1.0); + normal = aNormal; + gl_Position = globalTransformation * vec4(aPosition, 1.0); } \ No newline at end of file diff --git a/u06-2/wavefrontobj.c b/u06-2/wavefrontobj.c index ef5c925..256451b 100644 --- a/u06-2/wavefrontobj.c +++ b/u06-2/wavefrontobj.c @@ -7,6 +7,19 @@ #define OBJ_LINE_BUFFER_SIZE 256 +/** + * + * SPECIFICALY MADE FOR teapot.obj + * ADJUSTMENT NEEDED FOR + * - Textures + * - Face Definitions other than vertex/texture/normal + * - Vertex positions including w + * - Any faces using vertices yet to be defined + * (File is read top to bottom. A face using a vertex + * defined underneath it in the file will not work) + * + */ + ParsedObjFile readObjFile(char* path) { ParsedObjFile parsedFile; @@ -14,7 +27,7 @@ ParsedObjFile readObjFile(char* path) { if (fp == NULL) { fprintf(stderr, "File could not be opened: %s", path); - parsedFile.vertices = NULL; + parsedFile.faces = NULL; parsedFile.length = 0; } @@ -42,10 +55,81 @@ ParsedObjFile readObjFile(char* path) { printf("Vertices: %d\nFaces: %d\nNormals:%d\nTextures:%d\n", numVertices, numFaces, numVertexNormals, numTextureCoords); + vec3* vertices = (vec3*) malloc(sizeof(vec3) * numVertices); + vec3* normals = (vec3*) malloc(sizeof(vec3) * numVertexNormals); + face* faces = (face*) malloc(sizeof(face) * numFaces); + + parsedFile.faces = faces; + parsedFile.length = numFaces; + + rewind(fp); + + uint curVertex = 0; + uint curNormal = 0; + uint curFace = 0; + + while (fgets(buf, OBJ_LINE_BUFFER_SIZE, fp)) { + if (buf[0] == 'v') { + if (buf[1] == ' ') { + + sscanf(buf, + "v %f %f %f", + &vertices[curVertex].x, + &vertices[curVertex].y, + &vertices[curVertex].z + ); + curVertex++; + + } else if (buf[1] == 't') { + continue; + } else if (buf[1] == 'n') { + + sscanf(buf, + "vn %f %f %f", + &normals[curNormal].x, + &normals[curNormal].y, + &normals[curNormal].z + ); + curNormal++; + + } + } + + if (buf[0] == 'f') { + int v1, v2, v3; + int vt1, vt2, vt3; + int vn1, vn2, vn3; + + sscanf(buf, + "f %d/%d/%d %d/%d/%d %d/%d/%d", + &v1, &vt1, &vn1, + &v2, &vt2, &vn2, + &v3, &vt3, &vn3 + ); + + memcpy(&faces[curFace].v1.position, &vertices[v1 - 1], sizeof(vec3)); + memcpy(&faces[curFace].v2.position, &vertices[v2 - 1], sizeof(vec3)); + memcpy(&faces[curFace].v3.position, &vertices[v3 - 1], sizeof(vec3)); + + memcpy(&faces[curFace].v1.normal, &normals[vn1 - 1], sizeof(vec3)); + memcpy(&faces[curFace].v2.normal, &normals[vn2 - 1], sizeof(vec3)); + memcpy(&faces[curFace].v3.normal, &normals[vn3 - 1], sizeof(vec3)); + + curFace++; + + // TODO: textures + } + + } + + free(vertices); + free(normals); fclose(fp); + + return parsedFile; } void clearParsedFile(ParsedObjFile file) { - free(file.vertices); + free(file.faces); } \ No newline at end of file diff --git a/u06-2/wavefrontobj.h b/u06-2/wavefrontobj.h index 1d034fb..72a59b6 100644 --- a/u06-2/wavefrontobj.h +++ b/u06-2/wavefrontobj.h @@ -6,13 +6,17 @@ typedef struct { vec3 position; - vec3 texture; vec3 normal; } vertex; +typedef struct { + vertex v1; + vertex v2; + vertex v3; +} face; typedef struct { - vertex* vertices; + face* faces; GLuint length; } ParsedObjFile;