290 lines
8.9 KiB
C
290 lines
8.9 KiB
C
/* ************************************************************************** */
|
|
/* */
|
|
/* ::: :::::::: */
|
|
/* run.c :+: :+: :+: */
|
|
/* +:+ +:+ +:+ */
|
|
/* By: gbrochar <gbrochar@student.42.fr> +#+ +:+ +#+ */
|
|
/* +#+#+#+#+#+ +#+ */
|
|
/* 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);
|
|
} |