diff --git a/main.cpp b/main.cpp index b0414b2..6109cd5 100644 --- a/main.cpp +++ b/main.cpp @@ -86,6 +86,12 @@ struct charglyph_t { uint32_t advance; // offset to next glyph }; +struct texture_t { + GLuint gl_id; // OpenGL GLuint ID + uint32_t w; + uint32_t h; +}; + struct hex_t { int32_t id; glm::vec3 position; @@ -96,6 +102,7 @@ struct hex_t { uint32_t vao; uint32_t vbo; uint32_t ebo; + texture_t *tex; }; struct grid_t { @@ -114,12 +121,6 @@ struct selection_t { int32_t nselected; }; -struct texture_t { - uint32_t gl_id; // OpenGL GLuint ID - uint32_t w; - uint32_t h; -}; - struct input_t { uint8_t keys[GLFW_KEY_LAST]; }; @@ -135,6 +136,8 @@ glm::mat4 transforms[ARRAY_LIMIT]; int32_t letter_map[ARRAY_LIMIT]; int32_t text_frame_idx; texture_t pngtex = {}; +uint8_t white_data[] = { 255, 255, 255, 255 }; +texture_t default_tex = {}; camera_t the_camera = {}; bool dirty_window = true; @@ -164,19 +167,25 @@ bool is_selected(int idx, selection_t *sel) return false; } -void select(int idx, selection_t *sel) +void select(int idx, selection_t *sel, grid_t *grid) { + // NOTE: temp code if (!is_selected(idx, sel)) + { sel->indices[sel->nselected++] = idx; + if (pngtex.gl_id) + grid->hexes[idx].tex = &pngtex; + } } -void deselect(int idx, selection_t *sel) +void deselect(int idx, selection_t *sel, grid_t *grid) { for (int i = 0; i < sel->nselected; ++i) if (sel->indices[i] == idx) { sel->indices[i] = -1; --sel->nselected; + grid->hexes[idx].tex = &default_tex; } } @@ -202,6 +211,7 @@ int path_callback([[maybe_unused]]ImGuiInputTextCallbackData *data) return 0; } +// TODO: Make this function less complicated void ogl_debugcb(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, GLchar const* message, void const* user_param) { auto const src_str = [source]() { @@ -506,13 +516,15 @@ void create_grid(grid_t *grid, int rows, int columns) the_hexagon->vertices[6] = the_hexagon->position + glm::vec3(-radius * glm::cos(glm::radians(60.0)), -radius * glm::sin(glm::radians(60.0)), 0); // default uv coordinates are a simple 1 unit-sized hexagon mask - the_hexagon->uvs[0] = glm::vec2(0, 0); - the_hexagon->uvs[1] = glm::vec2(-radius, 0); - the_hexagon->uvs[2] = glm::vec2(-radius * glm::cos(glm::radians(60.0)), radius * glm::sin(glm::radians(60.0))); - the_hexagon->uvs[3] = glm::vec2(radius * glm::cos(glm::radians(60.0)), radius * glm::sin(glm::radians(60.0))); - the_hexagon->uvs[4] = glm::vec2(radius, 0); - the_hexagon->uvs[5] = glm::vec2(radius * glm::cos(glm::radians(60.0)), -radius * glm::sin(glm::radians(60.0))); - the_hexagon->uvs[6] = glm::vec2(-radius * glm::cos(glm::radians(60.0)), -radius * glm::sin(glm::radians(60.0))); + the_hexagon->uvs[0] = glm::vec2(0.5, 0.5); + the_hexagon->uvs[1] = glm::vec2(0, 0.5); + the_hexagon->uvs[2] = glm::vec2(0.5 - glm::cos(glm::radians(60.0))/2.0, 0.5 + glm::sin(glm::radians(60.0))/2.0); + the_hexagon->uvs[3] = glm::vec2(0.5 + glm::cos(glm::radians(60.0))/2.0, 0.5 + glm::sin(glm::radians(60.0))/2.0); + the_hexagon->uvs[4] = glm::vec2(1, 0.5); + the_hexagon->uvs[5] = glm::vec2(0.5 + glm::cos(glm::radians(60.0))/2.0, 0.5 - glm::sin(glm::radians(60.0))/2.0); + the_hexagon->uvs[6] = glm::vec2(0.5 - glm::cos(glm::radians(60.0))/2.0, 0.5 - glm::sin(glm::radians(60.0))/2.0); + + the_hexagon->tex = &default_tex; // copy verts + uvs to a temp ordered buffer before sending to GPU float databuf[7 * 3 + 7 * 2]; @@ -685,6 +697,17 @@ int main([[maybe_unused]]int argc, [[maybe_unused]]char **argv) glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); + // white default texture creation + + default_tex.w = 1; + default_tex.h = 1; + glGenTextures(1, &default_tex.gl_id); + glBindTexture(GL_TEXTURE_2D, default_tex.gl_id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, default_tex.w, default_tex.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, white_data); + + static grid_t grid = {}; create_grid(&grid, 10, 10); @@ -857,11 +880,11 @@ int main([[maybe_unused]]int argc, [[maybe_unused]]char **argv) hovered_hex = i * grid.columns + j; if (mouse_pressed) { - select(idx, &selection); + select(idx, &selection, &grid); } else if (right_mouse_pressed) { - deselect(idx, &selection); + deselect(idx, &selection, &grid); } if (!is_selected(idx, &selection)) glUniform4f(glGetUniformLocation(hex_program, "hex_color"), 1.0f, 0.0f, 0.0f, 1.0f); // red @@ -879,10 +902,15 @@ int main([[maybe_unused]]int argc, [[maybe_unused]]char **argv) glUniform4f(glGetUniformLocation(hex_program, "hex_color"), grid.hexes[idx].color.x, grid.hexes[idx].color.y, grid.hexes[idx].color.z, grid.hexes[idx].color.w); } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, grid.hexes[idx].tex->gl_id); + glUniform1i(glGetUniformLocation(hex_program, "tex"), 0); + glBindVertexArray(grid.hexes[idx].vao); glBindBuffer(GL_ARRAY_BUFFER, grid.hexes[idx].vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, grid.hexes[idx].ebo); glEnable(GL_CULL_FACE); + glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT, 0); glDisable(GL_CULL_FACE); glBindVertexArray(0); diff --git a/shaders/hex.frag b/shaders/hex.frag index a49aaca..94002fb 100644 --- a/shaders/hex.frag +++ b/shaders/hex.frag @@ -1,7 +1,9 @@ #version 330 core +in vec2 frag_uv; out vec4 final_color; uniform vec4 hex_color; +uniform sampler2D tex; void main() { - final_color = hex_color; + final_color = texture(tex, frag_uv) * hex_color; } diff --git a/shaders/hex.vert b/shaders/hex.vert index 0443488..3cb8756 100644 --- a/shaders/hex.vert +++ b/shaders/hex.vert @@ -5,7 +5,10 @@ uniform mat4 model; uniform mat4 view; uniform mat4 proj; +out vec2 frag_uv; + void main() { gl_Position = proj * view * model * vec4(pos, 1.0f); + frag_uv = uv; }