// ################################################################################ // Common Framework for Computer Graphics Courses at FI MUNI. // // Copyright (c) 2021-2022 Visitlab (https://visitlab.fi.muni.cz) // All rights reserved. // ################################################################################ #include "application.hpp" #include "data.hpp" // ---------------------------------------------------------------------------- // Constructors & Destructors // ---------------------------------------------------------------------------- Application::Application(int initial_width, int initial_height, std::vector arguments) : PV112Application(initial_width, initial_height, arguments) { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); compile_shaders(); glCreateVertexArrays(1, &vao_empty); // Task 3.3: Create Vertex Buffer Objects (VBO). Copy vertex data found in data.hpp to VBOs. // Diamond glCreateBuffers(1, &diamond_positions_vbo); // // ======>>> alokuje a rovnou naplni buffer const int no_flag = 0; glNamedBufferStorage(diamond_positions_vbo, 36 * sizeof(float), diamond_positions, no_flag); glCreateBuffers(1, &diamond_colors_vbo); glNamedBufferStorage(diamond_colors_vbo, 36 * sizeof(float), diamond_colors, NULL); // Square glCreateBuffers(1, &square_vbo); glNamedBufferStorage(square_vbo, 36 * sizeof(float), square_data, NULL); // Triangle glCreateBuffers(1, &triangle_vbo); glNamedBufferStorage(triangle_vbo, 3 * sizeof(Vertex), triangle_vertices, NULL); // Indexed Diamond glCreateBuffers(1, &diamond_indices_vbo); glCreateBuffers(1, &diamond_positions_indexed_vbo); glCreateBuffers(1, &diamond_colors_indexed_vbo); glNamedBufferStorage(diamond_indices_vbo, 12 * sizeof(uint32_t), diamond_indices, NULL); glNamedBufferStorage(diamond_positions_indexed_vbo, 15 * sizeof(float), diamond_positions_indexed, NULL); glNamedBufferStorage(diamond_colors_indexed_vbo, 15 * sizeof(float), diamond_colors_indexed, NULL); // Task 3.4-3.6: Create Vertex Array Objects (VAO) fetching data from VBOs. // Diamond glCreateVertexArrays(1, &diamond_vao); // // ======>>> definuje binder (nacitac) const GLuint binder_id = 5; glVertexArrayVertexBuffer(diamond_vao, binder_id, diamond_positions_vbo, 0, 3 * sizeof(float)); glVertexArrayVertexBuffer(diamond_vao, 1, diamond_colors_vbo, 0, 3 * sizeof(float)); // // ======>>> definuje atribut const GLuint shader_location = 4; glEnableVertexArrayAttrib(diamond_vao, shader_location); glVertexArrayAttribFormat(diamond_vao, shader_location, 3, GL_FLOAT, GL_FALSE, 0); // ======>>> atribut spoji s binderem (nacitacem) glVertexArrayAttribBinding(diamond_vao, shader_location, binder_id); glEnableVertexArrayAttrib(diamond_vao, 1); glVertexArrayAttribFormat(diamond_vao, 1, 3, GL_FLOAT, GL_FALSE, 0); glVertexArrayAttribBinding(diamond_vao, 1, 1); // Square glCreateVertexArrays(1, &square_vao); glVertexArrayVertexBuffer(square_vao, 0, square_vbo, 0, 3 * sizeof(float)); glVertexArrayVertexBuffer(square_vao, 1, square_vbo, 6 * 3 * sizeof(float), 3 * sizeof(float)); glEnableVertexArrayAttrib(square_vao, 0); glVertexArrayAttribFormat(square_vao, 0, 3, GL_FLOAT, GL_FALSE, 0); glVertexArrayAttribBinding(square_vao, 0, 0); glEnableVertexArrayAttrib(square_vao, 1); glVertexArrayAttribFormat(square_vao, 1, 3, GL_FLOAT, GL_FALSE, 0); glVertexArrayAttribBinding(square_vao, 1, 1); // Triangle glCreateVertexArrays(1, &triangle_vao); glVertexArrayVertexBuffer(triangle_vao, 0, triangle_vbo, 0, sizeof(Vertex)); glEnableVertexArrayAttrib(triangle_vao, 0); glVertexArrayAttribFormat(triangle_vao, 0, 3, GL_FLOAT, GL_FALSE, 0); glVertexArrayAttribBinding(triangle_vao, 0, 0); glEnableVertexArrayAttrib(triangle_vao, 1); glVertexArrayAttribFormat(triangle_vao, 1, 3, GL_UNSIGNED_BYTE, GL_TRUE, offsetof(Vertex, color)); glVertexArrayAttribBinding(triangle_vao, 1, 0); // Indexed Diamond glCreateVertexArrays(1, &diamond_indexed_vao); glVertexArrayVertexBuffer(diamond_indexed_vao, 0, diamond_positions_indexed_vbo, 0, 3 * sizeof(float)); glVertexArrayVertexBuffer(diamond_indexed_vao, 1, diamond_colors_indexed_vbo, 0, 3 * sizeof(float)); glVertexArrayElementBuffer(diamond_indexed_vao, diamond_indices_vbo); glEnableVertexArrayAttrib(diamond_indexed_vao, 0); glVertexArrayAttribFormat(diamond_indexed_vao, 0, 3, GL_FLOAT, GL_FALSE, 0); glVertexArrayAttribBinding(diamond_indexed_vao, 0, 0); glEnableVertexArrayAttrib(diamond_indexed_vao, 1); glVertexArrayAttribFormat(diamond_indexed_vao, 1, 3, GL_FLOAT, GL_FALSE, 0); glVertexArrayAttribBinding(diamond_indexed_vao, 1, 1); } Application::~Application() { glDeleteVertexArrays(1, &vao_empty); // Task 3.3: Delete the Vertex Buffer Objects (VBOs). // Task 3.4-3.6: Delete Vertex Array Objects (VAOs). glDeleteVertexArrays(1, &diamond_vao); glDeleteBuffers(1, &diamond_positions_vbo); glDeleteBuffers(1, &diamond_colors_vbo); glDeleteVertexArrays(1, &square_vao); glDeleteBuffers(1, &square_vbo); glDeleteVertexArrays(1, &triangle_vao); glDeleteBuffers(1, &triangle_vbo); glDeleteVertexArrays(1, &diamond_indexed_vao); glDeleteBuffers(1, &diamond_indices_vbo); glDeleteBuffers(1, &diamond_positions_indexed_vbo); glDeleteBuffers(1, &diamond_colors_indexed_vbo); delete_shaders(); } // ---------------------------------------------------------------------------- // Methods // ---------------------------------------------------------------------------- void Application::delete_shaders() { glDeleteProgram(program_triangle); glDeleteProgram(program_square); glDeleteProgram(program_square_strip); glDeleteProgram(program_vao); } void Application::compile_shaders() { delete_shaders(); program_triangle = create_program(lecture_shaders_path / "main_triangle.vert", lecture_shaders_path / "main.frag"); program_square = create_program(lecture_shaders_path / "main_square.vert", lecture_shaders_path / "main.frag"); program_square_strip = create_program(lecture_shaders_path / "main_square_strip.vert", lecture_shaders_path / "main.frag"); program_vao = create_program(lecture_shaders_path / "main_vao.vert", lecture_shaders_path / "main_vao.frag"); } void Application::update(float delta) {} void Application::render() { glViewport(0, 0, width, height); glClear(GL_COLOR_BUFFER_BIT); switch (ui_chosen_program) { case 0: { // glUseProgram(program_triangle); glBindVertexArray(vao_empty); glDrawArrays(GL_TRIANGLES, 0, 3); break; } case 1: { // Task 3.1: Draw a square. glUseProgram(program_square); glBindVertexArray(vao_empty); glDrawArrays(GL_TRIANGLES, 0, 6); break; } case 2: { // Task 3.2: Draw a square using GL_TRIANGLE_STRIP glUseProgram(program_square_strip); glBindVertexArray(vao_empty); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); break; } case 3: { // Task 3.4-3.6: Draw all objects. glUseProgram(program_vao); glBindVertexArray(diamond_vao); glDrawArrays(GL_TRIANGLES, 0, 12); /* glBindVertexArray(square_vao); glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(triangle_vao); glDrawArrays(GL_TRIANGLES, 0, 3); glBindVertexArray(diamond_indexed_vao); glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_INT, nullptr); */ break; } } } void Application::render_ui() { const float unit = ImGui::GetFontSize(); ImGui::Begin("Configuration", nullptr, ImGuiWindowFlags_NoDecoration); ImGui::SetWindowSize(ImVec2(10 * unit, 20 * unit)); ImGui::SetWindowPos(ImVec2(40 * unit, 2 * unit)); ImGui::RadioButton("Triangle", &ui_chosen_program, 0); ImGui::RadioButton("Square", &ui_chosen_program, 1); ImGui::RadioButton("Square (triangle strip)", &ui_chosen_program, 2); ImGui::RadioButton("VAO-based objects", &ui_chosen_program, 3); ImGui::End(); } // ---------------------------------------------------------------------------- // Input Events // ---------------------------------------------------------------------------- void Application::on_resize(int width, int height) { // Calls the default implementation to set the class variables. PV112Application::on_resize(width, height); } void Application::on_mouse_move(double x, double y) {} void Application::on_mouse_button(int button, int action, int mods) {} void Application::on_key_pressed(int key, int scancode, int action, int mods) { // Calls default implementation that invokes compile_shaders when 'R key is hit. PV112Application::on_key_pressed(key, scancode, action, mods); }