-
Notifications
You must be signed in to change notification settings - Fork 108
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test/renderer: add a basic triangle "hello world" example
- Loading branch information
Showing
4 changed files
with
196 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,5 @@ if opt_tests.disabled() | |
endif | ||
|
||
test_incdir = include_directories('.') | ||
|
||
subdir('renderer') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |