made a mess

This commit is contained in:
sam 2024-04-30 23:02:19 +12:00
parent 385896da0f
commit cb3132e6eb
16 changed files with 8410 additions and 52 deletions

View file

@ -1,8 +1,8 @@
BINARY=gearlib
CC=gcc
CFLAGS=-O3 -Iinclude
LDFLAGS=-lglfw
CFLAGS=-O3 -Iinclude -g
LDFLAGS=-lglfw -lm
CFILES=$(shell find -L src -type f -name '*.c')
OBJ=$(CFILES:.c=.o)

BIN
cat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

View file

@ -4,6 +4,7 @@
#include <stdint.h>
uint32_t compile_shader(const char* path, int32_t type);
uint32_t compile_shader_text(const char* name, const char* text, int32_t type);
uint32_t load_shader_program(uint32_t shader, ...);
#endif

194
include/slibs.h Normal file
View file

@ -0,0 +1,194 @@
#ifndef SLIBS_H
#define SLIBS_H
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma region Miscellaneous
#define sl_auto(name, x) typeof(x) name = x
#define sl_new(type, ...) \
({ \
type *ptr = malloc(sizeof(type)); \
*ptr = (type){__VA_ARGS__}; \
ptr; \
})
#define sl_init(type, ...) \
(type) { __VA_ARGS__ }
#define sl_array_len(arr) sizeof(arr) / sizeof(arr[0])
#define sl_fmt_spec(arg) \
_Generic((arg), \
int8_t: "%d", \
int16_t: "%d", \
int32_t: "%d", \
int64_t: "%lld", \
uint8_t: "%u", \
uint16_t: "%u", \
uint32_t: "%lu", \
uint64_t: "%llu", \
double: "%lf", \
float: "%f", \
char: "%c", \
char *: "%s", \
void *: "%p", \
default: "Unknown")
#define sl_stringify(x) #x
#pragma endregion
#pragma region Vector
#define sl_vec(type) \
struct { \
type *data; \
size_t size; \
size_t capacity; \
}
#define sl_vec_grow(vec) \
{ \
(vec).capacity = (vec).capacity * 2 + 1; \
void *ptr = realloc((vec).data, (vec).capacity * sizeof(*(vec).data)); \
if (ptr) \
(vec).data = ptr; \
}
#define sl_vec_push(vec, element) \
{ \
if ((vec).size >= (vec).capacity) \
sl_vec_grow(vec); \
(vec).data[(vec).size++] = (element); \
}
#define sl_vec_shift(vec, element) \
{ \
if ((vec).size >= (vec).capacity) \
sl_vec_grow(vec); \
memmove((vec).data + 1, (vec).data, (vec).size * sizeof(*(vec).data)); \
(vec).data[0] = (element); \
(vec).size++; \
}
#define sl_vec_pop(vec) \
{ \
if ((vec).size > 0) { \
(vec).size--; \
} \
}
#define sl_vec_at(vec, index) ((vec).data[index])
#define sl_vec_size(vec) ((vec).size)
#define sl_vec_capacity(vec) ((vec).capacity)
#define sl_vec_free(vec) free((vec).data)
#define sl_vec_begin(vec) (vec).data
#define sl_vec_end(vec) ((vec).data + (vec).size)
#define sl_vec_it(name, vec) \
sl_auto((name), sl_vec_begin(vec)); \
(name) != sl_vec_end(vec); \
++(name)
#pragma endregion
#pragma region String
typedef sl_vec(char) sl_string;
#define sl_string(c_str) \
({ \
sl_string str = {0}; \
for (size_t i = 0; i < strlen((c_str)); i++) \
sl_vec_push(str, (c_str)[i]); \
str; \
})
#define sl_tostring(val) \
({ \
sl_auto(len, snprintf(NULL, 0, sl_fmt_spec(val), val) + 1); \
sl_auto(buf, (char *)malloc(len)); \
snprintf(buf, len, sl_fmt_spec(val), val); \
sl_auto(str, sl_string(buf)); \
free(buf); \
str; \
})
#define sl_str_free(str) sl_vec_free(str)
#define sl_c_str(str) \
({ \
sl_vec_push((str), '\0'); \
(str).size--; \
(str).data; \
})
#pragma endregion
#pragma region Pointers
#define sl_ptr(type) \
struct { \
type *ptr; \
int ref_count; \
}
#define sl_ptr_make(raw_ptr) \
{ raw_ptr, 1 }
#define sl_ptr_release(smart_ptr) \
({ \
smart_ptr.ref_count--; \
if (smart_ptr.ref_count <= 0) { \
free(smart_ptr.ptr); \
} \
})
#define sl_ptr_get(smart_ptr, raw_ptr_name, scope) \
({ \
assert(smart_ptr.ref_count > 0 && "Smart pointer already released!"); \
sl_auto(raw_ptr_name, smart_ptr.ptr); \
smart_ptr.ref_count++; \
scope; \
sl_ptr_release(smart_ptr); \
});
#define sl_ptr_scope(smart_ptr, scope) \
({ \
scope; \
sl_ptr_release(smart_ptr); \
});
void sl_read_file(const char *filename, sl_string *buffer);
#ifdef SL_IMPLEMENTATION
void sl_read_file(const char *filename, sl_string *buffer) {
FILE *file = fopen(filename, "r");
if (!file) {
fprintf(stderr, "Error: could not open file %s\n", filename);
exit(1);
}
fseek(file, 0, SEEK_END);
size_t file_size = ftell(file);
fseek(file, 0, SEEK_SET);
for (size_t i = 0; i < file_size; i++) {
sl_vec_push(*buffer, fgetc(file));
}
fclose(file);
}
#endif
#pragma endregion
#endif // SLIBS_H

