whoops
This commit is contained in:
parent
8bca227b73
commit
9c0bd98918
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -1,3 +1,3 @@
|
|||
libgearlib.a
|
||||
obj/
|
||||
test/*.exe
|
||||
*.a
|
||||
obj/
|
||||
examples/*.exe
|
||||
|
|
50
Makefile
50
Makefile
|
@ -1,25 +1,25 @@
|
|||
LIBRARY=libgearlib.a
|
||||
|
||||
CC:=gcc
|
||||
AR=ar
|
||||
CFLAGS=-O3 -Iinclude -g
|
||||
LDFLAGS=-lglfw -lm
|
||||
|
||||
CFILES=$(shell cd src && mingw32-find -L * -type f -name '*.c')
|
||||
OBJDIR=obj
|
||||
OBJ=$(addprefix $(OBJDIR)/, $(CFILES:.c=.o))
|
||||
|
||||
$(LIBRARY): $(OBJ) Makefile
|
||||
$(AR) rcs $(LIBRARY) $(OBJ)
|
||||
|
||||
obj/%.o: src/%.c
|
||||
mkdir -p $(OBJDIR)
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
run: $(LIBRARY)
|
||||
make -C examples test
|
||||
cd examples && ./test
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJ) $(LIBRARY)
|
||||
make -C test clean
|
||||
LIBRARY=libgearlib.a
|
||||
|
||||
CC:=gcc
|
||||
AR=ar
|
||||
CFLAGS=-O3 -Iinclude -g
|
||||
LDFLAGS=-lglfw -lm
|
||||
|
||||
CFILES=$(shell cd src && find -L * -type f -name '*.c')
|
||||
OBJDIR=obj
|
||||
OBJ=$(addprefix $(OBJDIR)/, $(CFILES:.c=.o))
|
||||
|
||||
$(LIBRARY): $(OBJ) Makefile
|
||||
$(AR) rcs $(LIBRARY) $(OBJ)
|
||||
|
||||
obj/%.o: src/%.c
|
||||
mkdir -p $(OBJDIR)
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
run: $(LIBRARY)
|
||||
make -C examples test
|
||||
cd examples && ./test
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJ) $(LIBRARY)
|
||||
make -C examples clean
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
CC=gcc
|
||||
|
||||
CFLAGS=-O3 -I../include
|
||||
LDFLAGS=C:\msys64\ucrt64\lib\libglfw3.a -L ../ -lgdi32 -lgearlib -lm
|
||||
|
||||
CFILES=$(shell mingw32-find -L * -type f -name '*.c')
|
||||
BINARIES=$(CFILES:.c=)
|
||||
|
||||
all: $(BINARIES)
|
||||
|
||||
%: %.c
|
||||
$(CC) $< -o $@ $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -rf $(BINARIES)
|
||||
|
||||
CC=gcc
|
||||
|
||||
CFLAGS = -O3 -I../include
|
||||
LDFLAGS = -L ../ -lglfw -lgearlib -lm
|
||||
|
||||
CFILES=$(shell find -L * -type f -name '*.c')
|
||||
BINARIES=$(CFILES:.c=)
|
||||
|
||||
all: $(BINARIES)
|
||||
|
||||
%: %.c
|
||||
$(CC) $< -o $@ $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -rf $(BINARIES)
|
||||
|
||||
|
|
BIN
examples/test
BIN
examples/test
Binary file not shown.
|
@ -1,35 +1,44 @@
|
|||
#include <gearlib.h>
|
||||
|
||||
int main() {
|
||||
Window window = create_window(800, 600, "test");
|
||||
glfwSwapInterval(0); // fps unlock
|
||||
enable_debugging();
|
||||
setup_textures();
|
||||
|
||||
Camera* camera = create_camera(vec2(0.0f, 0.0f));
|
||||
UniformBuffer* camera_buffer = create_uniform_buffer(sizeof(CameraMatrices));
|
||||
|
||||
Texture cat = load_texture("assets/cat.png");
|
||||
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
process_input(window);
|
||||
update_camera(camera, window);
|
||||
set_uniform_data(camera_buffer, camera->m);
|
||||
|
||||
glClearColor(vec4_spread(BLACK));
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
for(int i = 0; i < 32; i++) {
|
||||
draw_texture(cat, vec2(rand() % 600, rand() % 600), vec2(500.0f, 500.0f), WHITE);
|
||||
}
|
||||
|
||||
flush();
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
#include <gearlib.h>
|
||||
|
||||
int main() {
|
||||
Window window = create_window(800, 600, "test");
|
||||
glfwSwapInterval(0); // fps unlock
|
||||
enable_debugging();
|
||||
setup_textures();
|
||||
|
||||
Camera* camera = create_camera(vec2(0.0f, 0.0f));
|
||||
UniformBuffer* camera_buffer = create_uniform_buffer(sizeof(CameraMatrices));
|
||||
|
||||
Texture cat = load_texture("assets/cat.png");
|
||||
|
||||
double time = glfwGetTime();
|
||||
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
process_input(window);
|
||||
update_camera(camera, window);
|
||||
set_uniform_data(camera_buffer, camera->m);
|
||||
|
||||
glClearColor(vec4_spread(BLACK));
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
for(int i = 0; i < 32; i++) {
|
||||
draw_texture(cat, vec2(rand() % 600, rand() % 600), vec2(500.0f, 500.0f), WHITE);
|
||||
}
|
||||
|
||||
flush();
|
||||
|
||||
double end_time = glfwGetTime();
|
||||
double frame_time = end_time - time;
|
||||
time = end_time;
|
||||
|
||||
double fps = 1.0 / frame_time;
|
||||
printf("frame_time: %lf fps: %lf\n", frame_time, fps);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,32 +1,41 @@
|
|||
#include <gearlib.h>
|
||||
|
||||
int main() {
|
||||
Window window = create_window(800, 600, "textures");
|
||||
glfwSwapInterval(0); // fps unlock
|
||||
setup_textures();
|
||||
|
||||
Camera* camera = create_camera(vec2(0.0f, 0.0f));
|
||||
UniformBuffer* camera_buffer = create_uniform_buffer(sizeof(CameraMatrices));
|
||||
|
||||
Texture cat = load_texture("assets/cat.png");
|
||||
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
process_input(window);
|
||||
update_camera(camera, window);
|
||||
set_uniform_data(camera_buffer, camera->m);
|
||||
|
||||
glClearColor(vec4_spread(BLACK));
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
draw_texture(cat, vec2(250.0f, 250.0f), vec2(500.0f, 500.0f), WHITE);
|
||||
|
||||
flush();
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
#include <gearlib.h>
|
||||
|
||||
int main() {
|
||||
Window window = create_window(800, 600, "textures");
|
||||
glfwSwapInterval(0); // fps unlock
|
||||
setup_textures();
|
||||
|
||||
Camera* camera = create_camera(vec2(0.0f, 0.0f));
|
||||
UniformBuffer* camera_buffer = create_uniform_buffer(sizeof(CameraMatrices));
|
||||
|
||||
Texture cat = load_texture("assets/cat.png");
|
||||
|
||||
double time = glfwGetTime();
|
||||
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
process_input(window);
|
||||
update_camera(camera, window);
|
||||
set_uniform_data(camera_buffer, camera->m);
|
||||
|
||||
glClearColor(vec4_spread(BLUE));
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
draw_texture(cat, vec2(250.0f, 250.0f), vec2(500.0f, 500.0f), WHITE);
|
||||
|
||||
flush();
|
||||
|
||||
double end_time = glfwGetTime();
|
||||
double frame_time = end_time - time;
|
||||
time = end_time;
|
||||
|
||||
double fps = 1.0 / frame_time;
|
||||
printf("frame_time: %lf fps: %lf\n", frame_time, fps);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
|
|
BIN
src/.textures.c.swp
Normal file
BIN
src/.textures.c.swp
Normal file
Binary file not shown.
248
src/textures.c
248
src/textures.c
|
@ -1,119 +1,129 @@
|
|||
#include <textures.h>
|
||||
#include <stb_image.h>
|
||||
#include <opengl.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
RenderBatch* texture_quad_batch = NULL;
|
||||
int max_textures;
|
||||
|
||||
void setup_textures() {
|
||||
texture_quad_batch = create_texture_quad_batch();
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_textures);
|
||||
if(max_textures > 32) max_textures = 32;
|
||||
}
|
||||
|
||||
uint32_t load_texture(const char* path) {
|
||||
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, 4);
|
||||
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;
|
||||
}
|
||||
|
||||
vec2 texture_quad_texcoords[] = {
|
||||
{ 0.0f, 1.0f },
|
||||
{ 0.0f, 0.0f },
|
||||
{ 1.0f, 0.0f },
|
||||
|
||||
{ 0.0f, 1.0f },
|
||||
{ 1.0f, 0.0f },
|
||||
{ 1.0f, 1.0f }
|
||||
};
|
||||
|
||||
void draw_texture(Texture id, vec2 pos, vec2 size, vec4 tint) {
|
||||
mat4 transform = mat4Multiply(
|
||||
mat4Scale(size.x, size.y, 1.0f),
|
||||
mat4Translate(pos.x, pos.y, 0.0f));
|
||||
|
||||
draw_texture_trans(id, transform, tint);
|
||||
}
|
||||
|
||||
void draw_texture_trans(Texture id, mat4 transform, vec4 tint) {
|
||||
assert(texture_quad_batch != NULL && "texture_quad_batch is null, was setup_textures() called?");
|
||||
batch_draw_texture(texture_quad_batch, id, transform, tint);
|
||||
}
|
||||
|
||||
void batch_draw_texture(RenderBatch* batch, Texture texture, mat4 transform, vec4 color) {
|
||||
TextureQuadBatchData* batch_data = batch->data;
|
||||
uint32_t vertex_add = 6;
|
||||
|
||||
if(batch_needs_flush(batch, vertex_add) || batch_data->texture_index >= max_textures)
|
||||
flush_batch(batch);
|
||||
|
||||
uint32_t tex_id = batch_data->texture_index++;
|
||||
glBindTextureUnit(tex_id, texture);
|
||||
|
||||
for(int i = 0; i < vertex_add; i++) {
|
||||
TextureQuadVertex* vertex = batch->vertex_ptr;
|
||||
|
||||
vertex->Position = vec3Transform(quad_vertex_positions[i], transform);
|
||||
vertex->Tint = color;
|
||||
vertex->TexCoord = texture_quad_texcoords[i];
|
||||
vertex->TexID = tex_id;
|
||||
|
||||
batch->vertex_ptr += batch->vertex_size;
|
||||
batch->vertex_count++;
|
||||
}
|
||||
}
|
||||
|
||||
void texture_flush_callback(RenderBatch* batch) {
|
||||
TextureQuadBatchData* data = batch->data;
|
||||
data->texture_index = 0;
|
||||
}
|
||||
|
||||
RenderBatch* create_texture_quad_batch() {
|
||||
RenderBatch* texture_quad_batch = create_batch(sizeof(TextureQuadVertex), MAX_VERTICES);
|
||||
texture_quad_batch->shader = load_shader_program(
|
||||
compile_shader("assets/texture.vert", GL_VERTEX_SHADER),
|
||||
compile_shader("assets/texture.frag", GL_FRAGMENT_SHADER), 0);
|
||||
|
||||
texture_quad_batch->data = calloc(sizeof(TextureQuadBatchData), 1);
|
||||
texture_quad_batch->flush_callback = &texture_flush_callback;
|
||||
|
||||
batch_add_attrib(texture_quad_batch, (VertexAttrib){
|
||||
.type = GL_FLOAT, .size = sizeof(float), .count = 3
|
||||
}); // pos
|
||||
|
||||
batch_add_attrib(texture_quad_batch, (VertexAttrib){
|
||||
.type = GL_FLOAT, .size = sizeof(float), .count = 4
|
||||
}); // color
|
||||
|
||||
batch_add_attrib(texture_quad_batch, (VertexAttrib){
|
||||
.type = GL_FLOAT, .size = sizeof(float), .count = 2
|
||||
}); // texcoord
|
||||
|
||||
batch_add_attrib(texture_quad_batch, (VertexAttrib){
|
||||
.type = GL_FLOAT, .size = sizeof(float), .count = 1
|
||||
}); // texid
|
||||
|
||||
batch_bind_attribs(texture_quad_batch);
|
||||
|
||||
return texture_quad_batch;
|
||||
}
|
||||
#include <textures.h>
|
||||
#include <stb_image.h>
|
||||
#include <opengl.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
RenderBatch* texture_quad_batch = NULL;
|
||||
int max_textures;
|
||||
|
||||
void setup_textures() {
|
||||
texture_quad_batch = create_texture_quad_batch();
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_textures);
|
||||
if(max_textures > 32) max_textures = 32;
|
||||
}
|
||||
|
||||
uint32_t load_texture(const char* path) {
|
||||
uint32_t id;
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &id);
|
||||
|
||||
uint8_t default_texture[] = {
|
||||
0, 0, 0, 255, 255, 0, 255, 255,
|
||||
255, 0, 255, 255, 0, 0, 0, 255 };
|
||||
|
||||
int width = 2, height = 2, channels;
|
||||
uint8_t* pixels = stbi_load(path, &width, &height, &channels, 4);
|
||||
if(pixels) {
|
||||
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);
|
||||
|
||||
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 {
|
||||
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_NEAREST);
|
||||
glTextureParameteri(id, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glTextureStorage2D(id, 1, GL_RGBA8, width, height);
|
||||
glTextureSubImage2D(id, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, default_texture);
|
||||
printf("[Texture %d, %s] Failed to load image data: %s\n", id, path, stbi_failure_reason());
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
vec2 texture_quad_texcoords[] = {
|
||||
{ 0.0f, 1.0f },
|
||||
{ 0.0f, 0.0f },
|
||||
{ 1.0f, 0.0f },
|
||||
|
||||
{ 0.0f, 1.0f },
|
||||
{ 1.0f, 0.0f },
|
||||
{ 1.0f, 1.0f }
|
||||
};
|
||||
|
||||
void draw_texture(Texture id, vec2 pos, vec2 size, vec4 tint) {
|
||||
mat4 transform = mat4Multiply(
|
||||
mat4Scale(size.x, size.y, 1.0f),
|
||||
mat4Translate(pos.x, pos.y, 0.0f));
|
||||
|
||||
draw_texture_trans(id, transform, tint);
|
||||
}
|
||||
|
||||
void draw_texture_trans(Texture id, mat4 transform, vec4 tint) {
|
||||
assert(texture_quad_batch != NULL && "texture_quad_batch is null, was setup_textures() called?");
|
||||
batch_draw_texture(texture_quad_batch, id, transform, tint);
|
||||
}
|
||||
|
||||
void batch_draw_texture(RenderBatch* batch, Texture texture, mat4 transform, vec4 color) {
|
||||
TextureQuadBatchData* batch_data = batch->data;
|
||||
uint32_t vertex_add = 6;
|
||||
|
||||
if(batch_needs_flush(batch, vertex_add) || batch_data->texture_index >= max_textures)
|
||||
flush_batch(batch);
|
||||
|
||||
uint32_t tex_id = batch_data->texture_index++;
|
||||
glBindTextureUnit(tex_id, texture);
|
||||
|
||||
for(int i = 0; i < vertex_add; i++) {
|
||||
TextureQuadVertex* vertex = batch->vertex_ptr;
|
||||
|
||||
vertex->Position = vec3Transform(quad_vertex_positions[i], transform);
|
||||
vertex->Tint = color;
|
||||
vertex->TexCoord = texture_quad_texcoords[i];
|
||||
vertex->TexID = tex_id;
|
||||
|
||||
batch->vertex_ptr += batch->vertex_size;
|
||||
batch->vertex_count++;
|
||||
}
|
||||
}
|
||||
|
||||
void texture_flush_callback(RenderBatch* batch) {
|
||||
TextureQuadBatchData* data = batch->data;
|
||||
data->texture_index = 0;
|
||||
}
|
||||
|
||||
RenderBatch* create_texture_quad_batch() {
|
||||
RenderBatch* texture_quad_batch = create_batch(sizeof(TextureQuadVertex), MAX_VERTICES);
|
||||
texture_quad_batch->shader = load_shader_program(
|
||||
compile_shader("assets/texture.vert", GL_VERTEX_SHADER),
|
||||
compile_shader("assets/texture.frag", GL_FRAGMENT_SHADER), 0);
|
||||
|
||||
texture_quad_batch->data = calloc(sizeof(TextureQuadBatchData), 1);
|
||||
texture_quad_batch->flush_callback = &texture_flush_callback;
|
||||
|
||||
batch_add_attrib(texture_quad_batch, (VertexAttrib){
|
||||
.type = GL_FLOAT, .size = sizeof(float), .count = 3
|
||||
}); // pos
|
||||
|
||||
batch_add_attrib(texture_quad_batch, (VertexAttrib){
|
||||
.type = GL_FLOAT, .size = sizeof(float), .count = 4
|
||||
}); // color
|
||||
|
||||
batch_add_attrib(texture_quad_batch, (VertexAttrib){
|
||||
.type = GL_FLOAT, .size = sizeof(float), .count = 2
|
||||
}); // texcoord
|
||||
|
||||
batch_add_attrib(texture_quad_batch, (VertexAttrib){
|
||||
.type = GL_FLOAT, .size = sizeof(float), .count = 1
|
||||
}); // texid
|
||||
|
||||
batch_bind_attribs(texture_quad_batch);
|
||||
|
||||
return texture_quad_batch;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue