#include #include #include #include "vertexShader.c" #include "fragmentShader.c" #include "matrixMath.h" #include "transformation.h" #include #include #include #include #define RESTART 345678 GLuint program; GLuint vao; GLuint cubeIndicesBufferObject; bool exitRequested = false; GLFWwindow* window; GLfloat aspectRatio = 1.0f; GLfloat step = 0.0f; const GLfloat pi = 3.14159f; GLfloat cameraPosition[3] = {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 }; void handleInputs(void) { if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { cameraPosition[2] += 0.02f; } if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { cameraPosition[2] -= 0.02f; } if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) { cameraPosition[1] += 0.02f; } if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) { cameraPosition[1] -= 0.02f; } } void keyboardHandler(GLFWwindow* window, int key, int scancode, int action, int mods) { if (action == GLFW_PRESS) { if (key == GLFW_KEY_ESCAPE) { exitRequested = true; } } } void init(void) { // create and compile vertex shader const GLchar *vertexTextConst = vertexShader_glsl; GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexTextConst, &vertexShader_glsl_len); glCompileShader(vertexShader); GLint status; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status); if (!status) { printf("Error compiling vertex shader: "); GLchar infoLog[1024]; glGetShaderInfoLog(vertexShader, 1024, NULL, infoLog); printf("%s",infoLog); } 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); } // 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); } glValidateProgram(program); glGetProgramiv(program, GL_VALIDATE_STATUS, &status); if (!status) { printf("Error validating program: "); GLchar infoLog[1024]; glGetProgramInfoLog(program, 1024, NULL, infoLog); printf("%s",infoLog); } GLuint triangleVertexBufferObject; glGenBuffers(1, &triangleVertexBufferObject); glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBufferObject); glBufferData(GL_ARRAY_BUFFER, sizeof(cube), cube, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); // create vertex array object glGenVertexArrays(1, &vao); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBufferObject); glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0 ); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); // ENABLE BACKFACE CULLING glFrontFace(GL_CW); glEnable(GL_CULL_FACE); // 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(GLfloat* position, GLfloat* scaleVec, GLfloat* rotateVec) { GLfloat modelTransformation[16]; identity(modelTransformation); scale(modelTransformation, modelTransformation, scaleVec); rotateX(modelTransformation, modelTransformation, rotateVec[0]); rotateY(modelTransformation, modelTransformation, rotateVec[1]); rotateZ(modelTransformation, modelTransformation, rotateVec[2]); translate(modelTransformation, modelTransformation, position); glUniformMatrix4fv(glGetUniformLocation(program, "modelTransformation"), 1, GL_FALSE, 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))); } void draw(void) { handleInputs(); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(program); glBindVertexArray(vao); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cubeIndicesBufferObject); step += 0.002f; if (step > 1.0f) step -= 1.0f; 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); // ------------- VIEWING TRANSFORMATION ------------------- GLfloat origin[3] = {0.0f, 0.0f, 0.0f}; GLfloat up[3] = {0.0f, 1.0f, 0.0f}; GLfloat viewingTransformation[16]; GLfloat fixedCameraPosition[3] = {cos(stepi) * 4.0f, 1.5f, sin(stepi) * 4.0f}; lookAt(viewingTransformation, fixedCameraPosition, origin, up); // -------------- PROJECTION TRANSFORMATION ---------------- GLfloat projectionTransformation[16]; GLfloat near = 0.1f; GLfloat far = 5.0f; perspectiveProjection(projectionTransformation, near, far); // -------------- NORMALISATION TRANSFORMATION ------------- GLfloat normalisationTransformation[16]; GLfloat r = 0.2f; GLfloat l = -0.2f; GLfloat t = 0.2f; GLfloat b = -0.2f; normalisedDeviceCoordinates(normalisationTransformation, r, l, t, b, near, far); // --------------- LAZY ASPECT RATIO ADJUSTMENT ------------ GLfloat aspectScale[16]; GLfloat aspectScaleVector[3] = {1.0f / aspectRatio, 1.0f, 1.0f}; scaling(aspectScale, aspectScaleVector); GLfloat globalTransformation[16]; identity(globalTransformation); multiply(globalTransformation, viewingTransformation, globalTransformation); multiply(globalTransformation, projectionTransformation, globalTransformation); multiply(globalTransformation, normalisationTransformation, globalTransformation); multiply(globalTransformation, aspectScale, globalTransformation); glUniformMatrix4fv(glGetUniformLocation(program, "globalTransformation"), 1, GL_FALSE, globalTransformation); GLfloat position[3] = {0.0f, -2.0f, 0.0f}; GLfloat scaleVec[3] = {3.0f, 0.2f, 3.0f}; GLfloat rotateVec[3] = {0.0f, 0.0f, 0.0f}; for (int i=0; i < 10; i++) { position[1] += 0.4; rotateVec[1] += 0.2; scaleVec[0] -= 0.3; scaleVec[2] -= 0.3; drawCube(position, scaleVec, rotateVec); } } void framebuffer_size_callback(GLFWwindow *window, int width, int height) { glViewport(0, 0, width, height); aspectRatio = (float)width / 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; 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; } glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glfwMakeContextCurrent(window); // register keyboard event handler glfwSetKeyCallback(window, keyboardHandler); glewInit(); printf("OpenGL version supported by this platform (%s):\n", glGetString(GL_VERSION)); init(); while (!glfwWindowShouldClose(window) && !exitRequested) { draw(); glfwSwapBuffers(window); glfwPollEvents(); } glfwTerminate(); return 0; }