Working chunk and textures
This commit is contained in:
+3
-3
@@ -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/chunk/chunk.c src/chunk/noise.c src/chunk/chunkmesh.c src/flags.c src/texture.c
|
||||
|
||||
OBJ=$(SRC:.c=.o)
|
||||
CFLAGS=-g -Werror -Wextra -Wall `pkg-config --cflags sdl3 gl`
|
||||
LDFLAGS=`pkg-config --libs sdl3 gl` -lm
|
||||
CFLAGS=-Werror -Wextra -Wall `pkg-config --cflags sdl3 sdl3-image gl`
|
||||
LDFLAGS=`pkg-config --libs sdl3 sdl3-image gl` -lm
|
||||
TARGET=wschod
|
||||
CC=gcc
|
||||
LD=gcc
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#version 100
|
||||
|
||||
precision lowp float;
|
||||
|
||||
varying vec2 f_uv;
|
||||
varying float f_height;
|
||||
|
||||
void main ()
|
||||
{
|
||||
gl_FragColor = vec4 (f_uv.x, 1.0, f_uv.y, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#version 100
|
||||
|
||||
precision lowp float;
|
||||
|
||||
varying vec2 f_uv;
|
||||
varying vec3 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]);
|
||||
|
||||
gl_FragColor = result * vec4(f_height, f_height, f_height, 1.0);
|
||||
}
|
||||
@@ -1,17 +1,20 @@
|
||||
#version 100
|
||||
|
||||
attribute vec3 position;
|
||||
attribute vec4 position;
|
||||
attribute vec3 material;
|
||||
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
varying vec2 f_uv;
|
||||
varying vec3 f_material;
|
||||
varying float f_height;
|
||||
|
||||
void main ()
|
||||
{
|
||||
f_uv = position.xy / 8.0;
|
||||
f_material = material;
|
||||
f_height = position.y;
|
||||
|
||||
gl_Position = projection * view * vec4 (position, 1.0);
|
||||
gl_Position = projection * view * position;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
@@ -9,8 +9,10 @@ pkgs.mkShellNoCC {
|
||||
gcc
|
||||
pkg-config
|
||||
sdl3
|
||||
sdl3-image
|
||||
gdb
|
||||
cglm
|
||||
glew
|
||||
valgrind
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "chunk.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
Chunk
|
||||
Chunk_new ()
|
||||
{
|
||||
@@ -18,9 +20,11 @@ Chunk_noise (Chunk *chunk, int xoffset, int yoffset)
|
||||
{
|
||||
for (int x = 0; x < CHUNK_DIM; ++x)
|
||||
{
|
||||
float val = noise2 ((x + xoffset * CHUNK_DIM), (y + yoffset * CHUNK_DIM)) * 8;
|
||||
chunk->heightmap[INDEX (x, y)] = val;
|
||||
chunk->materialmap[INDEX (x, y)] = 0;
|
||||
(void) xoffset; (void) yoffset;
|
||||
float val = sinf (x) + sinf (y);
|
||||
(void) val;
|
||||
chunk->heightmap[INDEX (x, y)] = (val + 0.5);
|
||||
chunk->materialmap[INDEX (x, y)] = (int) val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#define CHUNK_DIM 16
|
||||
#define CHUNK_SIZE (CHUNK_DIM*CHUNK_DIM)
|
||||
|
||||
#define INDEX(x, y) (CHUNK_DIM * y + x)
|
||||
#define INDEX(x, y) (CHUNK_DIM * (y) + (x))
|
||||
|
||||
typedef struct Chunk
|
||||
{
|
||||
|
||||
@@ -7,31 +7,43 @@ ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nd, Chunk *nr, Chunk *n
|
||||
/* 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);
|
||||
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;
|
||||
for (int y = 0; y < CHUNKMESH_DIM; ++y)
|
||||
{
|
||||
for (int x = 0; x < CHUNKMESH_DIM; ++x)
|
||||
{
|
||||
float height = chunk->heightmap[INDEX (x, y)];
|
||||
|
||||
float material_id = chunk->materialmap[INDEX (x, y)];
|
||||
|
||||
if (x == CHUNK_DIM && y < CHUNKMESH_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)
|
||||
{
|
||||
height = nd->heightmap[INDEX (x, 0)];
|
||||
material_id = nr->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)];
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (x < CHUNK_DIM && y < CHUNK_DIM)
|
||||
{
|
||||
@@ -41,11 +53,11 @@ ChunkMesh_from_Chunk_and_neighbors (Chunk *chunk, Chunk *nd, Chunk *nr, Chunk *n
|
||||
int i3 = CMINDEX (x + 1, y + 1);
|
||||
|
||||
/*
|
||||
i0----i1
|
||||
| |
|
||||
| |
|
||||
i2----i3
|
||||
*/
|
||||
i0----i1
|
||||
| \ |
|
||||
| \ |
|
||||
i2----i3
|
||||
*/
|
||||
|
||||
indices[i_i++] = i0;
|
||||
indices[i_i++] = i2;
|
||||
@@ -59,17 +71,27 @@ 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);
|
||||
|
||||
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);
|
||||
glEnableVertexAttribArray (1);
|
||||
glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, sizeof (vec3_t), 0);
|
||||
|
||||
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);
|
||||
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
free (positions);
|
||||
free (materials);
|
||||
free (indices);
|
||||
|
||||
return mesh;
|
||||
@@ -79,7 +101,7 @@ void
|
||||
ChunkMesh_render (ChunkMesh *mesh)
|
||||
{
|
||||
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh->ebo);
|
||||
|
||||
|
||||
if (game_flags.wireframe_enabled)
|
||||
{
|
||||
glDrawElements (GL_LINES, CHUNKMESH_SIZE * 6, GL_UNSIGNED_INT, 0);
|
||||
@@ -88,4 +110,6 @@ ChunkMesh_render (ChunkMesh *mesh)
|
||||
{
|
||||
glDrawElements (GL_TRIANGLES, CHUNKMESH_SIZE * 6, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
#include "../math_3d.h"
|
||||
#include "chunk.h"
|
||||
|
||||
#define CHUNKMESH_DIM (CHUNK_SIZE+1)
|
||||
#define CHUNKMESH_DIM (CHUNK_DIM+1)
|
||||
#define CHUNKMESH_SIZE (CHUNKMESH_DIM*CHUNKMESH_DIM)
|
||||
#define CMINDEX(x, y) (CHUNKMESH_DIM * y + x)
|
||||
#define CMINDEX(x, y) (CHUNKMESH_DIM * (y) + (x))
|
||||
|
||||
typedef struct ChunkMesh
|
||||
{
|
||||
unsigned int pbo;
|
||||
/* Element Buffer Object, the indices. */
|
||||
unsigned int mbo;
|
||||
unsigned int ebo;
|
||||
} ChunkMesh;
|
||||
|
||||
|
||||
@@ -23,12 +23,12 @@ noise_seed (int seed)
|
||||
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 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;
|
||||
|
||||
|
||||
+12
-4
@@ -66,6 +66,9 @@ SDL_AppInit (void **appstate, int argc, char **argv)
|
||||
glViewport(0, 0, 640, 480);
|
||||
glClearColor (0, 0.3, 0.8, 1);
|
||||
|
||||
glEnable (GL_CULL_FACE);
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
|
||||
/* Initialize and load resources. */
|
||||
Resources_init ();
|
||||
noise_seed (1337);
|
||||
@@ -75,14 +78,12 @@ SDL_AppInit (void **appstate, int argc, char **argv)
|
||||
Chunk_noise (&chunk, 0, 0);
|
||||
test_chunkmesh = ChunkMesh_from_Chunk_and_neighbors (&chunk, NULL, NULL, NULL);
|
||||
|
||||
program_use (resources.programs[1]);
|
||||
program_print (resources.programs[1]);
|
||||
|
||||
/* Set up game state. */
|
||||
game_state.last_time = SDL_GetTicks ();
|
||||
|
||||
/* Set some basic game flags for testing. */
|
||||
game_flags.can_free_look = 1;
|
||||
game_flags.wireframe_enabled = 0;
|
||||
|
||||
/* Initialize the default camera. */
|
||||
camera = Camera_default ();
|
||||
@@ -193,12 +194,19 @@ SDL_AppIterate (void *appstate)
|
||||
|
||||
/* Render stuff. */
|
||||
|
||||
glClear (GL_COLOR_BUFFER_BIT);
|
||||
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]);
|
||||
|
||||
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);
|
||||
|
||||
+34
-4
@@ -6,7 +6,7 @@ void
|
||||
Resources_add_program (const char *v_src, const char *f_src)
|
||||
{
|
||||
resources.programs_len++;
|
||||
resources.programs = realloc (resources.programs, sizeof (int) * resources.programs_len);
|
||||
resources.programs = realloc (resources.programs, sizeof (unsigned int) * resources.programs_len);
|
||||
resources.programs[resources.programs_len - 1] = program_create (v_src, f_src);
|
||||
}
|
||||
|
||||
@@ -47,18 +47,48 @@ Resources_load_program (const char *v_path, const char *f_path)
|
||||
free (f_src);
|
||||
}
|
||||
|
||||
void
|
||||
Resources_add_texture (int width, int height, unsigned char *data)
|
||||
{
|
||||
resources.textures_len++;
|
||||
resources.textures = realloc (resources.textures, sizeof (unsigned int) * resources.textures_len);
|
||||
resources.textures[resources.textures_len - 1] = texture_create (width, height, data);
|
||||
}
|
||||
|
||||
void
|
||||
Resources_load_texture (const char *path)
|
||||
{
|
||||
SDL_Surface *surface = IMG_Load (path);
|
||||
|
||||
if (surface == NULL)
|
||||
{
|
||||
WARN ("Failed to load texture from path %s: %s", path, SDL_GetError ());
|
||||
}
|
||||
|
||||
Resources_add_texture (surface->w, surface->h, surface->pixels);
|
||||
SDL_DestroySurface (surface);
|
||||
}
|
||||
|
||||
void
|
||||
Resources_init ()
|
||||
{
|
||||
resources.programs_len = 0;
|
||||
resources.programs = malloc (sizeof (int));
|
||||
Resources_load_program ("res/default.vert", "res/default.frag");
|
||||
Resources_load_program ("res/chunk.vert", "res/chunk.frag");
|
||||
resources.programs = malloc (sizeof (unsigned int));
|
||||
Resources_load_program ("res/shaders/default.vert", "res/shaders/default.frag");
|
||||
Resources_load_program ("res/shaders/chunk.vert", "res/shaders/chunk.frag");
|
||||
|
||||
resources.textures_len = 0;
|
||||
resources.textures = malloc (sizeof (unsigned int));
|
||||
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/asphalt_gravel.png");
|
||||
}
|
||||
|
||||
void
|
||||
Resources_free ()
|
||||
{
|
||||
free (resources.programs);
|
||||
free (resources.textures);
|
||||
}
|
||||
|
||||
|
||||
+11
-1
@@ -1,13 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3_image/SDL_image.h>
|
||||
|
||||
#include "program.h"
|
||||
#include "texture.h"
|
||||
|
||||
typedef struct Resources {
|
||||
size_t programs_len;
|
||||
int *programs;
|
||||
unsigned int *programs;
|
||||
|
||||
size_t textures_len;
|
||||
unsigned int *textures;
|
||||
} Resources;
|
||||
|
||||
void Resources_add_program (const char *v_src, const char *f_src);
|
||||
void Resources_load_program (const char *v_path, const char *f_path);
|
||||
|
||||
void Resources_add_texture (int width, int height, unsigned char *data);
|
||||
void Resources_load_texture (const char *path);
|
||||
|
||||
void Resources_init ();
|
||||
void Resources_free ();
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "texture.h"
|
||||
|
||||
unsigned int
|
||||
texture_create (int width, int height, unsigned char *data)
|
||||
{
|
||||
unsigned int texture;
|
||||
glGenTextures (1, &texture);
|
||||
glBindTexture (GL_TEXTURE_2D, texture);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap (GL_TEXTURE_2D);
|
||||
glBindTexture (GL_TEXTURE_2D, 0);
|
||||
|
||||
return texture;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL_opengles2.h>
|
||||
|
||||
unsigned int texture_create (int width, int height, unsigned char *data);
|
||||
Reference in New Issue
Block a user