#define STB_IMAGE_IMPLEMENTATION #include "mesh.h" #include "shader.h" #include "window.h" #include "camera.h" #include "texture.h" #include "light.h" #include "material.h" static const char *vertex_shader_code = "shaders/shader.vert"; static const char *fragment_shader_code = "shaders/shader.frag"; int main() { Mesh *meshes[10] = {nullptr}; Shader shaders[10]; Window window(1024, 720); bool success = setup_window(&window); // Delta f32 dt = 0.0f; f32 last_dt = 0.f; { // Create a mesh f32 vertices[] = { // x y z u v nx ny nz -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f }; u32 indices[] = { 0, 3, 1, 1, 3, 2, 2, 3, 0, 0, 1, 2 }; calculate_normals_avg(vertices, 32, 8, indices, 12, 5); Mesh *pyramid1 = new Mesh(); create_mesh(pyramid1, vertices, indices, 32, 12); meshes[0] = pyramid1; Mesh *pyramid2 = new Mesh(); create_mesh(pyramid2, vertices, indices, 32, 12); meshes[1] = pyramid2; } { // Create a shader Shader *shader = new Shader(); create_shader(shader, vertex_shader_code, fragment_shader_code); shaders[0] = *shader; } Texture clay_texture = Texture((char *)"assets/textures/clay_texture_1k.png"); load_texture(&clay_texture); Texture plaster_texture = Texture((char *)"assets/textures/plaster_texture_1k.png"); load_texture(&plaster_texture); Material shiny_material(1.0f, 32.0f); Material dull_material(0.3f, 4.0f); Light sun_light(Vector3(1.0f, 1.0f, 1.0f), 0.2f, Vector3(2.0f, -1.0, -2.0f), 1.0f); Matrix4 projection = glm::perspective(45.0f, (f32)window.buffer_width / (f32)window.buffer_height, 0.1f, 100.0f); Camera camera(Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 1.0f, 0.0f), 90.0f, 0.0f, 5.0f, 1.0f); // Loop until window is closed while (!glfwWindowShouldClose(window.gl_window)) { // Calculate delta f32 now = glfwGetTime(); dt = now - last_dt; last_dt = now; key_control(&camera, window.ascii_keys, dt); mouse_control(&camera, window.x_change_position, window.y_change_position); // This sucks window.x_change_position = 0.0f; window.y_change_position = 0.0f; // Clear window glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(shaders[0].id); use_light( &sun_light, shaders[0].uniform_ambient_color, shaders[0].uniform_ambient_intensity, shaders[0].uniform_diffuse_direction, shaders[0].uniform_diffuse_intensity ); glUniformMatrix4fv(shaders[0].uniform_projection, 1, GL_FALSE, glm::value_ptr(projection)); Matrix4 view = calculate_view_matrix(&camera); glUniformMatrix4fv(shaders[0].uniform_view, 1, GL_FALSE, glm::value_ptr(view)); glUniform3f(shaders[0].uniform_eye_position, camera.position.x, camera.position.y, camera.position.z); { Matrix4 model(1.0f); model = glm::translate(model, Vector3(0.0f, 3.0f, 2.5f)); // model = glm::scale(model, Vector3(0.4f, 0.4f, 1.0f)); glUniformMatrix4fv(shaders[0].uniform_model, 1, GL_FALSE, glm::value_ptr(model)); use_texture(&clay_texture); use_material(&shiny_material, shaders[0].uniform_shininess, shaders[0].uniform_specular_intensity); render_mesh(meshes[0]); } { Matrix4 model(1.0f); model = glm::translate(model, Vector3(0.0f, 0.0f, 3.5f)); glUniformMatrix4fv(shaders[0].uniform_model, 1, GL_FALSE, glm::value_ptr(model)); use_texture(&plaster_texture); use_material(&dull_material, shaders[0].uniform_shininess, shaders[0].uniform_specular_intensity); render_mesh(meshes[1]); } glUseProgram(0); // We usually have two buffers, the first is hidden and that's // the one we draw to. The second is the one we display, so // when we're done drawing we call this glfwSwapBuffers() to // swap the buffers to show the one we've been drawing to so // that it now shows. We then can start drawing on the other // buffer. glfwSwapBuffers(window.gl_window); // Get and handle user input events glfwPollEvents(); } return 0; }