diff --git a/lib/sb b/lib/sb index 1690bb5..64f6b76 160000 --- a/lib/sb +++ b/lib/sb @@ -1 +1 @@ -Subproject commit 1690bb5f1996c4f6e342cc59ffa05fa15f9d77ed +Subproject commit 64f6b765a76a5839dda44e5ca0dd153d17245aec diff --git a/src/Pudding.cpp b/src/Pudding.cpp index 855bcb8..a2e1b89 100644 --- a/src/Pudding.cpp +++ b/src/Pudding.cpp @@ -160,40 +160,63 @@ void Pudding::load_gl_context() { sb::Log::log("could not create capture frame thread context"); } - /* Generate a vertex array object ID, bind it as current */ + /* Generate a vertex array object ID, bind it as current (requirement of OpenGL) */ vao.generate(); vao.bind(); /* 2D attributes (location and UV) for any texture that is a plane spanning the screen */ - std::vector rectangle_attributes = { - /* rectangle vertices will be added later */ - sb::Attributes({ - {-1.0f, 1.0f}, {1.0f, 1.0f}, {-1.0f, -1.0f}, - {1.0f, 1.0f}, {1.0f, -1.0f}, {-1.0f, -1.0f} - }), - /* first three rectangle UV coordinates, three more will be added later */ - sb::Attributes({ - {0.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}, - {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 0.0f} - }) + rectangle_attributes = { + { + "position", sb::Attributes({ + {-1.0f, 1.0f}, {1.0f, 1.0f}, {-1.0f, -1.0f}, + {1.0f, 1.0f}, {1.0f, -1.0f}, {-1.0f, -1.0f} + }) + }, + { + "uv", sb::Attributes({ + {0.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}, + {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 0.0f} + }) + } }; - /* Generate one vertex buffer object to hold all vertices and rectangle UV map. Since we're using one buffer, data + rectangle_attributes["position"].index(11); + rectangle_attributes["uv"].index(12); + /* Generate one vertex buffer object to hold all vertex data. Since we're using one buffer, data * will be copied in one after the other, offset to after the previous data location. The same buffer offset will * be passed to the vertex attributes for each data. */ vbo.generate(); vbo.target(GL_ARRAY_BUFFER); vbo.bind(); + /* Load two shader programs, one for rendering the flat objects, and one for rendering the 3D model. Load and configure + * the flat shader program first. */ + GLuint vertex_shader = load_shader("src/flat.vert", GL_VERTEX_SHADER); + GLuint fragment_shader = load_shader("src/flat.frag", GL_FRAGMENT_SHADER); + flat_program = glCreateProgram(); + glAttachShader(flat_program, vertex_shader); + glAttachShader(flat_program, fragment_shader); + glBindAttribLocation(flat_program, rectangle_attributes["position"].index(), "in_position"); + glBindAttribLocation(flat_program, rectangle_attributes["uv"].index(), "vertex_uv"); + /* load, configure and link the 3D world program */ + vertex_shader = load_shader("src/mvp.vert", GL_VERTEX_SHADER); + fragment_shader = load_shader("src/mvp.frag", GL_FRAGMENT_SHADER); + mvp_program = glCreateProgram(); + glAttachShader(mvp_program, vertex_shader); + glAttachShader(mvp_program, fragment_shader); + glBindAttribLocation(mvp_program, 2, "in_position"); + glBindAttribLocation(mvp_program, 3, "in_color"); + glBindAttribLocation(mvp_program, 4, "vertex_uv"); + sb::Log::gl_errors("after loading shaders"); /* allocate space for vertices, UV and colors, and copy rectangle vertices in at initialization */ - GLsizeiptr vbo_size = rectangle_attributes[0].size() + rectangle_attributes[1].size() + pudding_attributes["uv"].size() + + GLsizeiptr vbo_size = rectangle_attributes["position"].size() + rectangle_attributes["uv"].size() + pudding_attributes["uv"].size() + pudding_attributes["vertices"].size() + pudding_attributes["colors"].size(); - glBufferData(GL_ARRAY_BUFFER, vbo_size, rectangle_attributes[0], GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, vbo_size, rectangle_attributes["position"], GL_STATIC_DRAW); /* specify the rectangle vertex attributes as consecutive 2D float coords */ - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr); + glVertexAttribPointer(rectangle_attributes["position"].index(), 2, GL_FLOAT, GL_FALSE, 0, nullptr); /* copy rectangle UV data into the VBO, offset to after the vertex data, set up attributes */ - GLintptr offset = rectangle_attributes[0].size(); - glBufferSubData(GL_ARRAY_BUFFER, offset, rectangle_attributes[1].size(), rectangle_attributes[1]); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, reinterpret_cast(offset)); + GLintptr offset = rectangle_attributes["position"].size(); + glBufferSubData(GL_ARRAY_BUFFER, offset, rectangle_attributes["uv"].size(), rectangle_attributes["uv"]); + glVertexAttribPointer(rectangle_attributes["uv"].index(), 2, GL_FLOAT, GL_FALSE, 0, reinterpret_cast(offset)); /* copy pudding vertices into VBO, offset to after the rectangle UV, and set up vertex attributes for 3D */ - offset += rectangle_attributes[1].size(); + offset += rectangle_attributes["uv"].size(); glBufferSubData(GL_ARRAY_BUFFER, offset, pudding_attributes["vertices"].size(), pudding_attributes["vertices"]); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast(offset)); /* copy pudding color values into VBO, offset to after pudding vertices and set as 3D */ @@ -204,35 +227,21 @@ void Pudding::load_gl_context() offset += pudding_attributes["colors"].size(); glBufferSubData(GL_ARRAY_BUFFER, offset, pudding_attributes["uv"].size(), pudding_attributes["uv"]); glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, 0, reinterpret_cast(offset)); - /* Load two shader programs, one for rendering the flat objects, and one for rendering the 3D model. Load, configure, - * and link the flat shader program first. */ - GLuint vertex_shader = load_shader("src/flat.vert", GL_VERTEX_SHADER); - GLuint fragment_shader = load_shader("src/flat.frag", GL_FRAGMENT_SHADER); - flat_program = glCreateProgram(); - glAttachShader(flat_program, vertex_shader); - glAttachShader(flat_program, fragment_shader); - glBindAttribLocation(flat_program, 0, "in_position"); - glBindAttribLocation(flat_program, 1, "vertex_uv"); + sb::Log::gl_errors("after loading attributes"); + /* link shaders */ link_shader(flat_program); + link_shader(mvp_program); + sb::Log::gl_errors("after linking"); + /* store uniform locations after linking */ flat_texture_uniform_location = glGetUniformLocation(flat_program, "base_texture"); flat_time_uniform_location = glGetUniformLocation(flat_program, "time"); scroll_uniform_location = glGetUniformLocation(flat_program, "scroll"); - /* load, configure and link the 3D world program */ - vertex_shader = load_shader("src/mvp.vert", GL_VERTEX_SHADER); - fragment_shader = load_shader("src/mvp.frag", GL_FRAGMENT_SHADER); - mvp_program = glCreateProgram(); - glAttachShader(mvp_program, vertex_shader); - glAttachShader(mvp_program, fragment_shader); - glBindAttribLocation(mvp_program, 2, "in_position"); - glBindAttribLocation(mvp_program, 3, "in_color"); - glBindAttribLocation(mvp_program, 4, "vertex_uv"); - link_shader(mvp_program); mvp_uniform_location = glGetUniformLocation(mvp_program, "mvp"); time_uniform_location = glGetUniformLocation(mvp_program, "time"); effect_uniform_location = glGetUniformLocation(mvp_program, "effect"); uv_transformation_uniform_location = glGetUniformLocation(mvp_program, "uv_transformation"); coordinate_bound_uniform_location = glGetUniformLocation(mvp_program, "coordinate_bound"); - sb::Log::gl_errors(); + sb::Log::gl_errors("after uniform locations"); } /* Read every resource/tile/.*.jpg into a GL texture, storing the texture pointer and file name in a std::map */ @@ -750,8 +759,8 @@ void Pudding::update() /* disable pudding attributes and enable rectangle attributes */ glDisableVertexAttribArray(2); glDisableVertexAttribArray(3); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); + glEnableVertexAttribArray(rectangle_attributes["position"].index()); + glEnableVertexAttribArray(rectangle_attributes["uv"].index()); glUniform1i(flat_texture_uniform_location, 0); glActiveTexture(GL_TEXTURE0); tiles[current_tile_index].bind(); @@ -773,8 +782,8 @@ void Pudding::update() /* pass the mvp matrix to the shader */ glUniformMatrix4fv(mvp_uniform_location, 1, GL_FALSE, &mvp[0][0]); /* disable rectangle attributes and enable pudding attributes */ - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); + glDisableVertexAttribArray(rectangle_attributes["position"].index()); + glDisableVertexAttribArray(rectangle_attributes["uv"].index()); glEnableVertexAttribArray(2); if (items.size() == 0) { @@ -813,8 +822,8 @@ void Pudding::update() /* disable pudding attributes and enable rectangle attributes */ glDisableVertexAttribArray(2); glDisableVertexAttribArray(3); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); + glEnableVertexAttribArray(rectangle_attributes["position"].index()); + glEnableVertexAttribArray(rectangle_attributes["uv"].index()); glDisable(GL_DEPTH_TEST); /* just need to set these once since we're drawing one texture per viewport */ glUniform1i(flat_texture_uniform_location, 0); diff --git a/src/Pudding.hpp b/src/Pudding.hpp index 2f5e9e8..552561e 100644 --- a/src/Pudding.hpp +++ b/src/Pudding.hpp @@ -133,13 +133,11 @@ private: uv_transformation_uniform_location, flat_texture_uniform_location, coordinate_bound_uniform_location, flat_time_uniform_location, scroll_uniform_location; glm::mat4 projection, model = glm::mat4(1.0f), mvp; - std::map pudding_attributes = { + std::map rectangle_attributes, pudding_attributes = { {"vertices", sb::Attributes()}, {"uv", sb::Attributes()}, {"color", sb::Attributes()} }; - std::vector pudding_vertices, pudding_colors; - std::vector pudding_uv; bool show_item = false, reading_capture_frame = false; SDL_GLContext capture_frame_thread_context = nullptr; std::vector tiles;