/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* run.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: gbrochar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/12/23 19:38:05 by gbrochar #+# #+# */ /* Updated: 2024/04/25 16:33:52 by gbrochar ### ########.fr */ /* */ /* ************************************************************************** */ #include "scop.h" #include "mat4.h" #include "vec3.h" #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" GLuint VBO; //GLuint IBO; GLuint gScaleLocation; GLuint gTimeLocation; GLuint gProjLocation; GLuint gViewLocation; GLuint gModelLocation; GLuint gNormalLocation; GLuint has_texture_location; //GLuint gCountLocation; GLuint index_count; int is_good; GLuint gSamplerLocation; GLuint texture; 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 time = 0.0f; time += 0.01f; t_vec3 eye; t_vec3 up; t_vec3 target; eye.x = 0; eye.y = 0; eye.z = 2; up.x = 0; up.y = 1; up.z = 0; target.x = 0; target.y = 0; target.z = 0; t_mat4 proj = mat4_perspective(45.0 * M_PI / 180.0, 800.0 / 600.0, 0.001, 100); 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); t_mat4 normal = mat4_transpose(mat4_inverse(mat4_multiply(view, model))); glUniform1f(gTimeLocation, time); glUniformMatrix4fv(gProjLocation, 1, GL_FALSE, (GLfloat *)proj.data); glUniformMatrix4fv(gViewLocation, 1, GL_FALSE, (GLfloat *)view.data); glUniformMatrix4fv(gModelLocation, 1, GL_FALSE, (GLfloat *)model.data); glUniformMatrix4fv(gNormalLocation, 1, GL_FALSE, (GLfloat *)normal.data); //glUniform1i(gCountLocation, index_count); glUniform1i(gSamplerLocation, 0); glUniform1i(has_texture_location, is_good); glActiveTexture(GL_TEXTURE0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, VBO); glVertexAttribPointer(0, 3, GL_DOUBLE, GL_FALSE, 8 * sizeof(double), 0); if (is_good) { glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_DOUBLE, GL_FALSE, 8 * sizeof(double), (void *)(3 * sizeof(double))); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 3, GL_DOUBLE, GL_FALSE, 8 * sizeof(double), (void *)(5 * sizeof(double))); } glDrawArrays(GL_TRIANGLES, 0, index_count); //glBindTexture(GL_TEXTURE_2D, texture); //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); //glDrawElements(GL_TRIANGLES, index_count * 3, GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); } static void CreateVertexBuffer(t_env *e) { printf("status of different buffers:\n"); printf("vertices len %ld\n", e->object.vertices.ptr); printf("uv len %ld\n", e->object.uvs.ptr); printf("normals len %ld\n", e->object.normals.ptr); printf("vertices indices len %ld\n", e->object.vertices_indices.ptr); printf("uvs indices len %ld\n", e->object.uvs_indices.ptr); printf("normals indices len %ld\n", e->object.normals_indices.ptr); is_good = 1; e->vbo_data = (double *)malloc(e->object.vertices_indices.ptr * 8 * sizeof(double)); for (size_t i = 0; i < e->object.vertices_indices.ptr * 8; i += 8) { e->vbo_data[i] = e->object.vertices.data[e->object.vertices_indices.data[i / 8] * 3]; e->vbo_data[i + 1] = e->object.vertices.data[e->object.vertices_indices.data[i / 8] * 3 + 1]; e->vbo_data[i + 2] = e->object.vertices.data[e->object.vertices_indices.data[i / 8] * 3 + 2]; if (e->object.uvs_indices.ptr == e->object.vertices_indices.ptr && e->object.uvs_indices.data[i / 8] * 2 + 1 < e->object.uvs.ptr) { e->vbo_data[i + 3] = e->object.uvs.data[e->object.uvs_indices.data[i / 8] * 2]; e->vbo_data[i + 4] = e->object.uvs.data[e->object.uvs_indices.data[i / 8] * 2 + 1]; } else { is_good = 0; } if (e->object.normals_indices.ptr == e->object.vertices_indices.ptr && e->object.normals_indices.data[i / 8] * 3 + 2 < e->object.normals.ptr) { e->vbo_data[i + 5] = e->object.normals.data[e->object.normals_indices.data[i / 8] * 3]; e->vbo_data[i + 6] = e->object.normals.data[e->object.normals_indices.data[i / 8] * 3 + 1]; e->vbo_data[i + 7] = e->object.normals.data[e->object.normals_indices.data[i / 8] * 3 + 2]; } else { is_good = 0; } } glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, e->object.vertices_indices.ptr * 8 * sizeof(double), e->vbo_data, GL_STATIC_DRAW); printf("Buffer created with success !\n"); /* 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.vertices_indices.ptr * sizeof(int), e->object.vertices_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"); gTimeLocation = glGetUniformLocation(e->shader_program, "time"); gProjLocation = glGetUniformLocation(e->shader_program, "proj"); gViewLocation = glGetUniformLocation(e->shader_program, "view"); gModelLocation = glGetUniformLocation(e->shader_program, "model"); gNormalLocation = glGetUniformLocation(e->shader_program, "normalMat"); gSamplerLocation = glGetUniformLocation(e->shader_program, "ourTexture"); has_texture_location = glGetUniformLocation(e->shader_program, "has_texture"); // assert(gScaleLocation != 0xFFFFFFFF); assert(gTimeLocation != 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 *= 1.03; if (key == GLFW_KEY_J && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->scale.x *= 0.97; if (key == GLFW_KEY_I && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->scale.y *= 1.03; if (key == GLFW_KEY_K && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->scale.y *= 0.97; if (key == GLFW_KEY_O && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->scale.z *= 1.03; if (key == GLFW_KEY_L && (action == GLFW_PRESS || action == GLFW_REPEAT)) e->scale.z *= 0.97; (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.vertices_indices.ptr; printf("%ld\n", e->object.vertices.ptr); printf("%ld\n", e->object.vertices_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); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); int tex_width, tex_height, nrChannels; unsigned char *tex_data = stbi_load("resources/fox.jpg", &tex_width, &tex_height, &nrChannels, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex_width, tex_height, 0, GL_RGB, GL_UNSIGNED_BYTE, tex_data); glGenerateMipmap(GL_TEXTURE_2D); stbi_image_free(tex_data); 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); }