Created chunk renderer

This commit is contained in:
Eric-Paul Ickhorn 2023-10-11 10:10:06 +02:00
parent fec3d35fe9
commit 132f84a43f
9 changed files with 394 additions and 30 deletions

View File

@ -20,6 +20,7 @@ typedef struct tc_block_attribute
typedef struct tc_block_entry
{
char *name;
uint32_t identifier;
uint32_t attributes_capacity;
uint32_t num_attributes;

View File

@ -0,0 +1,31 @@
#include "world.h"
bool tc_generate_default_terrain_chunk(tc_worldgen_s *gen, tc_chunk_s *chunk)
{
tc_block_s block;
block.type_identifier = 1;
block.position.x = 0.0f;
block.position.y = 0.0f;
block.position.z = 0.0f;
uint32_t x_in_chunk = 0;
uint32_t y_in_chunk = 0;
uint32_t z_in_chunk = 0;
while(x_in_chunk < 32)
{
y_in_chunk = 0;
while(y_in_chunk < 32)
{
z_in_chunk = 0;
while(z_in_chunk < 32)
{
tc_set_block_in_chunk(chunk, x_in_chunk, y_in_chunk, z_in_chunk, block);
++z_in_chunk;
}
++y_in_chunk;
}
++x_in_chunk;
}
return true;
}

View File

@ -1,4 +1,5 @@
#include "state.h"
#include "world.h"
#include <SDL2/SDL.h>
@ -17,6 +18,10 @@ void tc_init_renderer(techneck_s *techneck)
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
);
techneck->renderer.active_camera.position.x = 0.0f;
techneck->renderer.active_camera.position.y = 0.0f;
techneck->renderer.active_camera.position.z = 0.0f;
techneck->renderer.gl_context = SDL_GL_CreateContext(techneck->renderer.window);
gladLoadGLLoader(&SDL_GL_GetProcAddress);
gladLoadGL();
@ -31,6 +36,8 @@ techneck_s tc_init()
{
techneck_s techneck;
tc_init_renderer(&techneck);
techneck.main_world = tc_init_worlds();
techneck.block_registry = tc_init_blocks();
return techneck;
}

View File

