fallingCand/main.c
2025-11-29 14:08:35 -08:00

133 lines
3.7 KiB
C

// main.c
#include <stdio.h>
#include <stdlib.h>
#include "gl_utils.h"
#include "sand_sim.h"
#define GRID_W 2048
#define GRID_H 2048
static int g_fbWidth = 800;
static int g_fbHeight = 800;
SandSim sim;
static void render_sand(SandSim* sim,
GLuint program,
GLuint vao,
int fbW,
int fbH) {
glUseProgram(program);
GLint uResLoc = glGetUniformLocation(program, "u_resolution");
GLint uGridLoc = glGetUniformLocation(program, "u_gridSize");
GLint uStateLoc = glGetUniformLocation(program, "u_state");
if (uResLoc >= 0) {
glUniform2f(uResLoc, (float)fbW, (float)fbH);
}
if (uGridLoc >= 0) {
glUniform2i(uGridLoc, sim->gridW, sim->gridH);
}
if (uStateLoc >= 0) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, sim->tex_curr);
glUniform1i(uStateLoc, 0);
}
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
int main(void) {
GLFWwindow* window = init_glfw_glad("Falling Sand - Fullscreen Quad", g_fbWidth, g_fbHeight);
if (!window) {
return EXIT_FAILURE;
}
glfwGetFramebufferSize(window, &g_fbWidth, &g_fbHeight);
glViewport(0, 0, g_fbWidth, g_fbHeight);
printf("Renderer: %s\n", (const char*)glGetString(GL_RENDERER));
printf("OpenGL: %s\n", (const char*)glGetString(GL_VERSION));
printf("GLSL: %s\n", (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION));
// --- Create fullscreen triangle geometry (VAO + VBO) ---
float vertices[] = {
// x, y
-1.0f, -1.0f,
3.0f, -1.0f,
-1.0f, 3.0f};
GLuint vao = 0, vbo = 0;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// layout(location = 0) in vec2 aPos;
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,
2,
GL_FLOAT,
GL_FALSE,
2 * sizeof(float),
(void*)0);
glBindVertexArray(0);
if (!sand_init(&sim, GRID_W, GRID_H, "shaders/sand_step.comp")) {
fprintf(stderr, "Failed to initialize sand sim\n");
return EXIT_FAILURE;
}
// --- Create shader program ---
GLuint program = create_program_from_files(
"shaders/fullscreen.vert",
"shaders/sand_display.frag");
glUseProgram(program);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
double sim_dt = 1.0 / 360.0;
double currentTime = glfwGetTime();
double accumulator = 0.0;
// --- Main loop ---
while (!glfwWindowShouldClose(window)) {
double newTime = glfwGetTime();
double frameTime = newTime - currentTime;
currentTime = newTime;
if (frameTime > 0.25) frameTime = 0.25;
accumulator += frameTime;
while (accumulator >= sim_dt) {
sand_step_gpu(&sim); // one discrete CA step on the GPU (commented bc unimplemeted)
accumulator -= sim_dt;
}
glfwPollEvents();
// Re-query framebuffer size each frame (cheap and simple)
int fbw, fbh;
glfwGetFramebufferSize(window, &fbw, &fbh);
if (fbw != g_fbWidth || fbh != g_fbHeight) {
g_fbWidth = fbw;
g_fbHeight = fbh;
glViewport(0, 0, g_fbWidth, g_fbHeight);
}
glClear(GL_COLOR_BUFFER_BIT);
render_sand(&sim, program, vao, g_fbWidth, g_fbHeight);
glfwSwapBuffers(window);
}
// --- Cleanup ---
glDeleteProgram(program);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
glfwDestroyWindow(window);
glfwTerminate();
return EXIT_SUCCESS;
}