Skip to content

Commit

Permalink
test/renderer: add a basic triangle "hello world" example
Browse files Browse the repository at this point in the history
  • Loading branch information
Akaricchi committed May 13, 2024
1 parent 49cf3e1 commit 861935d
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 0 deletions.
2 changes: 2 additions & 0 deletions test/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ if opt_tests.disabled()
endif

test_incdir = include_directories('.')

subdir('renderer')
13 changes: 13 additions & 0 deletions test/renderer/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

tests = [
'triangle',
]

foreach test : tests
executable(
test, '@0@.c'.format(test),
dependencies : libtaisei_dep,
include_directories : test_incdir,
install : false,
)
endforeach
96 changes: 96 additions & 0 deletions test/renderer/test_renderer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@

#include "taisei.h"

#include "renderer/api.h"
#include "events.h"
#include "log.h"
#include "util/compat.h"
#include "video.h"
#include "config.h"

#include <locale.h>

static void test_init_log(void) {
log_init(LOG_ALL);
log_add_output(LOG_ALL, SDL_RWFromFP(stderr, false), log_formatter_console);
}

static void test_init_sdl(void) {
mem_install_sdl_callbacks();

if(SDL_Init(SDL_INIT_EVENTS) < 0) {
log_fatal("SDL_Init() failed: %s", SDL_GetError());
}

events_init();
}

static void test_init_basic(void) {
setlocale(LC_ALL, "C");
test_init_log();
test_init_sdl();
}

static ShaderObject *test_renderer_load_glsl(ShaderStage stage, const char *src) {
// TODO: This is mostly copypasted from resource/shader_object; add a generic API for this

ShaderSource s = {
.content = (char*)src,
.content_size = strlen(src),
.stage = stage,
.lang = {
.lang = SHLANG_GLSL,
.glsl.version = { 330, GLSL_PROFILE_CORE }
},
};

ShaderLangInfo altlang = { SHLANG_INVALID };

if(!r_shader_language_supported(&s.lang, &altlang)) {
if(altlang.lang == SHLANG_INVALID) {
log_fatal("Shading language not supported by backend");
}

log_warn("Shading language not supported by backend, attempting to translate");
assert(r_shader_language_supported(&altlang, NULL));

spirv_init_compiler();

ShaderSource newsrc;
bool result = spirv_transpile(&s, &newsrc, &(SPIRVTranspileOptions) {
.lang = &altlang,
.optimization_level = SPIRV_OPTIMIZE_NONE,
.filename = "<embedded>",
});

if(!result) {
log_fatal("Shader translation failed");
}

s = newsrc;
}

ShaderObject *obj = r_shader_object_compile(&s);

if(!obj) {
log_fatal("Failed to compile shader");
}

if(s.content != src) {
shader_free_source(&s);
}

return obj;
}

static void test_init_renderer(void) {
test_init_basic();

config_set_int(CONFIG_VSYNC, 1);
config_set_int(CONFIG_VID_RESIZABLE, 1);

video_init(&(VideoInitParams) {
.width = 800,
.height = 600,
});
}
85 changes: 85 additions & 0 deletions test/renderer/triangle.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@

#include "taisei.h"

#include "test_renderer.h"
#include "resource/model.h"
#include "global.h"

typedef struct Vertex2D {
vec2 pos;
Color color;
} Vertex2D;

int main(int argc, char **argv) {
test_init_renderer();

const char *vert_shader_src =
"#version 330\n"
"layout(location = 0) in vec2 a_position;\n"
"layout(location = 1) in vec4 a_color;\n"
"out vec4 v_color;\n"
"void main(void) {\n"
" gl_Position = vec4(a_position, 0, 1);\n"
" v_color = a_color;\n"
"}\n";

const char *frag_shader_src =
"#version 330\n"
"in vec4 v_color;\n"
"layout(location = 0) out vec4 o_color;\n"
"void main(void) {\n"
" o_color = v_color;\n"
"}\n";

ShaderObject *vert_obj = test_renderer_load_glsl(SHADER_STAGE_VERTEX, vert_shader_src);
ShaderObject *frag_obj = test_renderer_load_glsl(SHADER_STAGE_FRAGMENT, frag_shader_src);
ShaderProgram *prog = r_shader_program_link(2, (ShaderObject*[]) { vert_obj, frag_obj });
r_shader_object_destroy(vert_obj);
r_shader_object_destroy(frag_obj);

VertexAttribSpec va_spec[] = {
{ 2, VA_FLOAT, VA_CONVERT_FLOAT },
{ 4, VA_FLOAT, VA_CONVERT_FLOAT },
};

VertexAttribFormat va_format[ARRAY_SIZE(va_spec)];
r_vertex_attrib_format_interleaved(ARRAY_SIZE(va_spec), va_spec, va_format, 0);

Vertex2D vertices[] = {
{ { -1.0f, -1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } },
{ { 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },
{ { 1.0f, -1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } },
};

VertexBuffer *vert_buf = r_vertex_buffer_create(sizeof(vertices), vertices);
r_vertex_buffer_set_debug_label(vert_buf, "Triangle vertex buffer");

VertexArray *vert_array = r_vertex_array_create();
r_vertex_array_set_debug_label(vert_array, "Triangle vertex array");
r_vertex_array_layout(vert_array, ARRAY_SIZE(va_format), va_format);
r_vertex_array_attach_vertex_buffer(vert_array, vert_buf, 0);

Model triangle = {
.primitive = PRIM_TRIANGLES,
.vertex_array = vert_array,
.num_vertices = ARRAY_SIZE(vertices),
.offset = 0,
};

r_shader_ptr(prog);

while(!taisei_quit_requested()) {
r_clear(BUFFER_COLOR, RGB(0, 0, 0), 1);
r_draw_model_ptr(&triangle, 1, 0);
events_poll(NULL, 0);
video_swap_buffers();
}

r_vertex_buffer_destroy(vert_buf);
r_vertex_array_destroy(vert_array);

// FIXME doesn't work when "default" shader is not loaded
// r_shader_program_destroy(prog);

return 0;
}

0 comments on commit 861935d

Please sign in to comment.