Chunk manager, fixed some chunk mesh problems

This commit is contained in:
2025-06-02 18:53:36 +02:00
parent f6efad02a6
commit 483f07ec19
26 changed files with 315 additions and 190 deletions
+4 -4
View File
@@ -1,9 +1,9 @@
SRC=src/math_3d.c src/main.c src/mesh.c src/program.c src/resources.c src/camera.c \
src/chunk/chunk.c src/chunk/noise.c src/chunk/chunkmesh.c src/flags.c src/texture.c
SRC=src/math_3d.c src/main.c src/program.c src/resources.c src/camera.c \
src/chunk/chunk.c src/chunk/mesh.c src/flags.c src/texture.c src/chunk/manager.c
OBJ=$(SRC:.c=.o)
CFLAGS=-Werror -Wextra -Wall `pkg-config --cflags sdl3 sdl3-image gl`
LDFLAGS=`pkg-config --libs sdl3 sdl3-image gl` -lm
CFLAGS=-Werror -Wextra -Wall `pkg-config --cflags sdl3 sdl3-image gl glib-2.0`
LDFLAGS=`pkg-config --libs sdl3 sdl3-image gl glib-2.0` -lm
TARGET=wschod
CC=gcc
LD=gcc
+2 -3
View File
@@ -3,19 +3,18 @@
precision lowp float;
varying vec2 f_uv;
varying vec3 f_material;
varying vec4 f_material;
varying float f_height;
uniform sampler2D materials[5];
void main ()
{
/* This means there can be four textures on a terrain. Could be
extended, but who cares? */
vec4 result = texture2D (materials[0], f_uv);
result = mix (result, texture2D (materials[1], f_uv), f_material[0]);
result = mix (result, texture2D (materials[2], f_uv), f_material[1]);
result = mix (result, texture2D (materials[3], f_uv), f_material[2]);
result = mix (result, texture2D (materials[4], f_uv), f_material[3]);
gl_FragColor = result;
}
+7 -6
View File
@@ -1,14 +1,15 @@
#version 100
attribute vec4 position;
attribute vec3 material;
attribute vec4 material;
varying vec2 f_uv;
varying vec4 f_material;
varying float f_height;
uniform mat4 view;
uniform mat4 projection;
varying vec2 f_uv;
varying vec3 f_material;
varying float f_height;
uniform vec4 chunk_position;
void main ()
{
@@ -16,5 +17,5 @@ void main ()
f_material = material;
f_height = position.y;
gl_Position = projection * view * position;
gl_Position = projection * view * (position + chunk_position);
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 50 KiB

+5 -3
View File
@@ -6,13 +6,15 @@ in
pkgs.mkShellNoCC {
packages = with pkgs; [
gcc
pkg-config
sdl3
sdl3-image
gdb
cglm
glew
glib
gcc
pkg-config
valgrind
gdb
];
}
+6
View File
@@ -46,3 +46,9 @@ Camera_get_projection (Camera *camera, float aspect)
return m4_perspective
(camera->fov, aspect, camera->near, camera->far);
}
void
Camera_print (Camera *camera)
{
INFO ("Camera position: (%6.1f, %6.1f, %6.1f)", camera->position.x, camera->position.y, camera->position.z);
}
+1
View File
@@ -18,3 +18,4 @@ vec3_t Camera_get_direction (Camera *camera);
vec3_t Camera_get_right (Camera *camera);
mat4_t Camera_get_view (Camera *camera);
mat4_t Camera_get_projection (Camera *camera, float aspect);
void Camera_print (Camera *camera);
+6 -11
View File
@@ -2,29 +2,24 @@
#include <math.h>
Chunk
Chunk *
Chunk_new ()
{
Chunk chunk;
chunk.heightmap = malloc (sizeof (float) * CHUNK_SIZE);
chunk.materialmap = malloc (sizeof (char) * CHUNK_SIZE);
INFO ("Created new Chunk. Memory size: %zu bytes",
sizeof (float) * CHUNK_SIZE + sizeof (char) * CHUNK_SIZE);
Chunk *chunk = malloc (sizeof (Chunk));
chunk->heightmap = malloc (sizeof (float) * CHUNK_SIZE);
chunk->materialmap = malloc (sizeof (char) * CHUNK_SIZE);
return chunk;
}
void
Chunk_noise (Chunk *chunk, int xoffset, int yoffset)
Chunk_random (Chunk *chunk)
{
for (int y = 0; y < CHUNK_DIM; ++y)
{
for (int x = 0; x < CHUNK_DIM; ++x)
{
(void) xoffset; (void) yoffset;
float val = sinf (x) + sinf (y);
(void) val;
chunk->heightmap[INDEX (x, y)] = 0;
chunk->materialmap[INDEX (x, y)] = rand () % 2;
chunk->materialmap[INDEX (x, y)] = rand () % 5;
}
}
}
+4 -3
View File
@@ -1,7 +1,8 @@
#pragma once
#include <stdlib.h>
#include "../util.h"
#include "noise.h"
#define CHUNK_DIM 16
#define CHUNK_SIZE (CHUNK_DIM*CHUNK_DIM)
@@ -14,7 +15,7 @@ typedef struct Chunk
char *materialmap;
} Chunk;
Chunk Chunk_new ();
void Chunk_noise (Chunk *chunk, int xoffset, int yoffset);
Chunk *Chunk_new ();
void Chunk_random (Chunk *chunk);
void Chunk_free (Chunk *chunk);
void Chunk_heightmap_print (Chunk *chunk);
+134
View File
@@ -0,0 +1,134 @@
#include "manager.h"
/* TODO: switch from string keys to struct keys or some other
stuff. */
ChunkManager chunk_manager;
void
ChunkManager_init ()
{
chunk_manager.chunks = g_hash_table_new (g_str_hash, g_str_equal);
chunk_manager.chunk_meshes = g_hash_table_new (g_str_hash, g_str_equal);
}
void
cm_get_chunk_pos (float x, float y, int *ox, int *oy)
{
*ox = floor (x / (float) CHUNK_DIM);
*oy = floor (y / (float) CHUNK_DIM);
}
char *
cm_coords_to_string (int ox, int oy)
{
char *buffer = malloc (sizeof (char) * 128);
snprintf (buffer, 128, "%d %d", ox, oy);
return buffer;
}
void
ChunkManager_update (float px, float py)
/* x = camera's X position, y = camera's Y position */
{
(void) px; (void) py;
int cx = 0, cy = 0;
/* cm_get_chunk_pos (px, py, &cx, &cy); */
for (int y = cy - RENDER_DISTANCE - 1; y <= cy + RENDER_DISTANCE + 1; ++y)
{
for (int x = cx - RENDER_DISTANCE - 1; x <= cx + RENDER_DISTANCE + 1; ++x)
{
if (ChunkManager_get_chunk_at (x, y) == NULL)
{
ChunkManager_generate_chunk_at (x, y);
}
}
}
for (int y = cy - RENDER_DISTANCE; y <= cy + RENDER_DISTANCE; ++y)
{
for (int x = cx - RENDER_DISTANCE; x <= cx + RENDER_DISTANCE; ++x)
{
if (ChunkManager_get_chunk_mesh_at (x, y) == NULL)
{
ChunkManager_generate_chunk_mesh_at (x, y);
}
}
}
}
void
ChunkManager_render (float px, float py, int program)
{
(void) px; (void) py;
int cx = 0, cy = 0;
/* cm_get_chunk_pos (px, py, &cx, &cy); */
for (int y = cy - RENDER_DISTANCE; y <= cy + RENDER_DISTANCE; ++y)
{
for (int x = cx - RENDER_DISTANCE; x <= cx + RENDER_DISTANCE; ++x)
{
ChunkMesh *mesh = ChunkManager_get_chunk_mesh_at (x, y);
if (mesh != NULL)
{
program_set_vec4 (program, "chunk_position", x * CHUNKMESH_DIM, 0.0, y * CHUNKMESH_DIM, 1.0);
ChunkMesh_render (mesh);
}
}
}
}
Chunk *
ChunkManager_get_chunk_at (int x, int y)
{
char *key = cm_coords_to_string (x, y);
return (Chunk *) g_hash_table_lookup (chunk_manager.chunks, key);
}
void
ChunkManager_set_chunk_at (int x, int y, Chunk *chunk)
{
char *key = cm_coords_to_string (x, y);
g_hash_table_insert (chunk_manager.chunks, key, chunk);
}
void
ChunkManager_generate_chunk_at (int x, int y)
{
Chunk *chunk = Chunk_new ();
Chunk_random (chunk);
ChunkManager_set_chunk_at (x, y, chunk);
}
void
ChunkManager_get_chunk_neighbors_at (int x, int y, Chunk **nr, Chunk **nd, Chunk **nc)
{
*nr = ChunkManager_get_chunk_at (x + 1, y);
*nd = ChunkManager_get_chunk_at (x, y + 1);
*nc = ChunkManager_get_chunk_at (x + 1, y + 1);
}
ChunkMesh *
ChunkManager_get_chunk_mesh_at (int x, int y)
{
char *key = cm_coords_to_string (x, y);
return (ChunkMesh *) g_hash_table_lookup (chunk_manager.chunk_meshes, key);
}
void
ChunkManager_set_chunk_mesh_at (int x, int y, ChunkMesh *mesh)
{
char *key = cm_coords_to_string (x, y);
g_hash_table_insert (chunk_manager.chunk_meshes, key, mesh);
}
void
ChunkManager_generate_chunk_mesh_at (int x, int y)
{
Chunk *nr, *nd, *nc;
ChunkManager_get_chunk_neighbors_at (x, y, &nr, &nd, &nc);
ChunkManager_set_chunk_mesh_at
(x, y, ChunkMesh_from_Chunk_and_neighbors (ChunkManager_get_chunk_at (x, y), nr, nd, nc));
}
+33
View File
@@ -0,0 +1,33 @@
#pragma once
/* Yes, glib. */
#include <glib-2.0/glib.h>
#include "../program.h"
#include "chunk.h"
#include "mesh.h"
#define RENDER_DISTANCE 1
typedef struct ChunkManager
{
GHashTable *chunks;
GHashTable *chunk_meshes;
GAsyncQueue *chunk_queue;
GAsyncQueue *chunk_mesh_queue;
} ChunkManager;
void ChunkManager_init ();
void ChunkManager_update (float px, float py);
void ChunkManager_render (float px, float py, int program);
Chunk *ChunkManager_get_chunk_at (int x, int y);
void ChunkManager_get_chunk_neighbors_at (int x, int y, Chunk **nr, Chunk **nd, Chunk **nc);
void ChunkManager_set_chunk_at (int x, int y, Chunk *chunk);
ChunkMesh *ChunkManager_get_chunk_mesh_at (int x, int y);
void ChunkManager_set_chunk_mesh_at (int x, int y, ChunkMesh *mesh);
void ChunkManager_generate_chunk_at (int x, int y);
void ChunkManager_generate_chunk_mesh_at (int x, int y);
@@ -1,20 +1,16 @@
#include "chunkmesh.h"
#include "mesh.h"
extern GameFlags game_flags;
ChunkMesh
ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nd, Chunk *nr, Chunk *nc)
ChunkMesh *
ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nr, Chunk *nd, Chunk *nc)
/* nd --- down neighbor; nr --- right neighbor; nc --- corner neighbor */
{
vec3_t *positions = malloc (sizeof (vec3_t) * CHUNKMESH_SIZE);
vec3_t *materials = malloc (sizeof (vec3_t) * CHUNKMESH_SIZE);
float *materials = malloc (sizeof (float) * 4 * CHUNKMESH_SIZE);
unsigned int *indices = malloc (sizeof (unsigned int) * CHUNKMESH_SIZE * 6);
INFO ("Temporarily allocated %zu bytes for ChunkMesh.",
(sizeof (vec3_t) * CHUNKMESH_SIZE * 2
+ sizeof (unsigned int) * CHUNKMESH_SIZE * 6));
int i_i = 0;
int m_i = 0, i_i = 0;
for (int y = 0; y < CHUNKMESH_DIM; ++y)
{
for (int x = 0; x < CHUNKMESH_DIM; ++x)
@@ -22,28 +18,29 @@ ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nd, Chunk *nr, Chunk *n
float height = chunk->heightmap[INDEX (x, y)];
float material_id = chunk->materialmap[INDEX (x, y)];
if (x == CHUNK_DIM && y < CHUNKMESH_DIM && nr != NULL)
if (x == CHUNK_DIM && y < CHUNK_DIM && nr != NULL)
{
height = nr->heightmap[INDEX (0, y)];
material_id = nr->materialmap[INDEX (0, y)];
}
if (y == CHUNK_DIM && x < CHUNKMESH_DIM && nd != NULL)
if (y == CHUNK_DIM && x < CHUNK_DIM && nd != NULL)
{
height = nd->heightmap[INDEX (x, 0)];
material_id = nr->materialmap[INDEX (x, 0)];
material_id = nd->materialmap[INDEX (x, 0)];
}
if (x == CHUNK_DIM && y == CHUNK_DIM && nc != NULL)
{
height = nc->heightmap[INDEX (0, 0)];
material_id = nr->materialmap[INDEX (0, 0)];
material_id = nc->materialmap[INDEX (0, 0)];
}
positions[CMINDEX (x, y)] = vec3 (x, height, y);
materials[CMINDEX (x, y)] = vec3
(material_id == 1 ? 1 : 0, material_id == 2 ? 1 : 0,
material_id == 3 ? 1 : 0);
materials[m_i++] = material_id == 1 ? 1 : 0;
materials[m_i++] = material_id == 2 ? 1 : 0;
materials[m_i++] = material_id == 3 ? 1 : 0;
materials[m_i++] = material_id == 4 ? 1 : 0;
if (x < CHUNK_DIM && y < CHUNK_DIM)
{
@@ -69,22 +66,22 @@ ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nd, Chunk *nr, Chunk *n
}
}
ChunkMesh mesh;
glGenBuffers (1, &mesh.pbo);
glGenBuffers (1, &mesh.mbo);
glGenBuffers (1, &mesh.ebo);
ChunkMesh *mesh = malloc (sizeof (ChunkMesh));
glGenBuffers (1, &mesh->pbo);
glGenBuffers (1, &mesh->mbo);
glGenBuffers (1, &mesh->ebo);
glBindBuffer (GL_ARRAY_BUFFER, mesh.pbo);
glBindBuffer (GL_ARRAY_BUFFER, mesh->pbo);
glBufferData (GL_ARRAY_BUFFER, sizeof (vec3_t) * CHUNKMESH_SIZE, positions, GL_STATIC_DRAW);
glEnableVertexAttribArray (0);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (vec3_t), 0);
glBindBuffer (GL_ARRAY_BUFFER, mesh.mbo);
glBufferData (GL_ARRAY_BUFFER, sizeof (vec3_t) * CHUNKMESH_SIZE, materials, GL_STATIC_DRAW);
glBindBuffer (GL_ARRAY_BUFFER, mesh->mbo);
glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 4 * CHUNKMESH_SIZE, materials, GL_STATIC_DRAW);
glEnableVertexAttribArray (1);
glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, sizeof (vec3_t), 0);
glVertexAttribPointer (1, 4, GL_FLOAT, GL_FALSE, sizeof (float) * 4, 0);
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh.ebo);
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh->ebo);
glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (unsigned int) * CHUNKMESH_SIZE * 6, indices, GL_STATIC_DRAW);
glBindBuffer (GL_ARRAY_BUFFER, 0);
@@ -100,15 +97,23 @@ ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nd, Chunk *nr, Chunk *n
void
ChunkMesh_render (ChunkMesh *mesh)
{
glBindBuffer (GL_ARRAY_BUFFER, mesh->pbo);
glEnableVertexAttribArray (0);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (vec3_t), 0);
glBindBuffer (GL_ARRAY_BUFFER, mesh->mbo);
glEnableVertexAttribArray (1);
glVertexAttribPointer (1, 4, GL_FLOAT, GL_FALSE, sizeof (float) * 4, 0);
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh->ebo);
if (game_flags.wireframe_enabled)
{
glDrawElements (GL_LINES, CHUNKMESH_SIZE * 6, GL_UNSIGNED_INT, 0);
glDrawElements (GL_LINES, CHUNK_SIZE * 6, GL_UNSIGNED_INT, 0);
}
else
{
glDrawElements (GL_TRIANGLES, CHUNKMESH_SIZE * 6, GL_UNSIGNED_INT, 0);
glDrawElements (GL_TRIANGLES, CHUNK_SIZE * 6, GL_UNSIGNED_INT, 0);
}
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
@@ -6,7 +6,6 @@
#include "../math_3d.h"
#include "chunk.h"
/* TODO: set to + 1 */
#define CHUNKMESH_DIM (CHUNK_DIM+1)
#define CHUNKMESH_SIZE (CHUNKMESH_DIM*CHUNKMESH_DIM)
#define CMINDEX(x, y) (CHUNKMESH_DIM * (y) + (x))
@@ -18,5 +17,6 @@ typedef struct ChunkMesh
unsigned int ebo;
} ChunkMesh;
ChunkMesh ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nd, Chunk *nr, Chunk *nc);
/* Rename to ChunkMesh_build */
ChunkMesh *ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nr, Chunk *nd, Chunk *nc);
void ChunkMesh_render (ChunkMesh *mesh);
-43
View File
@@ -1,43 +0,0 @@
#include "noise.h"
static u_int8_t *perm;
void
noise_seed (int seed)
{
srand (seed);
perm = malloc (sizeof (u_int8_t) * 256);
for (size_t i = 0; i < 256; ++i) {
perm[i] = i;
}
for (size_t i = 0; i < 255; ++i) {
size_t j = i + rand() / (RAND_MAX / (256 - i) + 1);
u_int8_t t = perm[j];
perm[j] = perm[i];
perm[i] = t;
}
}
float
noise2 (float x, float y)
{
int X = (int) FASTFLOOR (x) & 0xff;
int Y = (int) FASTFLOOR (y) & 0xff;
x -= FASTFLOOR (x);
y -= FASTFLOOR (y);
float u = FADE (x);
float v = FADE (y);
int A = (perm[X] + Y) & 0xff;
int B = (perm[X + 1] + Y) & 0xff;
return LERP
(v, LERP
(u, GRAD2
(perm[A], x, y),
GRAD2(perm[B], x - 1, y)),
LERP(u, GRAD2
(perm[A + 1], x, y - 1),
GRAD2(perm[B + 1], x - 1, y - 1)));
}
-17
View File
@@ -1,17 +0,0 @@
#pragma once
#include <stdlib.h>
#include <stddef.h>
#define FADE(t) (((6 * t - 15) * t + 10) * t * t * t)
#define LERP(t, a, b) (a + t * (b - a))
#define FASTFLOOR(x) (((int) (x) < (x)) ? ((int) x) : ((int) x - 1))
static inline float
GRAD2 (int hash, float x, float y)
{
return ((hash & 1) ? -x : x) + ((hash & 2) ? -y : y);
}
void noise_seed (int seed);
float noise2 (float x, float y);
+23 -23
View File
@@ -4,11 +4,10 @@
#include <stdio.h>
#include "chunk/chunkmesh.h"
#include "chunk/manager.h"
#include "state.h"
#include "flags.h"
#include "camera.h"
#include "mesh.h"
#include "resources.h"
/* TODO: switch back to cglm.h, since it's faster or something */
@@ -19,8 +18,8 @@ static SDL_GLContext context = NULL;
extern GameState game_state;
extern GameFlags game_flags;
extern Resources resources;
extern ChunkManager chunk_manager;
static ChunkMesh test_chunkmesh;
static Camera camera;
SDL_AppResult
@@ -71,16 +70,11 @@ SDL_AppInit (void **appstate, int argc, char **argv)
/* Initialize and load resources. */
Resources_init ();
noise_seed (1337);
/* Generate a test chunk. */
Chunk chunk = Chunk_new ();
Chunk_noise (&chunk, 0, 0);
test_chunkmesh = ChunkMesh_from_Chunk_and_neighbors (&chunk, NULL, NULL, NULL);
ChunkManager_init ();
program_use (resources.programs[1]);
int arr[4] = { 0, 1, 2, 3 };
program_set_int_array (resources.programs[1], "materials", 4, arr);
int arr[5] = { 0, 1, 2, 3, 4 };
program_set_int_array (resources.programs[1], "materials", 5, arr);
/* Set up game state. */
game_state.last_time = SDL_GetTicks ();
@@ -91,7 +85,6 @@ SDL_AppInit (void **appstate, int argc, char **argv)
/* Initialize the default camera. */
camera = Camera_default ();
camera.position.z = -1.0;
return SDL_APP_CONTINUE;
}
@@ -133,6 +126,14 @@ SDL_AppEvent (void *appstate, SDL_Event *event)
case SDLK_F1:
game_flags.wireframe_enabled = !game_flags.wireframe_enabled;
break;
case SDLK_F2:
int active_program;
glGetIntegerv (GL_CURRENT_PROGRAM, &active_program);
program_print (active_program);
break;
case SDLK_F3:
Camera_print (&camera);
break;
}
}
@@ -172,48 +173,47 @@ SDL_AppIterate (void *appstate)
{
camera.position = v3_add
(camera.position, v3_muls
(Camera_get_direction (&camera), game_state.delta_time));
(Camera_get_direction (&camera), game_state.delta_time * 5));
}
if (game_flags.moving_backward)
{
camera.position = v3_sub
(camera.position, v3_muls
(Camera_get_direction (&camera), game_state.delta_time));
(Camera_get_direction (&camera), game_state.delta_time * 5));
}
if (game_flags.moving_right)
{
camera.position = v3_add
(camera.position, v3_muls
(Camera_get_right (&camera), game_state.delta_time));
(Camera_get_right (&camera), game_state.delta_time * 5));
}
if (game_flags.moving_left)
{
camera.position = v3_sub
(camera.position, v3_muls
(Camera_get_right (&camera), game_state.delta_time));
(Camera_get_right (&camera), game_state.delta_time * 5));
}
ChunkManager_update (camera.position.x, camera.position.z);
/* Render stuff. */
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mat4_t view = Camera_get_view (&camera);
mat4_t projection = Camera_get_projection (&camera, 640.0 / 480.0);
program_use (resources.programs[1]);
program_set_mat4 (resources.programs[1], "projection", Camera_get_projection (&camera, 640.0 / 480.0));
program_set_mat4 (resources.programs[1], "view", Camera_get_view (&camera));
for (size_t i = 0; i < resources.textures_len; ++i)
{
glActiveTexture (GL_TEXTURE0 + i);
glBindTexture (GL_TEXTURE_2D, resources.textures[i]);
}
program_set_mat4 (resources.programs[1], "view", view);
program_set_mat4 (resources.programs[1], "projection", projection);
ChunkMesh_render (&test_chunkmesh);
ChunkManager_render (camera.position.x, camera.position.z, resources.programs[1]);
glBindTexture (GL_TEXTURE_2D, 0);
-21
View File
@@ -1,21 +0,0 @@
#include "mesh.h"
Mesh
Mesh_new (size_t vertices_len, float *vertices)
{
Mesh mesh = { vertices_len, vertices, 0 };
glGenBuffers (1, &mesh.vbo);
glBindBuffer (GL_ARRAY_BUFFER, mesh.vbo);
glBufferData (GL_ARRAY_BUFFER, vertices_len * sizeof (float), vertices, GL_STATIC_DRAW);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof (float), 0);
glEnableVertexAttribArray (0);
return mesh;
}
void
Mesh_draw (Mesh *mesh)
{
glBindBuffer (GL_ARRAY_BUFFER, mesh->vbo);
glDrawArrays (GL_TRIANGLES, 0, mesh->vertices_len);
}
-15
View File
@@ -1,15 +0,0 @@
#pragma once
#include <SDL3/SDL_opengles2.h>
#include "util.h"
typedef struct Mesh
{
size_t vertices_len;
float *vertices;
GLuint vbo;
} Mesh;
Mesh Mesh_new (size_t vertices_len, float *vertices);
void Mesh_draw (Mesh *mesh);
+45 -12
View File
@@ -72,6 +72,12 @@ program_create (const char *v_src, const char *f_src)
return program;
}
void
program_set_vec4 (int program, const char *name, float x, float y, float z, float w)
{
glUniform4f (glGetUniformLocation (program, name), x, y, z, w);
}
void
program_set_int_array (int program, const char *name, size_t count, int *value)
{
@@ -104,26 +110,53 @@ gl_type_to_string (GLenum type)
void
program_print (int program)
/* This function assumes that `program' is the active program. */
{
int bufsize;
glGetProgramiv (program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &bufsize);
char name[bufsize];
int uniform_no, attribute_no;
glGetProgramiv (program, GL_ACTIVE_UNIFORMS, &uniform_no);
glGetProgramiv (program, GL_ACTIVE_ATTRIBUTES, &attribute_no);
INFO ("== Program %d ==", program);
INFO ("== Program %d: %d active attribute(s) / %d active uniform(s) ==", program, attribute_no, uniform_no);
int attr_len;
glGetProgramiv (program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &attr_len);
char attr[attr_len];
int attribute_no;
glGetProgramiv (program, GL_ACTIVE_ATTRIBUTES, &attribute_no);
GLenum type;
for (GLint i = 0; i < attribute_no; i++) {
glGetActiveAttrib (program, i, bufsize, NULL, NULL, &type, name);
INFO ("Attribute #%d: %s %s", i, gl_type_to_string (type), name);
glGetActiveAttrib (program, i, attr_len, NULL, NULL, &type, attr);
INFO ("Attribute #%d: %s %s", i, gl_type_to_string (type), attr);
}
int uniform_len;
glGetProgramiv (program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniform_len);
char uniform[uniform_len];
int uniform_no;
glGetProgramiv (program, GL_ACTIVE_UNIFORMS, &uniform_no);
float *vec = malloc (sizeof (float) * 4);
for (GLint i = 0; i < uniform_no; i++) {
glGetActiveUniform (program, i, bufsize, NULL, NULL, &type, name);
INFO ("Uniform #%d: %s %s", i, gl_type_to_string (type), name);
glGetActiveUniform (program, i, uniform_len, NULL, NULL, &type, uniform);
switch (type)
{
case GL_FLOAT_VEC3:
glGetUniformfv (program, glGetUniformLocation (program, uniform), vec);
INFO ("Uniform #%d: %s %s = (%5.1f,%5.1f,%5.1f)", i, gl_type_to_string (type),
uniform, vec[0], vec[1], vec[2]);
break;
case GL_FLOAT_VEC4:
glGetUniformfv (program, glGetUniformLocation (program, uniform), vec);
INFO ("Uniform #%d: %s %s = (%5.1f,%5.1f,%5.1f,%5.1f)", i, gl_type_to_string (type),
uniform, vec[0], vec[1], vec[2], vec[3]);
break;
default:
INFO ("Uniform #%d: %s %s", i, gl_type_to_string (type), uniform);
break;
}
}
free (vec);
}
+1
View File
@@ -12,5 +12,6 @@ void shader_fail (int shader);
void program_fail (int program);
int program_create (const char *v_src, const char *f_src);
void program_set_int_array (int program, const char *name, size_t count, int *value);
void program_set_vec4 (int program, const char *name, float x, float y, float z, float w);
void program_set_mat4 (int program, const char *name, mat4_t value);
void program_print (int program);
+1
View File
@@ -80,6 +80,7 @@ Resources_init ()
Resources_load_texture ("res/textures/dirt.png");
Resources_load_texture ("res/textures/drygrass.png");
Resources_load_texture ("res/textures/grass.png");
Resources_load_texture ("res/textures/rock_cement.png");
Resources_load_texture ("res/textures/asphalt_gravel.png");
}
+9
View File
@@ -16,3 +16,12 @@
#define FATAL(fmt, args...) (fprintf (stderr, COLOR_RED "[!] %s:%d:%s(): " COLOR_RESET fmt "\n", __FILE__, __LINE__, __func__, ##args), exit (-1))
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
typedef struct ivec2_t { int x; int y; } ivec2_t;
static inline ivec2_t
ivec2 (int x, int y)
{
ivec2_t v = { x, y };
return v;
}