made a mess
This commit is contained in:
parent
385896da0f
commit
cb3132e6eb
4
Makefile
4
Makefile
|
@ -1,8 +1,8 @@
|
||||||
BINARY=gearlib
|
BINARY=gearlib
|
||||||
|
|
||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS=-O3 -Iinclude
|
CFLAGS=-O3 -Iinclude -g
|
||||||
LDFLAGS=-lglfw
|
LDFLAGS=-lglfw -lm
|
||||||
|
|
||||||
CFILES=$(shell find -L src -type f -name '*.c')
|
CFILES=$(shell find -L src -type f -name '*.c')
|
||||||
OBJ=$(CFILES:.c=.o)
|
OBJ=$(CFILES:.c=.o)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
uint32_t compile_shader(const char* path, int32_t type);
|
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, ...);
|
uint32_t load_shader_program(uint32_t shader, ...);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
194
include/slibs.h
Normal file
194
include/slibs.h
Normal 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
7985
include/stb_image.h
Normal file
File diff suppressed because it is too large
Load diff
8
include/textures.h
Normal file
8
include/textures.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef __TEXTURES_H__
|
||||||
|
#define __TEXTURES_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
uint32_t load_texture(const char* path);
|
||||||
|
|
||||||
|
#endif
|
|
@ -5,4 +5,16 @@
|
||||||
|
|
||||||
typedef GLFWwindow* Window;
|
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
|
#endif
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
#version 460 core
|
|
||||||
|
|
||||||
in vec4 fragColor;
|
|
||||||
out vec4 finalColor;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
finalColor = fragColor;
|
|
||||||
}
|
|
10
shader.vert
10
shader.vert
|
@ -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);
|
|
||||||
}
|
|
143
src/main.c
143
src/main.c
|
@ -1,33 +1,130 @@
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <debugging.h>
|
#include <debugging.h>
|
||||||
#include <shaders.h>
|
#include <shaders.h>
|
||||||
|
#include <textures.h>
|
||||||
#include <events.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() {
|
int main() {
|
||||||
init_gl(4, 6);
|
init_gl(4, 6);
|
||||||
GLFWwindow* window = create_window(800, 600, "gearlib");
|
Window window = create_window(800, 600, "gearlib");
|
||||||
enable_debugging();
|
enable_debugging();
|
||||||
|
load_default_shaders();
|
||||||
|
|
||||||
float vertices[] = {
|
glEnable(GL_BLEND);
|
||||||
-0.5f, -0.5f, 0.0f, // bottom left
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
0.5f, -0.5f, 0.0f, // bottom right
|
|
||||||
0.0f, 0.5f, 0.0f // top
|
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;
|
uint32_t quad_ibo;
|
||||||
glCreateBuffers(1, &vbo);
|
glCreateBuffers(1, &quad_ibo);
|
||||||
glNamedBufferStorage(vbo, sizeof(vertices), vertices, GL_DYNAMIC_STORAGE_BIT);
|
glNamedBufferStorage(quad_ibo, sizeof(quad_indices), quad_indices, GL_DYNAMIC_STORAGE_BIT);
|
||||||
|
|
||||||
uint32_t vao;
|
glCreateVertexArrays(1, &quad_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);
|
|
||||||
|
|
||||||
uint32_t program = load_shader_program(
|
size_t stride = 0;
|
||||||
compile_shader("shader.vert", GL_VERTEX_SHADER),
|
for(int i = 0; i < ARR_SIZE(quad_attribs); i++) {
|
||||||
compile_shader("shader.frag", GL_FRAGMENT_SHADER), 0);
|
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)) {
|
while (!glfwWindowShouldClose(window)) {
|
||||||
process_input(window);
|
process_input(window);
|
||||||
|
@ -35,11 +132,15 @@ int main() {
|
||||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
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);
|
glfwSwapBuffers(window);
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include <shaders.h>
|
#include <shaders.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#define SL_IMPLEMENTATION
|
#include <slibs.h>
|
||||||
#include <slibs/slibs.h>
|
|
||||||
#include <opengl.h>
|
#include <opengl.h>
|
||||||
|
|
||||||
uint32_t compile_shader(const char* path, int32_t type) {
|
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);
|
sl_read_file(path, &source);
|
||||||
const char* source_cstr = sl_c_str(source);
|
const char* source_cstr = sl_c_str(source);
|
||||||
|
|
||||||
uint32_t shader = glCreateShader(type);
|
uint32_t id = compile_shader_text(path, source_cstr, type);
|
||||||
glShaderSource(shader, 1, &source_cstr, NULL);
|
|
||||||
glCompileShader(shader);
|
|
||||||
|
|
||||||
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;
|
int success;
|
||||||
char info_log[512];
|
char info_log[512];
|
||||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
glGetShaderiv(id, GL_COMPILE_STATUS, &success);
|
||||||
if(!success) {
|
if(!success) {
|
||||||
glGetShaderInfoLog(shader, 512, NULL, info_log);
|
glGetShaderInfoLog(id, 512, NULL, info_log);
|
||||||
printf("[Shader %d, %s] Failed to compile: %s\n", shader, path, info_log);
|
printf("[Shader %d, %s] Failed to compile: %s\n", id, name, info_log);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
} else {
|
} 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, ...) {
|
uint32_t load_shader_program(uint32_t shader, ...) {
|
||||||
sl_vec(uint32_t) shaders = { 0 };
|
sl_vec(uint32_t) shaders = { 0 };
|
||||||
|
|
||||||
|
|
2
src/slibs.c
Normal file
2
src/slibs.c
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#define SL_IMPLEMENTATION
|
||||||
|
#include <slibs.h>
|
3
src/stb_image.c
Normal file
3
src/stb_image.c
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#define STBI_FAILURE_USERMSG
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include <stb_image.h>
|
29
src/textures.c
Normal file
29
src/textures.c
Normal 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
16
texture.frag
Normal 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
19
texture.vert
Normal 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);
|
||||||
|
}
|
Loading…
Reference in a new issue