@ -9,7 +9,8 @@ techneck_s tc_game_state_g;
mat4x4 projection_matrix;
mat4x4 view_matrix;
float triangle_vertices[108] = {
float triangle_vertices[108] =
{
// Front
-0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
@ -62,9 +63,7 @@ float triangle_vertices[108] = {
0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f
};
tc_vec3_s tc_camera_position = { 0.0f, 0.0f, 0.0f };
@ -124,7 +123,8 @@ void render()
glUniformMatrix4fv(view_uniform_location, 1, GL_FALSE, &view_matrix[0][0]);
// printf("%d\n", view_uniform_location);
render_block(block);
// render_block(block);
tc_draw_world(&tc_game_state_g.main_world);
SDL_GL_SwapWindow(tc_game_state_g.renderer.window);
}
@ -261,7 +261,7 @@ bool update()
int main(int argc, char **argv)
{
tc_game_state_g = tc_init();
tc_game_state_g.block_registry = tc_init_blocks();
tc_new_chunk(&tc_game_state_g.main_world, 0.0f, 0.0f, 0.0f);
block = tc_new_block_at_3f(0.0, 0.0, 0.0);

147
code/source-c/meshize.c Normal file
View File

@ -0,0 +1,147 @@
#include "world.h"
#include <stdlib.h>
#include <string.h>
float tc_block_vertices[108] =
{
// Front
-0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
// Back
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
// Left
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
// Right
0.5f, 0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, -0.5f, -0.5f,
0.5f, 0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
// Top
-0.5f, 0.5f, -0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f,
// Bottom
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, -0.5f
};
uint32_t tc_count_chunk_vertices(tc_chunk_s *chunk)
{
uint32_t num_vertices = 0;
uint32_t x_in_chunk = 0;
uint32_t y_in_chunk = 0;
uint32_t z_in_chunk = 0;
while(x_in_chunk < 32)
{
y_in_chunk = 0;
while(y_in_chunk < 32)
{
z_in_chunk = 0;
while(z_in_chunk < 32)
{
if(chunk->blocks[x_in_chunk][y_in_chunk][z_in_chunk].type_identifier > 0)
{
num_vertices += 36;
}
++z_in_chunk;
}
++y_in_chunk;
}
++x_in_chunk;
}
return num_vertices;
}
void tc_meshize_chunk(tc_chunk_s *chunk)
{
chunk->num_vertices = tc_count_chunk_vertices(chunk);
chunk->vertex_positions = malloc(sizeof(float) * 3 * chunk->num_vertices);
uint32_t vertex_index = 0;
float block_positions[36*3];
uint32_t x_in_chunk = 0;
uint32_t y_in_chunk = 0;
uint32_t z_in_chunk = 0;
while(x_in_chunk < 32)
{
y_in_chunk = 0;
while(y_in_chunk < 32)
{
z_in_chunk = 0;
while(z_in_chunk < 32)
{
if(chunk->blocks[x_in_chunk][y_in_chunk][z_in_chunk].type_identifier > 0)
{
memcpy(
block_positions,
tc_block_vertices,
sizeof(float) * 36 * 3
);
// Move the current block to where it is supposed to be
uint32_t vertex_of_block = 0;
while(vertex_of_block < 36)
{
uint32_t vertex_start = vertex_of_block * 3;
block_positions[vertex_start] +=
x_in_chunk;
block_positions[vertex_start + 1] +=
y_in_chunk;
block_positions[vertex_start + 2] +=
z_in_chunk;
++vertex_of_block;
}
memcpy(
&chunk->vertex_positions[vertex_index],
block_positions,
sizeof(float) * 36 * 3
);
vertex_index += 36;
}
++z_in_chunk;
}
++y_in_chunk;
}
++x_in_chunk;
}
}

View File

@ -8,30 +8,8 @@
#include "shaders.h"
#include "blocks.h"
typedef struct tc_vec3
{
float x;
float y;
float z;
} tc_vec3_s;
typedef struct tc_object
{
uint32_t vbo;
uint32_t vao;
tc_vec3_s position;
tc_vec3_s rotation;
} tc_object_s;
typedef struct tc_block
{
tc_vec3_s position;
tc_object_s drawing;
} tc_block_s;
#include "world.h"
#include "utility.h"
typedef struct tc_camera
{
@ -55,6 +33,7 @@ typedef struct
{
tc_renderer_s renderer;
tc_block_registry_s block_registry;
tc_world_s main_world;
} techneck_s;

23
code/source-c/utility.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef TC_UTILITY_H
#define TC_UTILITY_H
typedef struct tc_vec3
{
float x;
float y;
float z;
} tc_vec3_s;
typedef struct tc_object
{
uint32_t vbo;
uint32_t vao;
tc_vec3_s position;
tc_vec3_s rotation;
} tc_object_s;
#endif

106
code/source-c/world.c Normal file
View File

@ -0,0 +1,106 @@
#include "world.h"
#include "state.h"
#include <linmath.h>
#include <stdlib.h>
tc_worldgen_s tc_default_terrain_generator_g;
void tc_draw_chunk(tc_chunk_s *chunk)
{
mat4x4 model_matrix;
mat4x4_translate(model_matrix, chunk->position.x*32, chunk->position.y*32, chunk->position.z*32);
int model_matrix_uniform_location =
glGetUniformLocation(tc_game_state_g.renderer.draw_shader.program_id, "model_matrix");
glUniformMatrix4fv(model_matrix_uniform_location, 1, GL_FALSE, &model_matrix[0][0]);
// glBindVertexArray(chunk->vao);
glBindBuffer(GL_ARRAY_BUFFER, chunk->vertex_data);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *) 0);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, chunk->num_vertices);
glBindVertexArray(0);
}
void tc_init_world_generators()
{
tc_default_terrain_generator_g.name = "Default Terrain Generator";
tc_default_terrain_generator_g.fn_generate_chunk = &tc_generate_default_terrain_chunk;
}
tc_world_s tc_init_worlds()
{
tc_init_world_generators();
tc_world_s world;
world.chunks_capacity = 256;
world.num_chunks = 0;
world.chunks = calloc(sizeof(tc_chunk_s *), world.chunks_capacity);
world.worldgen = &tc_default_terrain_generator_g;
return world;
}
void tc_set_block_in_chunk(
tc_chunk_s *chunk,
uint32_t x, uint32_t y, uint32_t z,
tc_block_s block
) {
chunk->blocks[x][y][z] = block;
}
void tc_draw_world(tc_world_s *world)
{
uint32_t chunk_index = 0;
while(chunk_index < world->num_chunks)
{
tc_draw_chunk(world->chunks[chunk_index]);
++chunk_index;
}
}
void tc_add_chunk(tc_world_s *world, tc_chunk_s *chunk)
{
if(world->num_chunks >= world->chunks_capacity)
{
world->chunks_capacity *= 2;
world->chunks = realloc(world->chunks, sizeof(tc_chunk_s *) * world->chunks_capacity);
}
world->chunks[world->num_chunks] = chunk;
++world->num_chunks;
}
// Creates & Generates a chunk and provides a pointer to it
tc_chunk_s * tc_new_chunk(tc_world_s *world, float x, float y, float z)
{
tc_chunk_s *chunk = malloc(sizeof(tc_chunk_s));
chunk->position.x = x;
chunk->position.y = y;
chunk->position.z = z;
world->worldgen->fn_generate_chunk(world->worldgen, chunk);
tc_meshize_chunk(chunk);
glGenVertexArrays(1, &chunk->vao);
glBindVertexArray(chunk->vao);
glGenBuffers(1, &chunk->vertex_data);
glBindBuffer(GL_ARRAY_BUFFER, chunk->vertex_data);
glBufferData(GL_ARRAY_BUFFER, chunk->num_vertices * 3 * sizeof(float), chunk->vertex_positions, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *) 0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
tc_add_chunk(world, chunk);
return chunk;
}

