teapot baby

This commit is contained in:
Luca Conte 2024-04-25 16:39:08 +02:00
parent d4c350721e
commit 14ff26f1e3
5 changed files with 147 additions and 157 deletions

View File

@ -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);
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;