diff --git a/inc/scop.h b/inc/scop.h index 8e66e45..342f3f2 100644 --- a/inc/scop.h +++ b/inc/scop.h @@ -28,6 +28,10 @@ typedef enum e_gl_buf_type t_gl_buf_type; +# define VERTEX_FLAG 1 << 0 +# define UV_FLAG 1 << 1 +# define NORMAL_FLAG 1 << 2 + enum e_gl_buf_type { VERTEX, UV, @@ -75,10 +79,12 @@ struct s_obj { t_buf_ui vertices_indices; t_buf_ui uvs_indices; t_buf_ui normals_indices; + unsigned int properties; }; struct s_env { char *file_name; + char *texture_file_name; t_cam camera; t_window window; t_obj object; diff --git a/resources/poney.jpg b/resources/poney.jpg new file mode 100644 index 0000000..358ea6b Binary files /dev/null and b/resources/poney.jpg differ diff --git a/src/env.c b/src/env.c index 8a779f0..3e70efe 100644 --- a/src/env.c +++ b/src/env.c @@ -33,7 +33,7 @@ void init_camera(t_env *e) { e->camera.fov = 45; e->camera.near = 0.001; - e->camera.far = 1000; + e->camera.far = 100; e->camera.aspect = 1; } @@ -75,11 +75,18 @@ void init_transformations(t_env *e) e->scale.z = 1; } +void init_shader_params(t_env *e) { + e->texture = false; + e->lighting = false; + e->rotating = true; +} + void init_env(t_env *e) { init_window(e); init_camera(e); init_object(e); init_transformations(e); + init_shader_params(e); } diff --git a/src/parse_file.c b/src/parse_file.c index 9a88ae9..4d739bc 100644 --- a/src/parse_file.c +++ b/src/parse_file.c @@ -38,11 +38,17 @@ void set_params(t_env *e, int argc, char **argv) else e->file_name = strdup("resources/42.obj"); if (argc >= 3) - e->window.width = atof(argv[2]); + e->texture_file_name = strdup(argv[2]); + else + e->texture_file_name = strdup("resources/poney.jpg"); if (argc >= 4) - e->window.height = atof(argv[3]); + e->window.width = atoi(argv[3]); if (argc >= 5) - e->camera.fov = atof(argv[4]); + e->window.height = atoi(argv[4]); + if (argc >= 6) + e->camera.fov = atof(argv[5]); + e->window.width = e->window.width < 640 ? 640 : e->window.width; + e->window.height = e->window.height < 480 ? 480 : e->window.height; e->camera.aspect = (double)e->window.width / (double)e->window.height; } diff --git a/src/parse_line.c b/src/parse_line.c index 7c5731b..baaa858 100644 --- a/src/parse_line.c +++ b/src/parse_line.c @@ -48,7 +48,29 @@ void parse_triangulate(t_buf_ui *indices, int vertex_count) unsigned int *data_tmp; int i; - printf("vertex count : %d\n", vertex_count); + i = 0; + data_tmp = (unsigned int *)malloc( + sizeof(unsigned int) * 3 * (vertex_count - 2)); + indices->ptr -= vertex_count; + while (i < 3 * (vertex_count - 2)) + { + if (i % 3 == 0) + data_tmp[i] = indices->data[indices->ptr]; + else if (i % 3 == 1) + data_tmp[i] = indices->data[indices->ptr + (i - 1) / 3 + 1]; + else if (i % 3 == 2) + data_tmp[i] = indices->data[indices->ptr + (i - 2) / 3 + 2]; + i++; + } + parse_append_data_tmp(indices, vertex_count, data_tmp); + free(data_tmp); +} + +void parse_triangulate2(t_buf_ui *indices, int vertex_count) +{ + unsigned int *data_tmp; + int i; + i = 0; data_tmp = (unsigned int *)malloc( sizeof(unsigned int) * 3 * (vertex_count - 2)); @@ -68,8 +90,11 @@ void parse_triangulate(t_buf_ui *indices, int vertex_count) } void parse_triangulate_dispatcher(t_env *e, int vertex_count) { + if (e->object.properties & VERTEX_FLAG) parse_triangulate(&(e->object.vertices_indices), vertex_count); - parse_triangulate(&(e->object.uvs_indices), vertex_count); + if (e->object.properties & UV_FLAG) + parse_triangulate2(&(e->object.uvs_indices), vertex_count); + if (e->object.properties & NORMAL_FLAG) parse_triangulate(&(e->object.normals_indices), vertex_count); } @@ -91,6 +116,7 @@ int parse_line(t_env *e, char *line) token_count = 0; ret = SUCCESS; strtrim(line); + e->object.properties = 0; while ((token = strtok_r(line, " \t", &line))) { if (token_count == 0) diff --git a/src/parse_token.c b/src/parse_token.c index ae09b4a..085b07b 100644 --- a/src/parse_token.c +++ b/src/parse_token.c @@ -44,13 +44,16 @@ int parse_append_data_index(t_env *e, char *phrase) { int ret; while ((token = strtok_r(phrase, "/", &phrase))) { - if (token_count == 0) { + if (strlen(token) > 0 && token_count == 0) { + e->object.properties |= VERTEX_FLAG; ret = parse_append_data_ui(&(e->object.vertices_indices), token); } - else if (token_count == 1) { + else if (strlen(token) > 0 && token_count == 1) { + e->object.properties |= UV_FLAG; ret = parse_append_data_ui(&(e->object.uvs_indices), token); } - else if (token_count == 2) { + else if (strlen(token) > 0 && token_count == 2) { + e->object.properties |= NORMAL_FLAG; ret = parse_append_data_ui(&(e->object.normals_indices), token); } token_count++; diff --git a/src/run.c b/src/run.c index 6bd7182..64aebe8 100644 --- a/src/run.c +++ b/src/run.c @@ -25,9 +25,10 @@ GLuint gProjLocation; GLuint gViewLocation; GLuint gModelLocation; GLuint gNormalLocation; -GLuint has_texture_location; GLuint texture_level_location; GLuint lighting_location; +GLuint has_uvs_location; +GLuint has_normals_location; //GLuint gCountLocation; GLuint index_count; @@ -62,20 +63,22 @@ static void RenderSceneCB(t_env *e) 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 proj = mat4_perspective(e->camera.fov * M_PI / 180.0, e->camera.aspect, e->camera.near, e->camera.far); 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); if (e->rotating == true) { e->rotate.y += 0.01; - //mat4_rotatey(e->rotate, 0.01); } if (e->texture == true) { e->texture_level += 0.006; if (e->texture_level > 1) { e->texture_level = 1; } + } else { + e->texture_level -= 0.006; + if (e->texture_level < 0) { + e->texture_level = 0; + } } t_mat4 model = mat4_scale( mat4_rotatexyz( @@ -89,7 +92,8 @@ static void RenderSceneCB(t_env *e) //glUniform1i(gCountLocation, index_count); glActiveTexture(GL_TEXTURE0); glUniform1i(gSamplerLocation, 0); - glUniform1i(has_texture_location, e->texture); + glUniform1i(has_uvs_location, e->object.uvs.ptr); + glUniform1i(has_normals_location, e->object.normals.ptr); glUniform1f(texture_level_location, e->texture_level); glUniform1i(lighting_location, e->lighting); @@ -97,14 +101,14 @@ static void RenderSceneCB(t_env *e) glBindBuffer(GL_ARRAY_BUFFER, VBO); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), 0); - //if (e->texture) { + if (is_good) { glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(3 * sizeof(float))); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(5 * sizeof(float))); //glBindTexture(GL_TEXTURE_2D, texture); - //} + } //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); //glDrawElements(GL_TRIANGLES, index_count * 3, GL_UNSIGNED_INT, 0); @@ -129,9 +133,11 @@ static void CreateVertexBuffer(t_env *e) exit(0); } 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.vertices_indices.data[i / 8] * 3 + 2 < e->object.vertices.ptr) { + 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]; @@ -151,13 +157,13 @@ static void CreateVertexBuffer(t_env *e) glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, e->object.vertices_indices.ptr * 8 * sizeof(float), 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); - */ + /* 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) @@ -253,7 +259,8 @@ static void CompileShaders(t_env *e) 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"); + has_uvs_location = glGetUniformLocation(e->shader_program, "has_uvs"); + has_normals_location = glGetUniformLocation(e->shader_program, "has_normals"); texture_level_location = glGetUniformLocation(e->shader_program, "texture_level"); lighting_location = glGetUniformLocation(e->shader_program, "lighting"); // assert(gScaleLocation != 0xFFFFFFFF); @@ -283,9 +290,6 @@ void key_callback(GLFWwindow *window, int key, int scancode, int action, int m e->rotating = !e->rotating; if (key == GLFW_KEY_B && (action == GLFW_PRESS)) { e->texture = !e->texture; - if (e->texture == true) { - e->texture_level = 0; - } } if (key == GLFW_KEY_V && (action == GLFW_PRESS)) { e->lighting = !e->lighting; @@ -339,7 +343,8 @@ int run(t_env *e) return (FAILURE); /* Create a windowed mode window and its OpenGL context */ - window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL); + //glfwWindowHint(GLFW_STEREO, GLFW_TRUE); + window = glfwCreateWindow(e->window.width, e->window.height, "Hello World", NULL, NULL); glfwSetWindowUserPointer(window, e); glfwSetKeyCallback(window, key_callback); if (!window) @@ -372,7 +377,7 @@ int run(t_env *e) int tex_width, tex_height, nrChannels; - unsigned char *tex_data = stbi_load("resources/42_5.png", &tex_width, &tex_height, &nrChannels, 0); + unsigned char *tex_data = stbi_load(e->texture_file_name, &tex_width, &tex_height, &nrChannels, 0); printf("number of channels : %d\n", nrChannels); if (nrChannels == 4) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data); diff --git a/src/shader.fs b/src/shader.fs index 18e2c87..631d6ef 100644 --- a/src/shader.fs +++ b/src/shader.fs @@ -2,9 +2,10 @@ uniform float time; uniform sampler2D ourTexture; -uniform int has_texture; uniform float texture_level; uniform int lighting; +uniform int has_uvs; +uniform int has_normals; out vec4 FragColor; flat in int vID; @@ -20,12 +21,19 @@ float rand(float n) void main() { - vec3 color = vec3(rand(float(vID + int(time))), rand(float(vID + int(time))), rand(float(vID + int(time)))); - if (has_texture == 1) { - color = color * (1 - texture_level) + texture_level * texture(ourTexture, vec2(texCoord.x, 1.- texCoord.y)).rgb; - + vec3 triangle_color = vec3(rand(float(vID + int(time))), rand(float(vID + int(time))), rand(float(vID + int(time)))) * (1 - texture_level); + vec3 texture_color; + if (has_uvs > 0) { + texture_color = texture_level * texture(ourTexture, vec2(texCoord.x, 1.- texCoord.y)).rgb; } - if (lighting == 1) { + else { + texture_color = texture_level * texture(ourTexture, position.yz).rgb; + if (abs(position.x) < 0.077) { + texture_color = texture_level * texture(ourTexture, position.xy).rgb; + } + } + vec3 color = triangle_color + texture_color; + if (has_normals > 0 && lighting == 1) { vec3 n = normalize(vec3(10. * cos(time), 10., 10. * sin(time)) - position); float ambient = 0.2; float phong = max(0., dot(n, normalize(normal)));