diff --git a/cudoku.c b/cudoku.c index 19c9772..9d63c97 100644 --- a/cudoku.c +++ b/cudoku.c @@ -1,4 +1,5 @@ #include +#include #include "shader.h" @@ -49,5 +50,22 @@ void draw_bg_rect(Shader shader, unsigned int vao, float x_scale, float y_scale) glBindVertexArray(vao); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); - glBindVertexArray(0); + // TODO: no idea why binding to default (0) breaks the grid shader + /* glBindVertexArray(0); */ +} + +void draw_bg_lines(Shader shader, float x_scale, float y_scale, float resolution) { + use_shader(shader); + + float mat[4][4] = { + {x_scale, 0, 0, 0}, + {0, y_scale, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1}, + }; + + set_mat4(shader, "transform", (float *)mat); + set_float(shader, "resolution", resolution); + + glDrawArrays(GL_TRIANGLES, 0, 6); } diff --git a/cudoku.h b/cudoku.h index 27a475c..61eacd0 100644 --- a/cudoku.h +++ b/cudoku.h @@ -4,3 +4,4 @@ unsigned int prepare_bg_rect(Shader shader); void draw_bg_rect(Shader shader, unsigned int vao, float x_scale, float y_scale); +void draw_bg_lines(Shader shader, float x_scale, float y_scale, float resolution); diff --git a/main.c b/main.c index 4643cef..eb6bef1 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,6 @@ #include #include -#include #include "x11.h" #include "cudoku.h" @@ -39,6 +38,7 @@ int main() { float x_scale = 1.f, y_scale = 1.f; Shader board_shader = create_shader("shaders/board_v.glsl", "shaders/board_f.glsl"); + Shader grid_shader = create_shader("shaders/grid_v.glsl", "shaders/grid_f.glsl"); unsigned int board_vao = prepare_bg_rect(board_shader); bool quit = false; @@ -69,6 +69,7 @@ int main() { glClear(GL_COLOR_BUFFER_BIT); draw_bg_rect(board_shader, board_vao, x_scale, y_scale); + draw_bg_lines(grid_shader, x_scale, y_scale, width < height ? width : height); glXSwapBuffers(display, window); } diff --git a/shader.c b/shader.c index cfeb986..3946250 100644 --- a/shader.c +++ b/shader.c @@ -86,3 +86,7 @@ void set_mat4(Shader shader, const char *name, float *mat4) { glUniformMatrix4fv(loc, 1, GL_FALSE, mat4); } +void set_float(Shader shader, const char *name, float val) { + int loc = glGetUniformLocation(shader.program, name); + glUniform1f(loc, val); +} diff --git a/shader.h b/shader.h index d237775..1a5d9ca 100644 --- a/shader.h +++ b/shader.h @@ -8,3 +8,4 @@ void read_shader_file(const char *path, char **buf); Shader create_shader(const char *vertex_path, const char *fragment_path); void use_shader(Shader shader); void set_mat4(Shader shader, const char *name, float *mat); +void set_float(Shader shader, const char *name, float val); diff --git a/shaders/grid_f.glsl b/shaders/grid_f.glsl new file mode 100644 index 0000000..017ee03 --- /dev/null +++ b/shaders/grid_f.glsl @@ -0,0 +1,47 @@ +#version 330 core + +out vec4 FragColor; + +uniform mat4 transform; +uniform float resolution; + +void main() +{ + // Define the size of the grid + int gridSize = 9; + + // Calculate the step size for the grid lines + float stepSize = 2.0 / float(gridSize); + + // Calculate the UV coordinates of the current fragment + vec2 uv = (gl_FragCoord * transform).xy / vec2(resolution, resolution); // Adjust the resolution as needed + + // Calculate the coordinates of the current fragment in the [-1, 1] range + float fragCoordX = (uv.x - 0.5) * (2.0 / transform[0][0]) - 1.0; + float fragCoordY = (uv.y - 0.5) * (2.0 / transform[1][1]) - 1.0; + + // Initialize colors for grid lines and background + vec3 gridColor = vec3(0.4, 0.4, 0.4); + vec3 gridColorThick = vec3(0.2, 0.2, 0.2); + + bool isInsideGridHorizontally = (fragCoordX >= -2.0 && fragCoordX <= 0.0); + bool isInsideGridVertically = (fragCoordY >= -2.0 && fragCoordY <= 0.0); + bool isInsideGrid = isInsideGridHorizontally && isInsideGridVertically; + + // Determine if the current fragment is on a thicker grid line + bool isThickLineX = isInsideGrid && mod(fragCoordX, stepSize * 3) < 0.01; + bool isThickLineY = isInsideGrid && mod(fragCoordY, stepSize * 3) < 0.01; + + // Check if the current fragment is on a grid line + bool isGridX = isInsideGrid && mod(fragCoordX, stepSize) < 0.005; + bool isGridY = isInsideGrid && mod(fragCoordY, stepSize) < 0.005; + + // Set the fragment color based on whether it's a grid line or a thicker grid line + if ((isThickLineX) || (isThickLineY)) { + FragColor = vec4(gridColorThick, 1.0); + } else if (isGridX || isGridY) { + FragColor = vec4(gridColor, 1.0); + } else { + discard; + } +} diff --git a/shaders/grid_v.glsl b/shaders/grid_v.glsl new file mode 100644 index 0000000..6b842d7 --- /dev/null +++ b/shaders/grid_v.glsl @@ -0,0 +1,12 @@ +#version 330 core +uniform mat4 transform; + +vec3 gridPlane[6] = vec3[]( + vec3(1, 1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0), + vec3(-1, -1, 0), vec3(1, 1, 0), vec3(1, -1, 0) +); + +void main() { + vec3 p = gridPlane[gl_VertexID].xyz; + gl_Position = vec4(p, 1.0f); +} \ No newline at end of file