generated from AfonsoCMSousa/CPP-OpenGLTemplate
114 lines
3.3 KiB
C++
114 lines
3.3 KiB
C++
#pragma once
|
|
#include <glad/glad.h>
|
|
#include <glm/glm.hpp>
|
|
#include <glm/gtc/type_ptr.hpp>
|
|
#include <vector>
|
|
|
|
// XZ floor grid, centered at origin
|
|
// SIZE = half-extent (25 means grid goes -25 to +25)
|
|
// STEP = spacing between lines
|
|
static constexpr int GRID_SIZE = 25;
|
|
static constexpr float GRID_STEP = 1.0f;
|
|
|
|
struct GridRenderer {
|
|
unsigned int VAO, VBO;
|
|
unsigned int shader;
|
|
int vertex_count;
|
|
};
|
|
|
|
static const char *GRID_VERT_SRC = R"(
|
|
#version 330 core
|
|
layout(location = 0) in vec3 aPos;
|
|
uniform mat4 uMVP;
|
|
void main() {
|
|
gl_Position = uMVP * vec4(aPos, 1.0);
|
|
}
|
|
)";
|
|
|
|
static const char *GRID_FRAG_SRC = R"(
|
|
#version 330 core
|
|
out vec4 FragColor;
|
|
void main() {
|
|
FragColor = vec4(0.35, 0.35, 0.35, 1.0);
|
|
}
|
|
)";
|
|
|
|
inline GridRenderer grid_init() {
|
|
GridRenderer r;
|
|
|
|
// Build vertices on the CPU — two endpoints per line, X-parallel and Z-parallel
|
|
std::vector<float> verts;
|
|
verts.reserve(4 * 3 * (GRID_SIZE * 2 + 1) * 2); // rough upper bound
|
|
|
|
float lo = -GRID_SIZE * GRID_STEP;
|
|
float hi = GRID_SIZE * GRID_STEP;
|
|
|
|
for (int i = -GRID_SIZE; i <= GRID_SIZE; i++) {
|
|
float t = i * GRID_STEP;
|
|
|
|
// Line parallel to X axis (varies X, fixed Z=t)
|
|
verts.insert(verts.end(), { lo, 0.0f, t,
|
|
hi, 0.0f, t });
|
|
|
|
// Line parallel to Z axis (fixed X=t, varies Z)
|
|
verts.insert(verts.end(), { t, 0.0f, lo,
|
|
t, 0.0f, hi });
|
|
}
|
|
|
|
r.vertex_count = (int)(verts.size() / 3);
|
|
|
|
// Compile shaders
|
|
int success;
|
|
char log[512];
|
|
|
|
unsigned int vert = glCreateShader(GL_VERTEX_SHADER);
|
|
glShaderSource(vert, 1, &GRID_VERT_SRC, NULL);
|
|
glCompileShader(vert);
|
|
glGetShaderiv(vert, GL_COMPILE_STATUS, &success);
|
|
if (!success) { glGetShaderInfoLog(vert, 512, NULL, log); fprintf(stderr, "Grid vert: %s\n", log); }
|
|
|
|
unsigned int frag = glCreateShader(GL_FRAGMENT_SHADER);
|
|
glShaderSource(frag, 1, &GRID_FRAG_SRC, NULL);
|
|
glCompileShader(frag);
|
|
glGetShaderiv(frag, GL_COMPILE_STATUS, &success);
|
|
if (!success) { glGetShaderInfoLog(frag, 512, NULL, log); fprintf(stderr, "Grid frag: %s\n", log); }
|
|
|
|
r.shader = glCreateProgram();
|
|
glAttachShader(r.shader, vert);
|
|
glAttachShader(r.shader, frag);
|
|
glLinkProgram(r.shader);
|
|
glGetProgramiv(r.shader, GL_LINK_STATUS, &success);
|
|
if (!success) { glGetProgramInfoLog(r.shader, 512, NULL, log); fprintf(stderr, "Grid link: %s\n", log); }
|
|
glDeleteShader(vert);
|
|
glDeleteShader(frag);
|
|
|
|
// Upload geometry
|
|
glGenVertexArrays(1, &r.VAO);
|
|
glGenBuffers(1, &r.VBO);
|
|
|
|
glBindVertexArray(r.VAO);
|
|
glBindBuffer(GL_ARRAY_BUFFER, r.VBO);
|
|
glBufferData(GL_ARRAY_BUFFER, verts.size() * sizeof(float), verts.data(), GL_STATIC_DRAW);
|
|
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
|
glEnableVertexAttribArray(0);
|
|
|
|
glBindVertexArray(0);
|
|
return r;
|
|
}
|
|
|
|
inline void grid_draw(const GridRenderer &r, const glm::mat4 &mvp) {
|
|
glUseProgram(r.shader);
|
|
glUniformMatrix4fv(glGetUniformLocation(r.shader, "uMVP"), 1, GL_FALSE, glm::value_ptr(mvp));
|
|
glBindVertexArray(r.VAO);
|
|
glLineWidth(1.0f);
|
|
glDrawArrays(GL_LINES, 0, r.vertex_count);
|
|
glBindVertexArray(0);
|
|
}
|
|
|
|
inline void grid_destroy(GridRenderer &r) {
|
|
glDeleteVertexArrays(1, &r.VAO);
|
|
glDeleteBuffers(1, &r.VBO);
|
|
glDeleteProgram(r.shader);
|
|
}
|