simplify shader grid drawing and add option to use a texture for the grid

This commit is contained in:
2023-09-08 16:38:14 +02:00
parent 978f60d762
commit 27d6853e3e
11 changed files with 8109 additions and 62 deletions
+2
View File
@@ -0,0 +1,2 @@
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
+7987
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -1,9 +1,9 @@
BIN=cudoku
CC=gcc
CFLAGS=-Wall -Wextra -Werror -pedantic -O3 -g `pkg-config --cflags x11` -I3rdparty/glad/include
OBJ=main.o x11.o cudoku.o shader.o 3rdparty/glad/src/gl.o 3rdparty/glad/src/glx.o
LDFLAGS=`pkg-config --libs x11`
DEPS=3rdparty/glad/include/glad/gl.h 3rdparty/glad/include/glad/glx.h
CFLAGS=-Wall -Wextra -Werror -pedantic -O3 -g `pkg-config --cflags x11` -I3rdparty/glad/include -I3rdparty/stb
OBJ=main.o x11.o cudoku.o shader.o 3rdparty/glad/src/gl.o 3rdparty/glad/src/glx.o 3rdparty/stb/stb.o
LDFLAGS=`pkg-config --libs x11` -lm
DEPS=3rdparty/glad/include/glad/gl.h 3rdparty/glad/include/glad/glx.h 3rdparty/stb/stb_image.h
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

