Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
render=src/engine/render/render.c src/engine/render/render_init.c src/engine/render/render_util.c
io=src/engine/io/io.c
config=src/engine/config/config.c
input=src/engine/input/input.c
time=src/engine/time/time.c
physics=src/engine/physics/physics.c
array_list=src/engine/array_list/array_list.c
entity=src/engine/entity/entity.c
files=src/glad.c src/main.c src/engine/global.c $(render) $(io) $(config) $(input) $(time) $(physics) $(array_list) $(entity)

libs=-lm `sdl2-config --cflags --libs`

#CL /Zi /I W:/include $(files) /link $(libs) /OUT:mygame.exe

build:
gcc -g3 $(files) $(libs) -o mygame.out
Binary file added assets/player.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions shaders/batch_quad.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#version 330 core
out vec4 o_color;

in vec4 v_color;
in vec2 v_uvs;

uniform sampler2D texture_slot;

void main() {
o_color = texture(texture_slot, v_uvs) * v_color;
}
15 changes: 15 additions & 0 deletions shaders/batch_quad.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#version 330 core
layout (location = 0) in vec2 a_pos;
layout (location = 1) in vec2 a_uvs;
layout (location = 2) in vec4 a_color;

out vec4 v_color;
out vec2 v_uvs;

uniform mat4 projection;

void main() {
v_color = a_color;
v_uvs = a_uvs;
gl_Position = projection * vec4(a_pos, 0.0, 1.0);
}
2 changes: 0 additions & 2 deletions src/engine/entity/entity.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ void entity_init(void) {
}

