From 8e5dc406335b55b2ba1a65c617c976b5deef507a Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Mon, 1 Nov 2021 23:07:35 -0500 Subject: [PATCH] working on renderer --- include/gfx.h | 44 +++++++++++++++ src/gfx.c | 110 ++++++++++++++++++++++++++++++++++++++ src/heartbreak_graphics.c | 1 + tests/simp.onyx | 8 +-- 4 files changed, 156 insertions(+), 7 deletions(-) create mode 100644 include/gfx.h create mode 100644 src/gfx.c diff --git a/include/gfx.h b/include/gfx.h new file mode 100644 index 0000000..2e17a04 --- /dev/null +++ b/include/gfx.h @@ -0,0 +1,44 @@ +#ifndef HEARTBREAK_GFX_H +#define HEARTBREAK_GFX_H + + +#include "bh.h" +#include +#include + +typedef struct Shader { + GLint program; + + GLint position_loc; + GLint color_loc; + GLint texture_loc; + + GLint texture_uniform; + GLint view_uniform; + GLint world_uniform; +} Shader; + +Shader gfx_shader_make_from_source(const char* vertex_src, const char* fragment_src); + +typedef struct ImmediateVertex { + f32 x, y; + f32 r, g, b, a; + f32 u, v; +} ImmediateVertex; + +#define VERTEX_DATA_MAX_COUNT 1020 + +typedef struct ImmediateRenderer { + bh_allocator vertex_allocator; + ImmediateVertex* vertex_data; + u32 vertex_count; + + GLint vertex_array; + GLint vertex_buffer; + + Shader simple_shader; +} ImmediateRenderer; + +void gfx_immediate_renderer_init(ImmediateRenderer *ir); + +#endif \ No newline at end of file diff --git a/src/gfx.c b/src/gfx.c new file mode 100644 index 0000000..39c5776 --- /dev/null +++ b/src/gfx.c @@ -0,0 +1,110 @@ +#include "gfx.h" + +static const char* SIMPLE_SHADER_VERTEX = "#version 300 es\n" +"layout(location = 0) in vec2 a_vertex;\n" +"layout(location = 1) in vec4 a_color;\n" +"layout(location = 2) in vec2 a_texture;\n" +"\n" +"uniform mat4 u_view;\n" +"uniform mat4 u_world;\n" +"\n" +"out vec4 v_color;\n" +"out vec2 v_texture;\n" +"\n" +"void main() {\n" +" gl_Position = u_view * u_world * vec4(a_vertex, 0, 1);\n" +" v_color = a_color;\n" +" v_texture = a_texture;\n" +"}"; + +static const char* SIMPLE_SHADER_FRAGMENT = "#version 300 es\n" +"precision mediump float;\n" +"uniform sample2D u_texture;\n" +"\n" +"in vec4 v_color;\n" +"in vec2 v_texture;\n" +"\n" +"out vec4 fragColor;\n" +"\n" +"void main() {\n" +" fragColor = v_color;\n" +"}"; + +static b32 compile_shader(GLuint shader_type, const char *src, GLuint *out_shader) { + GLuint s = glCreateShader(shader_type); + + glShaderSource(s, 1, src, NULL); + glCompileShader(s); + + GLint successful; + glGetShaderiv(s, GL_COMPILE_STATUS, &successful); + if (successful != GL_TRUE) { + GLsizei log_length = 0; + GLchar shader_log[1024]; + glGetShaderInfoLog(s, 1023, &log_length, shader_log); + + bh_printf("Error compiling shader:\n%s\n", shader_log); + return 0; + } + + *out_shader = s; + return 1; +} + +static GLuint link_program(GLuint vertex_shader, GLuint fragment_shader) { + GLuint program = glCreateProgram(); + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + + GLuint successful; + glGetProgramiv(program, GL_LINK_STATUS, &successful); + if (successful != GL_TRUE) { + GLsizei log_length = 0; + GLchar program_log[1024]; + glGetShaderInfoLog(s, 1023, &log_length, program_log); + + bh_printf("Error linking program:\n%s\n", program_log); + return -1; + } + + return program; +} + +Shader gfx_shader_make_from_source(const char *vertex_src, const char *fragment_src) { + GLuint vertex_shader, fragment_shader; + compile_shader(GL_VERTEX_SHADER, vertex_src, &vertex_shader); + compile_shader(GL_FRAGMENT_SHADER, fragment_src, &fragment_shader); + + GLuint program = link_program(vertex_shader, fragment_shader); + + Shader shader; + shader.program = program; + + shader.position_loc = glGetAttribLocation(program, "a_position"); + shader.color_loc = glGetAttribLocation(program, "a_color"); + shader.texture_loc = glGetAttribLocation(program, "a_texture"); + + shader.texture_uniform = glGetUniformLocation(program, "u_texture"); + shader.view_uniform = glGetUniformLocation(program, "u_view"); + shader.world_uniform = glGetUniformLocation(program, "u_world"); + + return shader; +} + +void gfx_immediate_renderer_init(ImmediateRenderer *ir) { + ir->vertex_allocator = bh_heap_allocator(); + ir->vertex_data = bh_alloc(ir->vertex_allocator, sizeof(ImmediateVertex) * VERTEX_DATA_MAX_COUN); + ir->vertex_count = 0; + + ir->simple_shader = gfx_shader_make_from_source(SIMPLE_SHADER_VERTEX, SIMPLE_SHADER_FRAGMENT); + + glGenVertexArrays(1, &ir->vertex_array); + glBindVertexArray(ir->vertex_array); + + glGenBuffers(1, &ir->vertex_buffer); + glBindBuffer(GL_ARRAY_BUFFER, ir->vertex_buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(ImmediateVertex) * VERTEX_DATA_MAX_COUNT, NULL, GL_STREAM_DRAW); + + glBindVertexArray(-1); +} \ No newline at end of file diff --git a/src/heartbreak_graphics.c b/src/heartbreak_graphics.c index afb4ea0..7a71b3c 100644 --- a/src/heartbreak_graphics.c +++ b/src/heartbreak_graphics.c @@ -1,5 +1,6 @@ #define HEARTBREAK_MODULE_NAME graphics #include "heartbreak.h" +#include "gfx.h" static f32 clear_r, clear_g, clear_b, clear_a; diff --git a/tests/simp.onyx b/tests/simp.onyx index c5edf27..1912180 100644 --- a/tests/simp.onyx +++ b/tests/simp.onyx @@ -33,10 +33,4 @@ draw :: () { hb.graphics.rectangle(.Fill, 0, 0, 100, 100); } -main :: (_) => { - printf("Simp test is working!\n"); - - hb.run(.{ init, update, draw }); - - println("Leaving..."); -} \ No newline at end of file +main :: (_) => hb.run(.{ init, update, draw }); \ No newline at end of file -- 2.25.1