Add UVs to vert shader

This commit is contained in:
Phireh 2025-05-25 17:56:43 +02:00
commit 8675683d10
4 changed files with 139 additions and 29 deletions

View file

@ -5,4 +5,4 @@ CFLAGS=-I./include -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/inclu
.PHONY: hexnando .PHONY: hexnando
hexnando: main.cpp hexnando: main.cpp
g++ -std=c++20 -Wall -g -Wextra -pedantic -Werror -Wno-calloc-transposed-args -Og main.cpp ${LINK_FLAGS} ${CFLAGS} -o hexnando g++ -std=c++20 -Wall -g -Wextra -pedantic -Werror -Wno-calloc-transposed-args -Wno-return-type -Wno-unused-parameter -Og main.cpp ${LINK_FLAGS} ${CFLAGS} -o hexnando

160
main.cpp
View file

@ -91,6 +91,7 @@ struct hex_t {
glm::vec3 position; glm::vec3 position;
float radius; float radius;
glm::vec3 vertices[7]; glm::vec3 vertices[7];
glm::vec2 uvs[7];
glm::vec4 color; glm::vec4 color;
uint32_t vao; uint32_t vao;
uint32_t vbo; uint32_t vbo;
@ -119,6 +120,10 @@ struct texture_t {
uint32_t h; uint32_t h;
}; };
struct input_t {
uint8_t keys[GLFW_KEY_LAST];
};
const int32_t ARRAY_LIMIT = 400; const int32_t ARRAY_LIMIT = 400;
charglyph_t glyphmap[128]; charglyph_t glyphmap[128];
@ -129,9 +134,12 @@ uint32_t texture_array;
glm::mat4 transforms[ARRAY_LIMIT]; glm::mat4 transforms[ARRAY_LIMIT];
int32_t letter_map[ARRAY_LIMIT]; int32_t letter_map[ARRAY_LIMIT];
int32_t text_frame_idx; int32_t text_frame_idx;
texture_t pngtex = {}; texture_t pngtex = {};
camera_t the_camera = {};
bool dirty_window = true;
input_t frame_input = {};
// error processing // error processing
enum err_type { enum err_type {
OK = 0, OK = 0,
@ -177,9 +185,15 @@ void glfw_error_callback(int error, const char* description)
fprintf(stderr, "GLFW error %d: %s\n", error, description); fprintf(stderr, "GLFW error %d: %s\n", error, description);
} }
void scroll_callback([[maybe_unused]]GLFWwindow* window, [[maybe_unused]]double xoffset, double yoffset) void scroll_callback([[maybe_unused]]GLFWwindow *window, [[maybe_unused]]double xoffset, double yoffset)
{ {
mouse_scroll = yoffset; mouse_scroll = yoffset;
dirty_window = true;
}
void key_callback([[maybe_unused]]GLFWwindow *window, int key, [[maybe_unused]]int scancode, [[maybe_unused]]int action, [[maybe_unused]]int mods)
{
frame_input.keys[key] = action;
} }
int path_callback([[maybe_unused]]ImGuiInputTextCallbackData *data) int path_callback([[maybe_unused]]ImGuiInputTextCallbackData *data)
@ -188,6 +202,44 @@ int path_callback([[maybe_unused]]ImGuiInputTextCallbackData *data)
return 0; return 0;
} }
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]() {
switch (source)
{
case GL_DEBUG_SOURCE_API: return "API";
case GL_DEBUG_SOURCE_WINDOW_SYSTEM: return "WINDOW SYSTEM";
case GL_DEBUG_SOURCE_SHADER_COMPILER: return "SHADER COMPILER";
case GL_DEBUG_SOURCE_THIRD_PARTY: return "THIRD PARTY";
case GL_DEBUG_SOURCE_APPLICATION: return "APPLICATION";
case GL_DEBUG_SOURCE_OTHER: return "OTHER";
}
}();
auto const type_str = [type]() {
switch (type)
{
case GL_DEBUG_TYPE_ERROR: return "ERROR";
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: return "DEPRECATED_BEHAVIOR";
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: return "UNDEFINED_BEHAVIOR";
case GL_DEBUG_TYPE_PORTABILITY: return "PORTABILITY";
case GL_DEBUG_TYPE_PERFORMANCE: return "PERFORMANCE";
case GL_DEBUG_TYPE_MARKER: return "MARKER";
case GL_DEBUG_TYPE_OTHER: return "OTHER";
}
}();
auto const severity_str = [severity]() {
switch (severity) {
case GL_DEBUG_SEVERITY_NOTIFICATION: return "NOTIFICATION";
case GL_DEBUG_SEVERITY_LOW: return "LOW";
case GL_DEBUG_SEVERITY_MEDIUM: return "MEDIUM";
case GL_DEBUG_SEVERITY_HIGH: return "HIGH";
}
}();
std::cout << src_str << ", " << type_str << ", " << severity_str << ", " << id << ": " << message << '\n';
}
int read_png(const char *path) int read_png(const char *path)
{ {
@ -453,27 +505,57 @@ void create_grid(grid_t *grid, int rows, int columns)
the_hexagon->vertices[5] = the_hexagon->position + glm::vec3(radius * glm::cos(glm::radians(60.0)), -radius * glm::sin(glm::radians(60.0)), 0); the_hexagon->vertices[5] = the_hexagon->position + glm::vec3(radius * glm::cos(glm::radians(60.0)), -radius * glm::sin(glm::radians(60.0)), 0);
the_hexagon->vertices[6] = the_hexagon->position + glm::vec3(-radius * glm::cos(glm::radians(60.0)), -radius * glm::sin(glm::radians(60.0)), 0); 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)));
// copy verts + uvs to a temp ordered buffer before sending to GPU
float databuf[7 * 3 + 7 * 2];
int n = 0;
for (int i = 0; i < 7; ++i)
{
databuf[n++] = the_hexagon->vertices[i].x;
databuf[n++] = the_hexagon->vertices[i].y;
databuf[n++] = the_hexagon->vertices[i].z;
databuf[n++] = the_hexagon->uvs[i].x;
databuf[n++] = the_hexagon->uvs[i].y;
}
glGenVertexArrays(1, &the_hexagon->vao); glGenVertexArrays(1, &the_hexagon->vao);
glGenBuffers(1, &the_hexagon->vbo); glGenBuffers(1, &the_hexagon->vbo);
glBindVertexArray(the_hexagon->vao); glBindVertexArray(the_hexagon->vao);
glBindBuffer(GL_ARRAY_BUFFER, the_hexagon->vbo); glBindBuffer(GL_ARRAY_BUFFER, the_hexagon->vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 7 * 3, the_hexagon->vertices, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER,
sizeof(float) * 7 * 3 + // vertices
sizeof(float) * 7 * 2 // normals
, databuf, GL_STATIC_DRAW);
// EBO setup unsigned int indices[6];
unsigned int indices[18]; indices[0] = 1;
indices[0] = 0; indices[1] = 2; indices[2] = 1; indices[1] = 6;
indices[3] = 0; indices[4] = 3; indices[5] = 2; indices[2] = 2;
indices[6] = 0; indices[7] = 4; indices[8] = 3; indices[3] = 5;
indices[9] = 0; indices[10] = 5; indices[11] = 4; indices[4] = 3;
indices[12] = 0; indices[13] = 6; indices[14] = 5; indices[5] = 4;
indices[15] = 0; indices[16] = 1; indices[17] = 6;
glGenBuffers(1, &the_hexagon->ebo); glGenBuffers(1, &the_hexagon->ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, the_hexagon->ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, the_hexagon->ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*3 * sizeof(unsigned int), indices, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
// vertex position data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)0);
// uv data
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)(sizeof(float) * 3));
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0); glBindVertexArray(0);
} }
@ -503,6 +585,7 @@ int main([[maybe_unused]]int argc, [[maybe_unused]]char **argv)
glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);
glfwSwapInterval(1); glfwSwapInterval(1);
glfwSetScrollCallback(window, scroll_callback); glfwSetScrollCallback(window, scroll_callback);
glfwSetKeyCallback(window, key_callback);
if (!gladLoadGL()) if (!gladLoadGL())
{ {
@ -517,6 +600,9 @@ int main([[maybe_unused]]int argc, [[maybe_unused]]char **argv)
fprintf(stdout, "Compiled using libPNG version %s\n", PNG_LIBPNG_VER_STRING); fprintf(stdout, "Compiled using libPNG version %s\n", PNG_LIBPNG_VER_STRING);
fprintf(stdout, "Runtime using libPNG version %s\n", png_libpng_ver); fprintf(stdout, "Runtime using libPNG version %s\n", png_libpng_ver);
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(ogl_debugcb, nullptr);
// font library initialization // font library initialization
FT_Library ft; FT_Library ft;
@ -617,7 +703,7 @@ int main([[maybe_unused]]int argc, [[maybe_unused]]char **argv)
double cursor_y; double cursor_y;
double cursor_x_scaled; double cursor_x_scaled;
double cursor_y_scaled; double cursor_y_scaled;
camera_t the_camera;
bool mouse_pressed; bool mouse_pressed;
bool right_mouse_pressed; bool right_mouse_pressed;
bool mouse_over_gui; bool mouse_over_gui;
@ -653,18 +739,39 @@ int main([[maybe_unused]]int argc, [[maybe_unused]]char **argv)
{ {
TIME_BLOCK(input_handling); TIME_BLOCK(input_handling);
/* Input handling */ /* Input handling */
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) glfwPollEvents();
if (frame_input.keys[GLFW_KEY_W] == GLFW_PRESS)
{
the_camera.position.y += 0.1; the_camera.position.y += 0.1;
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) dirty_window = true;
}
if (frame_input.keys[GLFW_KEY_S] == GLFW_PRESS)
{
the_camera.position.y -= 0.1; the_camera.position.y -= 0.1;
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) dirty_window = true;
}
if (frame_input.keys[GLFW_KEY_A] == GLFW_PRESS)
{
the_camera.position.x -= 0.1; the_camera.position.x -= 0.1;
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) dirty_window = true;
}
if (frame_input.keys[GLFW_KEY_D] == GLFW_PRESS)
{
the_camera.position.x += 0.1; the_camera.position.x += 0.1;
if (glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS) dirty_window = true;
}
if (frame_input.keys[GLFW_KEY_R] == GLFW_PRESS)
{
the_camera.size -= glm::vec2(0.1); the_camera.size -= glm::vec2(0.1);
if (glfwGetKey(window, GLFW_KEY_F) == GLFW_PRESS) dirty_window = true;
}
if (frame_input.keys[GLFW_KEY_F] == GLFW_PRESS)
{
the_camera.size += glm::vec2(0.1); the_camera.size += glm::vec2(0.1);
dirty_window = true;
}
if (mouse_scroll > 0.0) if (mouse_scroll > 0.0)
{ {
the_camera.size -= glm::vec2(0.1); the_camera.size -= glm::vec2(0.1);
@ -711,9 +818,14 @@ int main([[maybe_unused]]int argc, [[maybe_unused]]char **argv)
glm::mat4 proj_matrix; glm::mat4 proj_matrix;
glm::vec2 cursor_world; glm::vec2 cursor_world;
static char image_path[PATH_MAX];
static int grid_rows = grid.rows;
static int grid_columns = grid.columns;
/* Rendering */ /* Rendering */
{ {
TIME_BLOCK(hex_render); TIME_BLOCK(hex_render);
glClearColor(0.1f, 0.2f, 0.3f, 1.0f); glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
@ -771,7 +883,7 @@ int main([[maybe_unused]]int argc, [[maybe_unused]]char **argv)
glBindBuffer(GL_ARRAY_BUFFER, grid.hexes[idx].vbo); glBindBuffer(GL_ARRAY_BUFFER, grid.hexes[idx].vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, grid.hexes[idx].ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, grid.hexes[idx].ebo);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glDrawElements(GL_TRIANGLES, 3*6, GL_UNSIGNED_INT, 0); glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT, 0);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
glBindVertexArray(0); glBindVertexArray(0);
} }
@ -827,11 +939,6 @@ int main([[maybe_unused]]int argc, [[maybe_unused]]char **argv)
} }
glDisable(GL_BLEND); glDisable(GL_BLEND);
glfwPollEvents();
static int grid_rows = grid.rows;
static int grid_columns = grid.columns;
static char image_path[PATH_MAX];
if (grid_rows != grid.rows || grid_columns != grid.columns) if (grid_rows != grid.rows || grid_columns != grid.columns)
{ {
@ -901,6 +1008,7 @@ int main([[maybe_unused]]int argc, [[maybe_unused]]char **argv)
} }
glfwSwapBuffers(window); glfwSwapBuffers(window);
dirty_window = false;
} }
// Cleanup // Cleanup

View file

@ -2,3 +2,4 @@
- Text rendering optimized yet still taking too much time. Using atlas with GL_TEXTURE_ARRAY - Text rendering optimized yet still taking too much time. Using atlas with GL_TEXTURE_ARRAY
- All vertex data lives in the CPU for each hex too - All vertex data lives in the CPU for each hex too
- Need UI to modify hex appeareance (show texture from file and then apply it to hex) - Need UI to modify hex appeareance (show texture from file and then apply it to hex)
- Each hex should be a triangle strip or a triangle fan, not a combo of 6 different triangles

View file

@ -1,5 +1,6 @@
#version 330 core #version 330 core
layout (location = 0) in vec3 pos; layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 uv;
uniform mat4 model; uniform mat4 model;
uniform mat4 view; uniform mat4 view;
uniform mat4 proj; uniform mat4 proj;