/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* run.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: gbrochar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/12/23 19:38:05 by gbrochar #+# #+# */ /* Updated: 2020/12/26 09:47:39 by gbrochar ### ########.fr */ /* */ /* ************************************************************************** */ #include "scop.h" #include "mat4.h" #include "vec3.h" GLuint VBO; GLuint IBO; GLuint gScaleLocation; GLuint gScaleIntLocation; GLuint gProjLocation; GLuint gViewLocation; GLuint gModelLocation; GLuint gCountLocation; GLuint index_count; const char* pVSFileName = "src/shader.vs"; const char* pFSFileName = "src/shader.fs"; static void RenderSceneCB(t_env *e) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); static float Scale = 0.0f; Scale += 0.01f; t_vec3 eye; t_vec3 up; t_vec3 target; eye.x = 0; eye.y = 0; eye.z = 10; up.x = 0; up.y = 1; up.z = 0; target.x = 0; target.y = 0; target.z = 9; t_mat4 proj = mat4_perspective(45.0 * M_PI / 180.0, 800.0 / 600.0, 0.001, 1000); t_mat4 view = mat4_inverse(mat4_lookat(eye, up, target)); // t_mat4 model = mat4_rotatey(mat4_rotatex(mat4_identity(), Scale), Scale / 1.3); //t_mat4 model = mat4_rotatey(mat4_identity(), Scale); t_mat4 model = mat4_scale( mat4_rotatexyz( mat4_translate(mat4_identity(), e->translate), e->rotate), e->scale); glUniform1f(gScaleIntLocation, Scale); glUniformMatrix4fv(gProjLocation, 1, GL_FALSE, (GLfloat *)proj.data); glUniformMatrix4fv(gViewLocation, 1, GL_FALSE, (GLfloat *)view.data); glUniformMatrix4fv(gModelLocation, 1, GL_FALSE, (GLfloat *)model.data); glUniform1i(gCountLocation, index_count); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, VBO); glVertexAttribPointer(0, 3, GL_DOUBLE, GL_FALSE, 0, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(0); } static void CreateVertexBuffer(t_env *e) { glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, e->object.vertices.ptr * sizeof(double), e->object.vertices.data, GL_STATIC_DRAW); glGenBuffers(1, &IBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, e->object.indices.ptr * sizeof(int), e->object.indices.data, GL_STATIC_DRAW); } static void AddShader(GLuint ShaderProgram, const char* pShaderText, GLenum ShaderType, GLuint *shader) { *shader = glCreateShader(ShaderType); if (*shader == 0) { fprintf(stderr, "Error creating shader type %d\n", ShaderType); exit(0); } const GLchar* p[1]; p[0] = pShaderText; GLint Lengths[1]; Lengths[0] = strlen(pShaderText); glShaderSource(*shader, 1, p, Lengths); glCompileShader(*shader); GLint success; glGetShaderiv(*shader, GL_COMPILE_STATUS, &success); if (!success) { GLchar InfoLog[1024]; glGetShaderInfoLog(*shader, 1024, NULL, InfoLog); fprintf(stderr, "Error compiling shader type %d: '%s'\n", ShaderType, InfoLog); exit(1); } glAttachShader(ShaderProgram, *shader); } static void CompileShaders(t_env *e) { e->shader_program = glCreateProgram(); if (e->shader_program == 0) { fprintf(stderr, "Error creating shader program\n"); exit(1); } char *vs = (char *)malloc(BUFFER_SIZE * sizeof(char)); char *fs = (char *)malloc(BUFFER_SIZE * sizeof(char)); char *buffer = (char *)malloc(BUFFER_SIZE * sizeof(char)); FILE *fp; vs[0] = '\0'; fs[0] = '\0'; fp = fopen(pVSFileName, "r"); while (fgets(buffer, 4096, fp)) { buffer[strcspn(buffer, "\n") + 1] = '\0'; strcat(vs, buffer); } fclose(fp); fp = fopen(pFSFileName, "r"); while (fgets(buffer, 4096, fp)) { buffer[strcspn(buffer, "\n") + 1] = '\0'; strcat(fs, buffer); } fclose(fp); AddShader(e->shader_program, vs, GL_VERTEX_SHADER, &(e->vertex_shader)); AddShader(e->shader_program, fs, GL_FRAGMENT_SHADER, &(e->fragment_shader)); GLint Success = 0; GLchar ErrorLog[1024] = { 0 }; glLinkProgram(e->shader_program); glGetProgramiv(e->shader_program, GL_LINK_STATUS, &Success); if (Success == 0) { glGetProgramInfoLog(e->shader_program, sizeof(ErrorLog), NULL, ErrorLog); fprintf(stderr, "Error linking shader program : '%s'\n", ErrorLog); exit(1); } glValidateProgram(e->shader_program); glGetProgramiv(e->shader_program, GL_VALIDATE_STATUS, &Success); if (!Success) { glGetProgramInfoLog(e->shader_program, sizeof(ErrorLog), NULL, ErrorLog); fprintf(stderr, "Invalid shader program '%s'\n", ErrorLog); exit(1); } glUseProgram(e->shader_program); // gScaleLocation = glGetUniformLocation(e->shader_program, "gScale"); gScaleIntLocation = glGetUniformLocation(e->shader_program, "time"); gProjLocation = glGetUniformLocation(e->shader_program, "proj"); gViewLocation = glGetUniformLocation(e->shader_program, "view"); gModelLocation = glGetUniformLocation(e->shader_program, "model"); // assert(gScaleLocation != 0xFFFFFFFF); assert(gScaleIntLocation != 0xFFFFFFFF); assert(gProjLocation != 0xFFFFFFFF); assert(gViewLocation != 0xFFFFFFFF); assert(gModelLocation != 0xFFFFFFFF); free(buffer); free(vs); free(fs); } void free_shaders(t_env *e) { glDetachShader(e->shader_program, e->vertex_shader); glDetachShader(e->shader_program, e->fragment_shader); glDeleteShader(e->vertex_shader); glDeleteShader(e->fragment_shader); glUseProgram(0); glDeleteProgram(e->shader_program); } void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) { t_env *e = (t_env *)glfwGetWindowUserPointer(window); if (key == GLFW_KEY_Q && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->translate.x += 0.03; if (key == GLFW_KEY_A && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->translate.x -= 0.03; if (key == GLFW_KEY_W && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->translate.y += 0.03; if (key == GLFW_KEY_S && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->translate.y -= 0.03; if (key == GLFW_KEY_E && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->translate.z += 0.03; if (key == GLFW_KEY_D && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->translate.z -= 0.03; if (key == GLFW_KEY_R && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->rotate.x += 0.03; if (key == GLFW_KEY_F && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->rotate.x -= 0.03; if (key == GLFW_KEY_T && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->rotate.y += 0.03; if (key == GLFW_KEY_G && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->rotate.y -= 0.03; if (key == GLFW_KEY_Y && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->rotate.z += 0.03; if (key == GLFW_KEY_H && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->rotate.z -= 0.03; if (key == GLFW_KEY_U && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->scale.x += 0.03; if (key == GLFW_KEY_J && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->scale.x -= 0.03; if (key == GLFW_KEY_I && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->scale.y += 0.03; if (key == GLFW_KEY_K && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->scale.y -= 0.03; if (key == GLFW_KEY_O && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->scale.z += 0.03; if (key == GLFW_KEY_L && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->scale.z -= 0.03; (void)scancode; (void)mods; } int run(t_env *e) { GLFWwindow* window; /* Initialize the library */ if (!glfwInit()) return (FAILURE); /* Create a windowed mode window and its OpenGL context */ window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL); glfwSetWindowUserPointer(window, e); glfwSetKeyCallback(window, key_callback); if (!window) { glfwTerminate(); return (FAILURE); } glfwMakeContextCurrent(window); index_count = e->object.indices.ptr; printf("%ld\n", e->object.vertices.ptr); printf("%ld\n", e->object.indices.ptr); GLenum res = glewInit(); if (res != GLEW_OK) { fprintf(stderr, "Error : '%s'\n", glewGetErrorString(res)); exit (1); } printf("GL version: %s\n", glGetString(GL_VERSION)); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); CreateVertexBuffer(e); CompileShaders(e); /* Loop until the user closes the window */ while (!glfwWindowShouldClose(window)) { /* Render here */ glClear(GL_COLOR_BUFFER_BIT); RenderSceneCB(e); /* Swap front and back buffers */ glfwSwapBuffers(window); /* Poll for and process events */ glfwPollEvents(); } free_shaders(e); glfwTerminate(); return (SUCCESS); }