test/renderer/texture: add a basic textured quad test
This commit is contained in:
parent
98888a461b
commit
023a6b31e6
3 changed files with 162 additions and 0 deletions
|
@ -1,6 +1,7 @@
|
|||
|
||||
tests = [
|
||||
'triangle',
|
||||
'texture',
|
||||
]
|
||||
|
||||
foreach test : tests
|
||||
|
|
161
test/renderer/texture.c
Normal file
161
test/renderer/texture.c
Normal file
|
@ -0,0 +1,161 @@
|
|||
|
||||
#include "taisei.h"
|
||||
|
||||
#include "test_renderer.h"
|
||||
#include "global.h"
|
||||
|
||||
typedef struct Vertex2D {
|
||||
vec2 pos;
|
||||
vec2 uv;
|
||||
vec4 color;
|
||||
} Vertex2D;
|
||||
|
||||
static Texture *load_texture(const char *path) {
|
||||
auto istream = SDL_RWFromFile(path, "rb");
|
||||
|
||||
if(!istream) {
|
||||
log_sdl_error(LOG_FATAL, "SDL_IOFromFile");
|
||||
}
|
||||
|
||||
Pixmap px = {};
|
||||
PixmapFormat fmt = PIXMAP_FORMAT_RGBA8;
|
||||
PixmapOrigin origin = PIXMAP_ORIGIN_TOPLEFT;
|
||||
|
||||
if(r_features() & RFEAT_TEXTURE_BOTTOMLEFT_ORIGIN) {
|
||||
origin = PIXMAP_ORIGIN_BOTTOMLEFT;
|
||||
}
|
||||
|
||||
if(!pixmap_load_stream(istream, PIXMAP_FILEFORMAT_AUTO, &px, fmt)) {
|
||||
log_fatal("pixmap_load_stream() failed");
|
||||
}
|
||||
|
||||
SDL_RWclose(istream);
|
||||
|
||||
pixmap_convert_inplace_realloc(&px, fmt);
|
||||
pixmap_flip_to_origin_inplace(&px, origin);
|
||||
|
||||
Texture *tex = r_texture_create(&(TextureParams) {
|
||||
.class = TEXTURE_CLASS_2D,
|
||||
.type = r_texture_type_from_pixmap_format(fmt),
|
||||
.width = px.width,
|
||||
.height = px.height,
|
||||
.layers = 1,
|
||||
.filter.min = TEX_FILTER_LINEAR,
|
||||
.filter.mag = TEX_FILTER_LINEAR,
|
||||
.wrap.s = TEX_WRAP_REPEAT,
|
||||
.wrap.t = TEX_WRAP_REPEAT,
|
||||
});
|
||||
|
||||
if(!tex) {
|
||||
log_fatal("r_texture_create() failed");
|
||||
}
|
||||
|
||||
r_texture_fill(tex, 0, 0, &px);
|
||||
mem_free(px.data.untyped);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
test_init_renderer();
|
||||
time_init();
|
||||
|
||||
FPSCounter fps = {};
|
||||
|
||||
const char *vert_shader_src =
|
||||
"#version 420\n"
|
||||
"layout(location = 0) in vec2 a_position;\n"
|
||||
"layout(location = 1) in vec2 a_uv;\n"
|
||||
"layout(location = 2) in vec4 a_color;\n"
|
||||
"layout(location = 0) out vec2 v_uv;\n"
|
||||
"layout(location = 1) out vec4 v_color;\n"
|
||||
"void main(void) {\n"
|
||||
" gl_Position = vec4(a_position, 0, 1);\n"
|
||||
" v_uv = a_uv;\n"
|
||||
" v_color = a_color;\n"
|
||||
"}\n";
|
||||
|
||||
const char *frag_shader_src =
|
||||
"#version 420\n"
|
||||
"layout(location = 0) in vec2 v_uv;\n"
|
||||
"layout(location = 1) in vec4 v_color;\n"
|
||||
"layout(location = 0) out vec4 o_color;\n"
|
||||
"uniform sampler2D u_sampler;\n"
|
||||
"void main(void) {\n"
|
||||
" o_color = texture(u_sampler, v_uv) * 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 },
|
||||
{ 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, -1, }, { 1, 1 }, { 1, 0, 0, 1 }, },
|
||||
// { { 1, 1, }, { 1, 0 }, { 0, 1, 0, 1 }, },
|
||||
// { { -1, -1, }, { 0, 1 }, { 0, 0, 1, 1 }, },
|
||||
// { { -1, 1, }, { 0, 0 }, { 1, 1, 0, 1 }, },
|
||||
|
||||
{ { 1, -1, }, { 1, 0 }, { 1, 0, 0, 1 }, },
|
||||
{ { 1, 1, }, { 1, 1 }, { 0, 1, 0, 1 }, },
|
||||
{ { -1, -1, }, { 0, 0 }, { 0, 0, 1, 1 }, },
|
||||
{ { -1, 1, }, { 0, 1 }, { 1, 1, 0, 1 }, },
|
||||
};
|
||||
|
||||
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_TRIANGLE_STRIP,
|
||||
.vertex_array = vert_array,
|
||||
.num_vertices = ARRAY_SIZE(vertices),
|
||||
.offset = 0,
|
||||
};
|
||||
|
||||
Texture *tex = load_texture("texture0.webp");
|
||||
|
||||
r_shader_ptr(prog);
|
||||
auto u_sampler = r_shader_uniform(prog, "u_sampler");
|
||||
|
||||
hrtime_t last_print_time = 0;
|
||||
|
||||
while(!taisei_quit_requested()) {
|
||||
r_clear(BUFFER_COLOR, RGB(0, 0, 0), 1);
|
||||
r_uniform_sampler(u_sampler, tex);
|
||||
r_draw_model_ptr(&triangle, 1, 0);
|
||||
events_poll(NULL, 0);
|
||||
video_swap_buffers();
|
||||
|
||||
fpscounter_update(&fps);
|
||||
|
||||
hrtime_t t = time_get();
|
||||
if(t - last_print_time > HRTIME_RESOLUTION) {
|
||||
last_print_time = t;
|
||||
log_debug("%.02f FPS", fps.fps);
|
||||
}
|
||||
}
|
||||
|
||||
r_vertex_buffer_destroy(vert_buf);
|
||||
r_vertex_array_destroy(vert_array);
|
||||
|
||||
r_shader_program_destroy(prog);
|
||||
|
||||
time_shutdown();
|
||||
test_shutdown_renderer();
|
||||
return 0;
|
||||
}
|
BIN
test/renderer/texture0.webp
Normal file
BIN
test/renderer/texture0.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
Loading…
Reference in a new issue