70
code/source-c/world.h Normal file
View File

@ -0,0 +1,70 @@
#ifndef TC_WORLD_H
#define TC_WORLD_H
#include <stdbool.h>
#include <stdint.h>
#include "blocks.h"
#include "utility.h"
typedef struct tc_worldgen tc_worldgen_s;
typedef struct tc_block tc_block_s;
typedef struct tc_chunk tc_chunk_s;
typedef struct tc_world tc_world_s;
struct tc_worldgen
{
char *name;
bool (*fn_generate_chunk) (tc_worldgen_s *gen, tc_chunk_s *chunk);
};
struct tc_block
{
uint32_t type_identifier;
tc_vec3_s position;
tc_object_s drawing;
};
struct tc_chunk
{
tc_vec3_s position;
tc_block_s blocks[32][32][32];
uint32_t num_vertices;
float *vertex_positions;
uint32_t vao;
uint32_t vertex_data;
};
struct tc_world
{
uint32_t chunks_capacity;
uint32_t num_chunks;
tc_chunk_s **chunks;
tc_worldgen_s *worldgen;
};
tc_world_s tc_init_worlds ();
void tc_draw_world (tc_world_s *world);
tc_chunk_s * tc_new_chunk (tc_world_s *world, float x, float y, float z);
void tc_set_block_in_chunk(
tc_chunk_s *chunk,
uint32_t x, uint32_t y, uint32_t z,
tc_block_s block
);
void tc_meshize_chunk (tc_chunk_s *chunk);
bool tc_generate_default_terrain_chunk (tc_worldgen_s *gen, tc_chunk_s *chunk);
#endif