use a geometry shader to render rectangles

This commit is contained in:
2025-06-06 17:13:41 +02:00
parent ed7a157ee3
commit 89a82a6be2
4 changed files with 82 additions and 28 deletions

View File

@@ -8,23 +8,27 @@
#include <stdint.h>
#include <stdlib.h>
#include "../util/vec/float2.h"
#include "shader.h"
#include "../error.h"
#include "shader.h"
#define VERTC 6
GLuint pipe;
float2 verts[VERTC] = {
{-1, -1 }, // pnt A
{1, -1 }, // pnt B
{1, -0.9F}, // pnt C
// include GLFW
#include <GLFW/glfw3.h>
{-1, -0.9F}, // pnt D
{1, -0.9F}, // pnt C
{-1, -1 }, // pnt A
};
GLuint vbo; // vertex buffer object
GLuint vao; // vertex array object
#define VERTC 1
static GLuint pipe;
static GLuint vbo; // vertex buffer object
static GLuint vao; // vertex array object
static GLuint screen_loc; // location to where OpenGL sends to the shaders of the screen dimensions
static void screen_resize(int w, int h) {
int32_t verts[VERTC][4] = {
{0, h, w, -20},
};
glUniform2i(screen_loc, w, h); // send the screen dimensions to the shader pipeline
glViewport(0, 0, w, h); // update the viewport
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_DYNAMIC_DRAW); // bind the data to it
}
int render_init(void) {
pipe = glCreateProgram();
@@ -32,11 +36,6 @@ int render_init(void) {
glLinkProgram(pipe); // link the application
glValidateProgram(pipe); // validate that what we've done is correct
// init the VBO
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
int len;
glGetProgramiv(pipe, GL_INFO_LOG_LENGTH, &len);
if (len > 0) {
@@ -46,14 +45,18 @@ int render_init(void) {
fatal("error whilst linking the pipe: '%s'", log);
}
// init the VAO
screen_loc = glGetUniformLocation(pipe, "screen");
glGenBuffers(1, &vbo); // create the vertex buffer objects
glBindBuffer(GL_ARRAY_BUFFER, vbo); // bind to it
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// set VBO info
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float2), NULL);
glVertexAttribIPointer(0, 4, GL_INT, 4 * sizeof(int32_t), NULL);
glBindVertexArray(0);
return 0;
@@ -65,11 +68,16 @@ void render_update(GLFWwindow* win) {
int w, h;
glfwGetWindowSize(win, &w, &h);
glViewport(0, 0, w, h);
glClearColor(0.1F, 0.1F, 0.1F, 1.0F);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glUseProgram(pipe);
static int d = -1; // initialize d to an impossible value so the condition below is always true on first execution
if ((h ^ w) != d) { // false negative when h and w swap integers, but this is quite a rare occurrence and it's impact is minimal
screen_resize(w, h);
d = h ^ w;
}
glClearColor(0.1F, 0.1F, 0.1F, 1.0F);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, VERTC);
glDrawArrays(GL_POINTS, 0, VERTC);
}

View File

@@ -16,6 +16,8 @@ extern char const NAM_S(sh_vert_glsl)[];
extern char const NAM_E(sh_vert_glsl)[];
extern char const NAM_S(sh_frag_glsl)[];
extern char const NAM_E(sh_frag_glsl)[];
extern char const NAM_S(sh_geom_glsl)[];
extern char const NAM_E(sh_geom_glsl)[];
// NOLINTEND
/* compile a shader */
@@ -41,10 +43,14 @@ static GLuint shader_compile(GLenum type, char const* src, size_t len) {
int shader_init(GLuint pipe) {
GLuint vs = COMPILE_NAME(GL_VERTEX_SHADER, sh_vert_glsl);
GLuint fs = COMPILE_NAME(GL_FRAGMENT_SHADER, sh_frag_glsl);
GLuint gs = COMPILE_NAME(GL_GEOMETRY_SHADER, sh_geom_glsl);
glAttachShader(pipe, vs);
glAttachShader(pipe, fs);
glAttachShader(pipe, gs);
glDeleteShader(vs);
glDeleteShader(fs);
glDeleteShader(gs);
return 1;
}