+63 -21
View File
@@ -1,13 +1,17 @@
#include <glad/gl.h>
#include <stdio.h>
#include <stdbool.h>
#include <glad/gl.h>
#include "3rdparty/stb/stb_image.h"
#include "shader.h"
static const float quad_vertices[] = {
-1.0f, 1.0f, 0.0f, // top left
1.0f, 1.0f, 0.0f, // top right
-1.0f, -1.0f, 0.0f, // bottom left
1.0f, -1.0f, 0.0f, // bottom right
// positions // texture coords
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // top left
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom left
1.0f, -1.0f, 0.0f, 1.0f, 0.0f // bottom right
};
static const int quad_indices[] = {
@@ -15,7 +19,19 @@ static const int quad_indices[] = {
1, 2, 3
};
unsigned int prepare_bg_rect() {
void set_scale_factor(int width, int height, float *x, float *y) {
if (width > height) {
float ratio = (float)height / (float)width;
*x = ratio;
*y = 1.f;
} else {
float ratio = (float)width / (float)height;
*x = 1.f;
*y = ratio;
}
}
unsigned int prepare_bg(bool use_texture) {
unsigned int vbo, vao, ebo;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
@@ -29,29 +45,55 @@ unsigned int prepare_bg_rect() {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quad_indices), quad_indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)0);
if (use_texture) {
unsigned int texture;
int tex_width = 0, tex_height = 0;
unsigned char *tex_data = NULL;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
tex_data = stbi_load("assets/sudoku-grid.png", &tex_width, &tex_height, NULL, 0);
if (tex_data) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex_width, tex_height, 0, GL_RGB, GL_UNSIGNED_BYTE, tex_data);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(tex_data);
} else {
printf("[ERROR] could not load texture image\n");
}
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)(3 * sizeof(float)));
}
glBindVertexArray(0);
return vao;
}
void draw_bg_rect(Shader shader, unsigned int vao, float* transform) {
use_shader(shader);
set_mat4(shader, "transform", transform);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
// TODO: no idea why binding to default (0) breaks the grid shader
/* glBindVertexArray(0); */
}
void draw_bg_lines(Shader shader, float* transform, float resolution) {
void draw_bg_grid_shader(Shader shader, int vao, float* transform, float resolution) {
use_shader(shader);
set_mat4(shader, "transform", transform);
set_float(shader, "resolution", resolution);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}
void draw_bg_grid_texture(Shader shader, int vao, float* transform) {
use_shader(shader);
set_mat4(shader, "transform", transform);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}
+6 -3
View File
@@ -1,7 +1,10 @@
#pragma once
#include <stdbool.h>
#include "shader.h"
unsigned int prepare_bg_rect(Shader shader);
void draw_bg_rect(Shader shader, unsigned int vao, float* transform);
void draw_bg_lines(Shader shader, float* transform, float resolution);
void set_scale_factor(int width, int height, float *x, float *y);
unsigned int prepare_bg(bool use_texture);
void draw_bg_grid_shader(Shader shader, int vao, float* transform, float resolution);
void draw_bg_grid_texture(Shader shader, int vao, float* transform);
+33 -17
View File
@@ -1,6 +1,9 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <glad/glx.h>
#include "3rdparty/stb/stb_image.h"
#include "x11.h"
#include "cudoku.h"
@@ -12,22 +15,29 @@
// Simply port the js algo for sudoku generation
// Maybe after the game works fine we can use some winapi to add windows support
void scale_bg_rect(int width, int height, float *x, float *y) {
if (width > height) {
float ratio = (float)height / (float)width;
*x = ratio;
*y = 1.f;
} else {
float ratio = (float)width / (float)height;
*x = 1.f;
*y = ratio;
}
void usage() {
printf("Usage: cudoku [OPTION]\n\n");
printf(" %-20s%-20s", "-h, --help", "prints this help message\n");
printf(" %-20s%-20s", "--use-texture", "use a texture instead of generating the grid using shaders\n");
}
Display *display;
Window window;
int main() {
int main(int argc, char *argv[]) {
bool use_texture = false;
if (argc > 1) {
char *flag = argv[1];
if (strcmp(flag, "--use-texture") == 0) {
use_texture = true;
}
if (strcmp(flag, "-h") == 0 || strcmp(flag, "--help") == 0) {
usage();
return 0;
}
}
int res = init_x11(&display, &window);
if (res < 0) return 1;
@@ -37,9 +47,13 @@ int main() {
// the window
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);
Shader grid_shader;
if (!use_texture)
grid_shader = create_shader("shaders/board_v.glsl", "shaders/grid_f.glsl");
else
grid_shader = create_shader("shaders/board_v.glsl", "shaders/board_f.glsl");
int vao = prepare_bg(use_texture);
bool quit = false;
while (!quit) {
@@ -54,7 +68,7 @@ int main() {
width = xce.width;
height = xce.height;
resize_x11_window(display, window);
scale_bg_rect(xce.width, xce.height, &x_scale, &y_scale);
set_scale_factor(xce.width, xce.height, &x_scale, &y_scale);
}
} else if (xev.type == KeyPress) {
@@ -75,8 +89,10 @@ int main() {
{0, 0, 0, 1},
};
draw_bg_rect(board_shader, board_vao, (float *)transform);
draw_bg_lines(grid_shader, (float *)transform, width < height ? width : height);
if (!use_texture)
draw_bg_grid_shader(grid_shader, vao, (float *)transform, width < height ? width : height);
else
draw_bg_grid_texture(grid_shader, vao, (float *)transform);
glXSwapBuffers(display, window);
}
+5 -1
View File
@@ -1,6 +1,10 @@
#version 330 core
out vec4 FragColor;
in vec2 texCoords;
uniform sampler2D aTexture;
void main() {
FragColor = vec4(240.f/255.f, 235.f/255.f, 227.f/255.f, 1.0);
FragColor = texture(aTexture, texCoords);
}
+3
View File
@@ -1,8 +1,11 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoords;
out vec2 texCoords;
uniform mat4 transform;
void main() {
gl_Position = transform * vec4(aPos, 1.0f);
texCoords = aTexCoords;
}
+6 -4
View File
@@ -15,12 +15,14 @@ void main()
// Calculate the UV coordinates of the current fragment
vec2 uv = (gl_FragCoord * transform).xy / vec2(resolution, resolution); // Adjust the resolution as needed
float scale_x = transform[0][0];
float scale_y = transform[1][1];
// 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;
float fragCoordX = (uv.x - 0.5) * (2.0 / scale_x) - 1.0;
float fragCoordY = (uv.y - 0.5) * (2.0 / scale_y) - 1.0;
// Initialize colors for grid lines and background
// Colors for grid lines
vec3 gridColor = vec3(0.4, 0.4, 0.4);
vec3 gridColorThick = vec3(0.2, 0.2, 0.2);
@@ -42,6 +44,6 @@ void main()
} else if (isGridX || isGridY) {
FragColor = vec4(gridColor, 1.0);
} else {
discard;
FragColor = vec4(240.f/255.f, 235.f/255.f, 227.f/255.f, 1.0);
}
}
-12
View File
@@ -1,12 +0,0 @@
#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);
}