usize entity_create(vec2 position, vec2 size, vec2 velocity, u8 collision_layer, u8 collision_mask, On_Hit on_hit, On_Hit_Static on_hit_static) {
vec2_scale(size, size, 0.5);

Entity entity = {
.body_id = physics_body_create(position, size, velocity, collision_layer, collision_mask, on_hit, on_hit_static),
.is_active = true,
Expand Down
1 change: 0 additions & 1 deletion src/engine/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include "time.h"

typedef struct global {
Render_State render;
Config_State config;
Input_State input;
Time_State time;
Expand Down
4 changes: 2 additions & 2 deletions src/engine/physics/physics.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ void physics_init(void) {
state.body_list = array_list_create(sizeof(Body), 0);
state.static_body_list = array_list_create(sizeof(Static_Body), 0);

state.gravity = -200;
state.terminal_velocity = -10000;
state.gravity = -100;
state.terminal_velocity = -7000;

tick_rate = 1.f / iterations;
}
Expand Down
28 changes: 23 additions & 5 deletions src/engine/render.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,35 @@

#include "types.h"

typedef struct render_state {
SDL_Window *window;
typedef struct batch_vertex {
vec2 position;
vec2 uvs;
vec4 color;
} Batch_Vertex;

typedef struct sprite_sheet {
f32 width;
f32 height;
} Render_State;
f32 cell_width;
f32 cell_height;
u32 texture_id;
} Sprite_Sheet;

#define MAX_BATCH_QUADS 10000
#define MAX_BATCH_VERTICES 40000
#define MAX_BATCH_ELEMENTS 60000

void render_init(void);
SDL_Window *render_init(void);
void render_begin(void);
void render_end(void);
void render_end(SDL_Window *window, u32 batch_texture_id);
void render_quad(vec2 pos, vec2 size, vec4 color);
void render_quad_line(vec2 pos, vec2 size, vec4 color);
void render_line_segment(vec2 start, vec2 end, vec4 color);
void render_aabb(f32 *aabb, vec4 color);
f32 render_get_scale();

void render_sprite_sheet_init(Sprite_Sheet *sprite_sheet, const char *path, f32 cell_width, f32 cell_height);
void render_sprite_sheet_frame(Sprite_Sheet *sprite_sheet, f32 row, f32 column, vec2 position);

// Temporary!
void append_quad(vec2 position, vec2 size, vec4 texture_coordinates, vec4 color);
174 changes: 150 additions & 24 deletions src/engine/render/render.c
Original file line number Diff line number Diff line change
@@ -1,56 +1,135 @@
#include <glad/glad.h>

#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

#include "../global.h"
#include "../render.h"
#include "../array_list.h"
#include "../util.h"
#include "render_internal.h"

static Render_State_Internal state = {0};

void render_init(void) {
global.render.width = 1920;
global.render.height = 1080;
global.render.window = render_init_window(global.render.width, global.render.height);

render_init_quad(&state.vao_quad, &state.vbo_quad, &state.ebo_quad);
render_init_line(&state.vao_line, &state.vbo_line);
render_init_shaders(&state);
render_init_color_texture(&state.texture_color);
static f32 window_width = 1920;
static f32 window_height = 1080;
static f32 render_width = 640;
static f32 render_height = 360;
static f32 scale = 3;

static u32 vao_quad;
static u32 vbo_quad;
static u32 ebo_quad;
static u32 vao_line;
static u32 vbo_line;
static u32 shader_default;
static u32 texture_color;
static u32 vao_batch;
static u32 vbo_batch;
static u32 ebo_batch;
static u32 shader_batch;
static Array_List *list_batch;

SDL_Window *render_init(void) {
SDL_Window *window = render_init_window(window_width, window_height);

render_init_quad(&vao_quad, &vbo_quad, &ebo_quad);
render_init_batch_quads(&vao_batch, &vbo_batch, &ebo_batch);
render_init_line(&vao_line, &vbo_line);
render_init_shaders(&shader_default, &shader_batch, render_width, render_height);
render_init_color_texture(&texture_color);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

list_batch = array_list_create(sizeof(Batch_Vertex), 8);

stbi_set_flip_vertically_on_load(1);

return window;
}

void render_begin(void) {
glClearColor(0.08, 0.1, 0.1, 1);
glClear(GL_COLOR_BUFFER_BIT);

list_batch->len = 0;
}

static void render_batch(Batch_Vertex *vertices, usize count, u32 texture_id) {
glBindBuffer(GL_ARRAY_BUFFER, vbo_batch);
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(Batch_Vertex), vertices);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_id);

glUseProgram(shader_batch);
glBindVertexArray(vao_batch);

// count >> 2 is the same as count / 4.
// 4 vertices per quad.
// 6 indices per quad (two tris).
glDrawElements(GL_TRIANGLES, (count >> 2) * 6, GL_UNSIGNED_INT, NULL);
}

void render_end(void) {
SDL_GL_SwapWindow(global.render.window);
static void append_quad(vec2 position, vec2 size, vec4 texture_coordinates, vec4 color) {
vec4 uvs = {0, 0, 1, 1};

if (texture_coordinates != NULL) {
memcpy(uvs, texture_coordinates, sizeof(vec4));
}

array_list_append(list_batch, &(Batch_Vertex){
.position = { position[0], position[1] },
.uvs = { uvs[0], uvs[1] },
.color = { color[0], color[1], color[2], color[3] },
});

array_list_append(list_batch, &(Batch_Vertex){
.position = { position[0] + size[0], position[1] },
.uvs = { uvs[2], uvs[1] },
.color = { color[0], color[1], color[2], color[3] },
});

array_list_append(list_batch, &(Batch_Vertex){
.position = { position[0] + size[0], position[1] + size[1] },
.uvs = { uvs[2], uvs[3] },
.color = { color[0], color[1], color[2], color[3] },
});

array_list_append(list_batch, &(Batch_Vertex){
.position = { position[0], position[1] + size[1] },
.uvs = { uvs[0], uvs[3] },
.color = { color[0], color[1], color[2], color[3] },
});
}

void render_end(SDL_Window *window, u32 batch_texture_id) {
render_batch(list_batch->items, list_batch->len, batch_texture_id);

SDL_GL_SwapWindow(window);
}

void render_quad(vec2 pos, vec2 size, vec4 color) {
glUseProgram(state.shader_default);
glUseProgram(shader_default);

mat4x4 model;
mat4x4_identity(model);

mat4x4_translate(model, pos[0], pos[1], 0);
mat4x4_scale_aniso(model, model, size[0], size[1], 1);

glUniformMatrix4fv(glGetUniformLocation(state.shader_default, "model"), 1, GL_FALSE, &model[0][0]);
glUniform4fv(glad_glGetUniformLocation(state.shader_default, "color"), 1, color);
glUniformMatrix4fv(glGetUniformLocation(shader_default, "model"), 1, GL_FALSE, &model[0][0]);
glUniform4fv(glad_glGetUniformLocation(shader_default, "color"), 1, color);

glBindVertexArray(state.vao_quad);
glBindVertexArray(vao_quad);

glBindTexture(GL_TEXTURE_2D, state.texture_color);
glBindTexture(GL_TEXTURE_2D, texture_color);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);

glBindVertexArray(0);
}

void render_line_segment(vec2 start, vec2 end, vec4 color) {
glUseProgram(state.shader_default);
glUseProgram(shader_default);
glLineWidth(3);

f32 x = end[0] - start[0];
Expand All @@ -60,13 +139,13 @@ void render_line_segment(vec2 start, vec2 end, vec4 color) {
mat4x4 model;
mat4x4_translate(model, start[0], start[1], 0);

glUniformMatrix4fv(glGetUniformLocation(state.shader_default, "model"), 1, GL_FALSE, &model[0][0]);
glUniform4fv(glGetUniformLocation(state.shader_default, "color"), 1, color);
glUniformMatrix4fv(glGetUniformLocation(shader_default, "model"), 1, GL_FALSE, &model[0][0]);
glUniform4fv(glGetUniformLocation(shader_default, "color"), 1, color);

glBindTexture(GL_TEXTURE_2D, state.texture_color);
glBindVertexArray(state.vao_line);
glBindTexture(GL_TEXTURE_2D, texture_color);
glBindVertexArray(vao_line);

glBindBuffer(GL_ARRAY_BUFFER, state.vbo_line);
glBindBuffer(GL_ARRAY_BUFFER, vbo_line);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(line), line);
glDrawArrays(GL_LINES, 0, 2);

Expand All @@ -93,3 +172,50 @@ void render_aabb(f32 *aabb, vec4 color) {
render_quad_line(&aabb[0], size, color);
}

static void calculate_sprite_texture_coordinates(vec4 result, f32 row, f32 column, f32 texture_width, f32 texture_height, f32 cell_width, f32 cell_height) {
f32 w = 1.0 / (texture_width / cell_width);
f32 h = 1.0 / (texture_height / cell_height);
f32 x = column * w;
f32 y = row * h;
result[0] = x;
result[1] = y;
result[2] = x + w;
result[3] = y + h;
}

void render_sprite_sheet_init(Sprite_Sheet *sprite_sheet, const char *path, f32 cell_width, f32 cell_height) {
glGenTextures(1, &sprite_sheet->texture_id);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, sprite_sheet->texture_id);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

int width, height, channel_count;
u8 *image_data = stbi_load(path, &width, &height, &channel_count, 0);
if (!image_data) {
ERROR_EXIT("Failed to load image: %s\n", path);
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
stbi_image_free(image_data);

sprite_sheet->width = (f32)width;
sprite_sheet->height = (f32)height;
sprite_sheet->cell_width = cell_width;
sprite_sheet->cell_height = cell_height;
}

void render_sprite_sheet_frame(Sprite_Sheet *sprite_sheet, f32 row, f32 column, vec2 position) {
vec4 uvs;
calculate_sprite_texture_coordinates(uvs, row, column, sprite_sheet->width, sprite_sheet->height, sprite_sheet->cell_width, sprite_sheet->cell_height);

vec2 size = {sprite_sheet->cell_width, sprite_sheet->cell_height};
vec2 bottom_left = {position[0] - size[0] * 0.5, position[1] - size[1] * 0.5};
append_quad(bottom_left, size, uvs, (vec4){1, 1, 1, 1});
}

f32 render_get_scale() {
return scale;
}
Loading