7985
include/stb_image.h Normal file

File diff suppressed because it is too large Load diff

8
include/textures.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef __TEXTURES_H__
#define __TEXTURES_H__
#include <stdint.h>
uint32_t load_texture(const char* path);
#endif

View file

@ -5,4 +5,16 @@
typedef GLFWwindow* Window;
typedef struct {
float x, y;
} float2;
typedef struct {
float x, y, z;
} float3;
typedef struct {
float x, y, z, w;
} float4;
#endif

View file

@ -1,8 +0,0 @@
#version 460 core
in vec4 fragColor;
out vec4 finalColor;
void main() {
finalColor = fragColor;
}

View file

@ -1,10 +0,0 @@
#version 460 core
layout(location = 0) in vec3 aPos;
out vec4 fragColor;
void main() {
gl_Position = vec4(aPos, 1.0);
fragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

View file

@ -1,33 +1,130 @@
#include <init.h>
#include <debugging.h>
#include <shaders.h>
#include <textures.h>
#include <events.h>
#include <types.h>
#include <stdlib.h>
#define MAX_VERTICES 1000
#define ARR_SIZE(arr) sizeof(arr)/sizeof(arr[0])
typedef struct {
int type;
size_t size;
int count;
} VertexAttrib;
typedef struct {
float3 Position;
float4 Color;
float2 TexCoord;
} QuadVertex;
VertexAttrib quad_attribs[] = {
{ .type = GL_FLOAT, .size = sizeof(float), .count = 3 }, // position
{ .type = GL_FLOAT, .size = sizeof(float), .count = 4 }, // color
{ .type = GL_FLOAT, .size = sizeof(float), .count = 2 }, // texcoord
};
uint32_t index_count = 0;
uint32_t vertex_count = 0;
uint32_t texture_shader, quad_vbo, quad_vao;
QuadVertex* quad_vertices;
QuadVertex* current_quad_vertex;
void load_default_shaders() {
texture_shader = load_shader_program(
compile_shader("texture.vert", GL_VERTEX_SHADER),
compile_shader("texture.frag", GL_FRAGMENT_SHADER), 0);
}
float3 quad_vertex_positions[4] = {
{ -0.5f, 0.5f, 0.0f },
{ -0.5f, -0.5f, 0.0f },
{ 0.5f, -0.5f, 0.0f },
{ 0.5f, 0.5f, 0.0f }
};
void draw_indexed(uint32_t vao, int count) {
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
void flush() {
glNamedBufferSubData(quad_vbo, 0, sizeof(QuadVertex) * vertex_count, quad_vertices);
draw_indexed(quad_vao, index_count);
vertex_count = 0;
index_count = 0;
current_quad_vertex = quad_vertices;
}
void draw_texture(uint32_t texture, float4 color) {
if(vertex_count > MAX_VERTICES - 4)
flush();
float2 texcoords[] = {
{ 0.0f, 0.0f },
{ 1.0f, 0.0f },
{ 0.0f, 1.0f },
{ 1.0f, 1.0f }
};
for(int i = 0; i < 4; i++) {
current_quad_vertex->Position = quad_vertex_positions[i];
current_quad_vertex->Color = color;
current_quad_vertex->TexCoord = texcoords[i];
current_quad_vertex++;
vertex_count++;
}
index_count += 6;
}
int main() {
init_gl(4, 6);
GLFWwindow* window = create_window(800, 600, "gearlib");
Window window = create_window(800, 600, "gearlib");
enable_debugging();
load_default_shaders();
float vertices[] = {
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f, // bottom right
0.0f, 0.5f, 0.0f // top
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
quad_vertices = malloc(sizeof(QuadVertex) * MAX_VERTICES);
current_quad_vertex = quad_vertices;
glCreateBuffers(1, &quad_vbo);
glNamedBufferStorage(quad_vbo, sizeof(QuadVertex) * MAX_VERTICES, NULL, GL_DYNAMIC_STORAGE_BIT);
uint32_t quad_indices[] = {
0, 1, 3,
1, 2, 3
};
uint32_t vbo;
glCreateBuffers(1, &vbo);
glNamedBufferStorage(vbo, sizeof(vertices), vertices, GL_DYNAMIC_STORAGE_BIT);
uint32_t quad_ibo;
glCreateBuffers(1, &quad_ibo);
glNamedBufferStorage(quad_ibo, sizeof(quad_indices), quad_indices, GL_DYNAMIC_STORAGE_BIT);
uint32_t vao;
glCreateVertexArrays(1, &vao);
glVertexArrayVertexBuffer(vao, 0, vbo, 0, 3 * sizeof(float));
glEnableVertexArrayAttrib(vao, 0);
glVertexArrayAttribFormat(vao, 0, 3, GL_FLOAT, GL_FALSE, 0);
glVertexArrayAttribBinding(vao, 0, 0);
glCreateVertexArrays(1, &quad_vao);
uint32_t program = load_shader_program(
compile_shader("shader.vert", GL_VERTEX_SHADER),
compile_shader("shader.frag", GL_FRAGMENT_SHADER), 0);
size_t stride = 0;
for(int i = 0; i < ARR_SIZE(quad_attribs); i++) {
VertexAttrib attr = quad_attribs[i];
glEnableVertexArrayAttrib(quad_vao, i);
glVertexArrayAttribFormat(quad_vao, i, attr.count, attr.type, GL_FALSE, stride);
glVertexArrayAttribBinding(quad_vao, i, 0);
stride += attr.size * attr.count;
}
glVertexArrayVertexBuffer(quad_vao, 0, quad_vbo, 0, stride);
glVertexArrayElementBuffer(quad_vao, quad_ibo);
uint32_t cat = load_texture("cat.png");
while (!glfwWindowShouldClose(window)) {
process_input(window);
@ -35,11 +132,15 @@ int main() {
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program);
glBindTextureUnit(0, cat);
glUseProgram(texture_shader);
for(int i = 0; i < 10000; i++) {
draw_texture(cat, (float4){ 1.0f, 1.0f, 1.0f, 1.0f });
}
flush();
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}

View file

@ -1,7 +1,6 @@
#include <shaders.h>
#include <stdarg.h>
#define SL_IMPLEMENTATION
#include <slibs/slibs.h>
#include <slibs.h>
#include <opengl.h>
uint32_t compile_shader(const char* path, int32_t type) {
@ -9,26 +8,33 @@ uint32_t compile_shader(const char* path, int32_t type) {
sl_read_file(path, &source);
const char* source_cstr = sl_c_str(source);
uint32_t shader = glCreateShader(type);
glShaderSource(shader, 1, &source_cstr, NULL);
glCompileShader(shader);
uint32_t id = compile_shader_text(path, source_cstr, type);
sl_str_free(source);
sl_str_free(source);
return id;
}
uint32_t compile_shader_text(const char* name, const char* text, int32_t type) {
uint32_t id = glCreateShader(type);
glShaderSource(id, 1, &text, NULL);
glCompileShader(id);
int success;
char info_log[512];
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
glGetShaderiv(id, GL_COMPILE_STATUS, &success);
if(!success) {
glGetShaderInfoLog(shader, 512, NULL, info_log);
printf("[Shader %d, %s] Failed to compile: %s\n", shader, path, info_log);
glGetShaderInfoLog(id, 512, NULL, info_log);
printf("[Shader %d, %s] Failed to compile: %s\n", id, name, info_log);
exit(-1);
} else {
printf("[Shader %d, %s] Compiled successfully\n", shader, path);
printf("[Shader %d, %s] Compiled successfully\n", id, name);
}
return shader;
return id;
}
uint32_t load_shader_program(uint32_t shader, ...) {
sl_vec(uint32_t) shaders = { 0 };

2
src/slibs.c Normal file
View file

@ -0,0 +1,2 @@
#define SL_IMPLEMENTATION
#include <slibs.h>

3
src/stb_image.c Normal file
View file

@ -0,0 +1,3 @@
#define STBI_FAILURE_USERMSG
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

29
src/textures.c Normal file
View file

@ -0,0 +1,29 @@
#include <textures.h>
#include <stb_image.h>
#include <opengl.h>
#include <stdio.h>
uint32_t load_texture(const char* path) {
stbi_set_flip_vertically_on_load(1);
uint32_t id;
glCreateTextures(GL_TEXTURE_2D, 1, &id);
glTextureParameteri(id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextureParameteri(id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTextureParameteri(id, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTextureParameteri(id, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
int width, height, channels;
unsigned char* pixels = stbi_load(path, &width, &height, &channels, 0);
if(pixels) {
glTextureStorage2D(id, 1, GL_RGBA8, width, height);
glTextureSubImage2D(id, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
printf("[Texture %d, %s] Loaded successfully (%dx%d, %d channels)\n", id, path, width, height, channels);
} else {
printf("[Texture %d, %s] Failed to load image data: %s\n", id, path, stbi_failure_reason());
exit(-1);
}
return id;
}

16
texture.frag Normal file
View file

@ -0,0 +1,16 @@
#version 460 core
layout(location = 0) out vec4 color;
struct VertexOutput {
vec4 Tint;
vec2 TexCoord;
};
layout(location = 0) in VertexOutput Input;
uniform sampler2D texture0;
void main() {
color = texture(texture0, Input.TexCoord) * Input.Tint;
}

19
texture.vert Normal file
View file

@ -0,0 +1,19 @@
#version 460 core
layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec4 a_Tint;
layout(location = 2) in vec2 a_TexCoord;
struct VertexOutput {
vec4 Tint;
vec2 TexCoord;
};
layout(location = 0) out VertexOutput Output;
void main() {
Output.Tint = a_Tint;
Output.TexCoord = a_TexCoord;
gl_Position = vec4(a_Position, 1.0);
}