rename render backend to be more consistent with jit / audio backends

This commit is contained in:
Anthony Pesch 2017-04-16 00:04:13 -04:00
parent 6d377e53b9
commit f4f8393ded
9 changed files with 287 additions and 291 deletions

View File

@ -24,14 +24,14 @@ DEFINE_AGGREGATE_COUNTER(frames);
DEFINE_OPTION_INT(audio, 1, "Enable audio");
struct emu {
struct window *window;
struct window *win;
struct window_listener listener;
struct dreamcast *dc;
volatile int running;
int debug_menu;
struct render_backend *rb;
struct render_backend *r;
struct microprofile *mp;
struct nuklear *nk;
@ -81,7 +81,7 @@ static int emu_launch_gdi(struct emu *emu, const char *path) {
}
static void emu_paint(struct emu *emu) {
rb_begin_frame(emu->rb);
r_begin_frame(emu->r);
nk_begin_frame(emu->nk);
mp_begin_frame(emu->mp);
@ -105,7 +105,7 @@ static void emu_paint(struct emu *emu) {
{
if (emu->debug_menu) {
struct nk_context *ctx = &emu->nk->ctx;
struct nk_rect bounds = {0.0f, 0.0f, (float)emu->window->width,
struct nk_rect bounds = {0.0f, 0.0f, (float)emu->win->width,
DEBUG_MENU_HEIGHT};
nk_style_default(ctx);
@ -126,9 +126,9 @@ static void emu_paint(struct emu *emu) {
nk_vec2(140.0f, 200.0f))) {
nk_layout_row_dynamic(ctx, DEBUG_MENU_HEIGHT, 1);
int fullscreen = emu->window->fullscreen;
int fullscreen = emu->win->fullscreen;
if (nk_checkbox_label(ctx, "fullscreen", &fullscreen)) {
win_set_fullscreen(emu->window, fullscreen);
win_set_fullscreen(emu->win, fullscreen);
}
nk_menu_end(ctx);
@ -152,7 +152,7 @@ static void emu_paint(struct emu *emu) {
"FPS %3d RPS %3d VBS %3d SH4 %4d ARM %d", frames, ta_renders,
pvr_vblanks, sh4_instrs, arm7_instrs);
nk_layout_row_push(ctx, (float)emu->window->width -
nk_layout_row_push(ctx, (float)emu->win->width -
ctx->current->layout->row.item_offset);
nk_label(ctx, status, NK_TEXT_RIGHT);
@ -169,7 +169,7 @@ static void emu_paint(struct emu *emu) {
mp_end_frame(emu->mp);
nk_end_frame(emu->nk);
rb_end_frame(emu->rb);
r_end_frame(emu->r);
}
static void emu_keydown(void *data, int device_index, enum keycode code,
@ -283,7 +283,7 @@ void emu_run(struct emu *emu, const char *path) {
thread_t core_thread = thread_create(&emu_core_thread, NULL, emu);
while (emu->running) {
win_pump_events(emu->window);
win_pump_events(emu->win);
emu_paint(emu);
}
@ -296,32 +296,32 @@ void emu_destroy(struct emu *emu) {
tr_destroy(emu->tr);
nk_destroy(emu->nk);
mp_destroy(emu->mp);
rb_destroy(emu->rb);
r_destroy(emu->r);
dc_destroy(emu->dc);
win_remove_listener(emu->window, &emu->listener);
win_remove_listener(emu->win, &emu->listener);
free(emu);
}
struct emu *emu_create(struct window *window) {
struct emu *emu_create(struct window *win) {
struct emu *emu = calloc(1, sizeof(struct emu));
emu->window = window;
emu->win = win;
/* add window input listeners */
emu->listener = (struct window_listener){
emu, &emu_joy_add, &emu_joy_remove, &emu_keydown, NULL, &emu_close, {0}};
win_add_listener(emu->window, &emu->listener);
win_add_listener(emu->win, &emu->listener);
/* setup dreamcast */
emu->dc = dc_create();
/* setup render backend */
emu->rb = rb_create(emu->window);
emu->mp = mp_create(emu->window, emu->rb);
emu->nk = nk_create(emu->window, emu->rb);
emu->tr = tr_create(emu->rb, ta_texture_provider(emu->dc->ta));
emu->r = r_create(emu->win);
emu->mp = mp_create(emu->win, emu->r);
emu->nk = nk_create(emu->win, emu->r);
emu->tr = tr_create(emu->r, ta_texture_provider(emu->dc->ta));
/* debug menu enabled by default */
emu->debug_menu = 1;

View File

@ -9,7 +9,7 @@
#include "hw/pvr/ta.h"
struct tr {
struct render_backend *rb;
struct render_backend *r;
struct texture_provider *provider;
/* current global state */
@ -138,7 +138,7 @@ static texture_handle_t tr_demand_texture(struct tr *tr,
/* if there's a dirty handle, destroy it before creating the new one */
if (entry->handle && entry->dirty) {
rb_destroy_texture(tr->rb, entry->handle);
r_destroy_texture(tr->r, entry->handle);
entry->handle = 0;
}
@ -336,8 +336,8 @@ static texture_handle_t tr_demand_texture(struct tr *tr,
tsp.clamp_v ? WRAP_CLAMP_TO_EDGE
: (tsp.flip_v ? WRAP_MIRRORED_REPEAT : WRAP_REPEAT);
entry->handle = rb_create_texture(tr->rb, pixel_fmt, filter, wrap_u, wrap_v,
mipmaps, width, height, output);
entry->handle = r_create_texture(tr->r, pixel_fmt, filter, wrap_u, wrap_v,
mipmaps, width, height, output);
entry->format = pixel_fmt;
entry->filter = filter;
entry->wrap_u = wrap_u;
@ -1025,7 +1025,7 @@ static void tr_render_list(struct tr *tr, const struct tile_render_context *rc,
const int *sorted_surf_end = list->surfs + list->num_surfs;
while (sorted_surf < sorted_surf_end) {
rb_draw_surface(tr->rb, &rc->surfs[*sorted_surf]);
r_draw_surface(tr->r, &rc->surfs[*sorted_surf]);
sorted_surf++;
}
}
@ -1033,13 +1033,13 @@ static void tr_render_list(struct tr *tr, const struct tile_render_context *rc,
void tr_render_context(struct tr *tr, const struct tile_render_context *rc) {
PROF_ENTER("gpu", "tr_render_context");
rb_begin_surfaces(tr->rb, rc->projection, rc->verts, rc->num_verts);
r_begin_surfaces(tr->r, rc->projection, rc->verts, rc->num_verts);
tr_render_list(tr, rc, TA_LIST_OPAQUE);
tr_render_list(tr, rc, TA_LIST_PUNCH_THROUGH);
tr_render_list(tr, rc, TA_LIST_TRANSLUCENT);
rb_end_surfaces(tr->rb);
r_end_surfaces(tr->r);
PROF_LEAVE();
}
@ -1048,11 +1048,11 @@ void tr_destroy(struct tr *tr) {
free(tr);
}
struct tr *tr_create(struct render_backend *rb,
struct tr *tr_create(struct render_backend *r,
struct texture_provider *provider) {
struct tr *tr = calloc(1, sizeof(struct tr));
tr->rb = rb;
tr->r = r;
tr->provider = provider;
return tr;

View File

@ -65,8 +65,8 @@ struct tracer_texture_entry {
};
struct tracer {
struct window *window;
struct render_backend *rb;
struct window *win;
struct render_backend *r;
struct nuklear *nk;
struct tr *tr;
struct window_listener listener;
@ -293,9 +293,9 @@ static void tracer_render_scrubber_menu(struct tracer *tracer) {
ctx->style.window.padding = nk_vec2(0.0f, 0.0f);
ctx->style.window.spacing = nk_vec2(0.0f, 0.0f);
struct nk_rect bounds = {
0.0f, (float)tracer->window->height - SCRUBBER_WINDOW_HEIGHT,
(float)tracer->window->width, SCRUBBER_WINDOW_HEIGHT};
struct nk_rect bounds = {0.0f,
(float)tracer->win->height - SCRUBBER_WINDOW_HEIGHT,
(float)tracer->win->width, SCRUBBER_WINDOW_HEIGHT};
nk_flags flags = NK_WINDOW_NO_SCROLLBAR;
if (nk_begin(ctx, "context scrubber", bounds, flags)) {
@ -576,7 +576,7 @@ static void tracer_render_side_menu(struct tracer *tracer) {
{
struct nk_rect bounds = {0.0f, 0.0, 240.0f,
tracer->window->height - SCRUBBER_WINDOW_HEIGHT};
tracer->win->height - SCRUBBER_WINDOW_HEIGHT};
nk_style_default(ctx);
@ -657,8 +657,8 @@ static void tracer_render_side_menu(struct tracer *tracer) {
}
{
struct nk_rect bounds = {tracer->window->width - 240.0f, 0.0, 240.0f,
tracer->window->height - SCRUBBER_WINDOW_HEIGHT};
struct nk_rect bounds = {tracer->win->width - 240.0f, 0.0, 240.0f,
tracer->win->height - SCRUBBER_WINDOW_HEIGHT};
nk_style_default(ctx);
@ -732,7 +732,7 @@ static void tracer_render_list(struct tracer *tracer,
while (sorted_surf < sorted_surf_end) {
int idx = *(sorted_surf++);
rb_draw_surface(tracer->rb, &tracer->rc.surfs[idx]);
r_draw_surface(tracer->r, &tracer->rc.surfs[idx]);
if (idx == end) {
*stopped = 1;
@ -742,7 +742,7 @@ static void tracer_render_list(struct tracer *tracer,
}
static void tracer_paint(struct tracer *tracer) {
rb_begin_frame(tracer->rb);
r_begin_frame(tracer->r);
nk_begin_frame(tracer->nk);
/* render ui */
@ -760,17 +760,17 @@ static void tracer_paint(struct tracer *tracer) {
end = rp->last_surf;
}
rb_begin_surfaces(tracer->rb, rc->projection, rc->verts, rc->num_verts);
r_begin_surfaces(tracer->r, rc->projection, rc->verts, rc->num_verts);
tracer_render_list(tracer, rc, TA_LIST_OPAQUE, end, &stopped);
tracer_render_list(tracer, rc, TA_LIST_PUNCH_THROUGH, end, &stopped);
tracer_render_list(tracer, rc, TA_LIST_TRANSLUCENT, end, &stopped);
rb_end_surfaces(tracer->rb);
r_end_surfaces(tracer->r);
}
nk_end_frame(tracer->nk);
rb_end_frame(tracer->rb);
r_end_frame(tracer->r);
}
static void tracer_keydown(void *data, int device_index, enum keycode code,
@ -820,7 +820,7 @@ void tracer_run(struct tracer *tracer, const char *path) {
tracer->running = 1;
while (tracer->running) {
win_pump_events(tracer->window);
win_pump_events(tracer->win);
tracer_paint(tracer);
}
}
@ -832,33 +832,33 @@ void tracer_destroy(struct tracer *tracer) {
tr_destroy(tracer->tr);
nk_destroy(tracer->nk);
rb_destroy(tracer->rb);
r_destroy(tracer->r);
win_remove_listener(tracer->window, &tracer->listener);
win_remove_listener(tracer->win, &tracer->listener);
free(tracer);
}
struct tracer *tracer_create(struct window *window) {
struct tracer *tracer_create(struct window *win) {
/* ensure param / poly / vertex size LUTs are generated */
ta_build_tables();
struct tracer *tracer = calloc(1, sizeof(struct tracer));
tracer->window = window;
tracer->win = win;
/* add window input listeners */
tracer->listener = (struct window_listener){
tracer, NULL, NULL, &tracer_keydown, NULL, &tracer_close, {0}};
win_add_listener(tracer->window, &tracer->listener);
win_add_listener(tracer->win, &tracer->listener);
/* setup render backend */
tracer->rb = rb_create(tracer->window);
tracer->nk = nk_create(tracer->window, tracer->rb);
tracer->r = r_create(tracer->win);
tracer->nk = nk_create(tracer->win, tracer->r);
tracer->provider =
(struct texture_provider){tracer, &tracer_texture_provider_find_texture};
tracer->tr = tr_create(tracer->rb, &tracer->provider);
tracer->tr = tr_create(tracer->r, &tracer->provider);
/* add all textures to free list */
for (int i = 0, n = array_size(tracer->textures); i < n; i++) {

View File

@ -26,7 +26,7 @@ static const int MAX_2D_SURFACES = 256;
struct microprofile {
struct window *window;
struct render_backend *rb;
struct render_backend *r;
struct window_listener listener;
texture_handle_t font_texture;
struct surface2 surfs[MAX_2D_SURFACES];
@ -243,16 +243,16 @@ void mp_end_frame(struct microprofile *mp) {
MicroProfileDraw(mp->window->width, mp->window->height);
/* render the surfaces */
rb_begin_ortho(mp->rb);
rb_begin_surfaces2(mp->rb, mp->verts, mp->num_verts, nullptr, 0);
r_begin_ortho(mp->r);
r_begin_surfaces2(mp->r, mp->verts, mp->num_verts, nullptr, 0);
for (int i = 0; i < mp->num_surfs; i++) {
struct surface2 *surf = &mp->surfs[i];
rb_draw_surface2(mp->rb, surf);
r_draw_surface2(mp->r, surf);
}
rb_end_surfaces2(mp->rb);
rb_end_ortho(mp->rb);
r_end_surfaces2(mp->r);
r_end_ortho(mp->r);
/* reset surfaces */
mp->num_surfs = 0;
@ -262,7 +262,7 @@ void mp_end_frame(struct microprofile *mp) {
void mp_begin_frame(struct microprofile *mp) {}
void mp_destroy(struct microprofile *mp) {
rb_destroy_texture(mp->rb, mp->font_texture);
r_destroy_texture(mp->r, mp->font_texture);
win_remove_listener(mp->window, &mp->listener);
@ -270,12 +270,12 @@ void mp_destroy(struct microprofile *mp) {
}
struct microprofile *mp_create(struct window *window,
struct render_backend *rb) {
struct render_backend *r) {
struct microprofile *mp = reinterpret_cast<struct microprofile *>(
calloc(1, sizeof(struct microprofile)));
mp->window = window;
mp->rb = rb;
mp->r = r;
/* add input event listeners */
mp->listener = {mp, NULL, NULL, &mp_keydown, &mp_mousemove, NULL, {}};
@ -296,9 +296,9 @@ struct microprofile *mp_create(struct window *window,
/* register the font texture */
mp->font_texture =
rb_create_texture(mp->rb, PXL_RGBA, FILTER_NEAREST, WRAP_CLAMP_TO_EDGE,
WRAP_CLAMP_TO_EDGE, 0, FONT_WIDTH, FONT_HEIGHT,
reinterpret_cast<const uint8_t *>(s_font_data));
r_create_texture(mp->r, PXL_RGBA, FILTER_NEAREST, WRAP_CLAMP_TO_EDGE,
WRAP_CLAMP_TO_EDGE, 0, FONT_WIDTH, FONT_HEIGHT,
reinterpret_cast<const uint8_t *>(s_font_data));
return mp;
}

View File

@ -5,8 +5,7 @@ struct microprofile;
struct render_backend;
struct window;
struct microprofile *mp_create(struct window *window,
struct render_backend *rb);
struct microprofile *mp_create(struct window *window, struct render_backend *r);
void mp_destroy(struct microprofile *mp);
void mp_begin_frame(struct microprofile *mp);

View File

@ -74,9 +74,9 @@ void nk_end_frame(struct nuklear *nk) {
nk_convert(&nk->ctx, &nk->cmds, &vbuf, &ebuf, &config);
/* bind buffers */
rb_begin_ortho(nk->rb);
rb_begin_surfaces2(nk->rb, nk->vertices, nk->ctx.draw_list.vertex_count,
nk->elements, nk->ctx.draw_list.element_count);
r_begin_ortho(nk->r);
r_begin_surfaces2(nk->r, nk->vertices, nk->ctx.draw_list.vertex_count,
nk->elements, nk->ctx.draw_list.element_count);
/* pass each draw command off to the render backend */
const struct nk_draw_command *cmd = NULL;
@ -102,14 +102,14 @@ void nk_end_frame(struct nuklear *nk) {
surf.first_vert = offset;
surf.num_verts = cmd->elem_count;
rb_draw_surface2(nk->rb, &surf);
r_draw_surface2(nk->r, &surf);
offset += cmd->elem_count;
}
nk_clear(&nk->ctx);
rb_end_surfaces2(nk->rb);
rb_end_ortho(nk->rb);
r_end_surfaces2(nk->r);
r_end_ortho(nk->r);
/* reset mouse wheel state as it won't be reset through any event */
nk->mouse_wheel = 0;
@ -136,18 +136,18 @@ void nk_destroy(struct nuklear *nk) {
nk_font_atlas_clear(&nk->atlas);
nk_free(&nk->ctx);
rb_destroy_texture(nk->rb, nk->font_texture);
r_destroy_texture(nk->r, nk->font_texture);
win_remove_listener(nk->window, &nk->listener);
free(nk);
}
struct nuklear *nk_create(struct window *window, struct render_backend *rb) {
struct nuklear *nk_create(struct window *window, struct render_backend *r) {
struct nuklear *nk = calloc(1, sizeof(struct nuklear));
nk->window = window;
nk->rb = rb;
nk->r = r;
/* add input event listeners */
nk->listener = (struct window_listener){
@ -162,8 +162,8 @@ struct nuklear *nk_create(struct window *window, struct render_backend *rb) {
const void *font_data = nk_font_atlas_bake(
&nk->atlas, &font_width, &font_height, NK_FONT_ATLAS_RGBA32);
nk->font_texture =
rb_create_texture(nk->rb, PXL_RGBA, FILTER_BILINEAR, WRAP_REPEAT,
WRAP_REPEAT, 0, font_width, font_height, font_data);
r_create_texture(nk->r, PXL_RGBA, FILTER_BILINEAR, WRAP_REPEAT,
WRAP_REPEAT, 0, font_width, font_height, font_data);
nk_font_atlas_end(&nk->atlas, nk_handle_id((int)nk->font_texture), &nk->null);
/* initialize nuklear context */

View File

@ -20,7 +20,7 @@ struct render_backend;
struct nuklear {
struct window *window;
struct render_backend *rb;
struct render_backend *r;
struct window_listener listener;
struct nk_context ctx;
@ -42,7 +42,7 @@ struct nuklear {
int shift[2];
};
struct nuklear *nk_create(struct window *window, struct render_backend *rb);
struct nuklear *nk_create(struct window *window, struct render_backend *r);
void nk_destroy(struct nuklear *nk);
void nk_begin_frame(struct nuklear *nk);

View File

@ -147,12 +147,12 @@ static GLenum prim_types[] = {
GL_LINES, /* PRIM_LINES */
};
static void rb_set_scissor_test(struct render_backend *rb, int enabled) {
if (rb->scissor_test == enabled) {
static void r_set_scissor_test(struct render_backend *r, int enabled) {
if (r->scissor_test == enabled) {
return;
}
rb->scissor_test = enabled;
r->scissor_test = enabled;
if (enabled) {
glEnable(GL_SCISSOR_TEST);
@ -161,27 +161,27 @@ static void rb_set_scissor_test(struct render_backend *rb, int enabled) {
}
}
static void rb_set_scissor_clip(struct render_backend *rb, int x, int y,
int width, int height) {
static void r_set_scissor_clip(struct render_backend *r, int x, int y,
int width, int height) {
glScissor(x, y, width, height);
}
static void rb_set_depth_mask(struct render_backend *rb, int enabled) {
if (rb->depth_mask == enabled) {
static void r_set_depth_mask(struct render_backend *r, int enabled) {
if (r->depth_mask == enabled) {
return;
}
rb->depth_mask = enabled;
r->depth_mask = enabled;
glDepthMask(enabled ? 1 : 0);
}
static void rb_set_depth_func(struct render_backend *rb, enum depth_func fn) {
if (rb->depth_func == fn) {
static void r_set_depth_func(struct render_backend *r, enum depth_func fn) {
if (r->depth_func == fn) {
return;
}
rb->depth_func = fn;
r->depth_func = fn;
if (fn == DEPTH_NONE) {
glDisable(GL_DEPTH_TEST);
@ -191,12 +191,12 @@ static void rb_set_depth_func(struct render_backend *rb, enum depth_func fn) {
}
}
static void rb_set_cull_face(struct render_backend *rb, enum cull_face fn) {
if (rb->cull_face == fn) {
static void r_set_cull_face(struct render_backend *r, enum cull_face fn) {
if (r->cull_face == fn) {
return;
}
rb->cull_face = fn;
r->cull_face = fn;
if (fn == CULL_NONE) {
glDisable(GL_CULL_FACE);
@ -206,14 +206,14 @@ static void rb_set_cull_face(struct render_backend *rb, enum cull_face fn) {
}
}
static void rb_set_blend_func(struct render_backend *rb, enum blend_func src_fn,
enum blend_func dst_fn) {
if (rb->src_blend == src_fn && rb->dst_blend == dst_fn) {
static void r_set_blend_func(struct render_backend *r, enum blend_func src_fn,
enum blend_func dst_fn) {
if (r->src_blend == src_fn && r->dst_blend == dst_fn) {
return;
}
rb->src_blend = src_fn;
rb->dst_blend = dst_fn;
r->src_blend = src_fn;
r->dst_blend = dst_fn;
if (src_fn == BLEND_NONE || dst_fn == BLEND_NONE) {
glDisable(GL_BLEND);
@ -223,38 +223,38 @@ static void rb_set_blend_func(struct render_backend *rb, enum blend_func src_fn,
}
}
static void rb_bind_vao(struct render_backend *rb, GLuint vao) {
if (rb->current_vao == vao) {
static void r_bind_vao(struct render_backend *r, GLuint vao) {
if (r->current_vao == vao) {
return;
}
rb->current_vao = vao;
r->current_vao = vao;
glBindVertexArray(vao);
}
static void rb_bind_program(struct render_backend *rb,
struct shader_program *program) {
if (rb->current_program == program) {
static void r_bind_program(struct render_backend *r,
struct shader_program *program) {
if (r->current_program == program) {
return;
}
rb->current_program = program;
r->current_program = program;
glUseProgram(program ? program->program : 0);
}
void rb_bind_texture(struct render_backend *rb, enum texture_map map,
GLuint tex) {
void r_bind_texture(struct render_backend *r, enum texture_map map,
GLuint tex) {
glActiveTexture(GL_TEXTURE0 + map);
glBindTexture(GL_TEXTURE_2D, tex);
}
static GLint rb_get_uniform(struct render_backend *rb, enum uniform_attr attr) {
return rb->current_program->uniforms[attr];
static GLint r_get_uniform(struct render_backend *r, enum uniform_attr attr) {
return r->current_program->uniforms[attr];
}
static void rb_print_shader_log(GLuint shader) {
static void r_print_shader_log(GLuint shader) {
int max_length, length;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &max_length);
@ -264,8 +264,8 @@ static void rb_print_shader_log(GLuint shader) {
free(info_log);
}
static int rb_compile_shader(const char *source, GLenum shader_type,
GLuint *shader) {
static int r_compile_shader(const char *source, GLenum shader_type,
GLuint *shader) {
size_t sourceLength = strlen(source);
*shader = glCreateShader(shader_type);
@ -277,7 +277,7 @@ static int rb_compile_shader(const char *source, GLenum shader_type,
glGetShaderiv(*shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
rb_print_shader_log(*shader);
r_print_shader_log(*shader);
glDeleteShader(*shader);
return 0;
}
@ -285,7 +285,7 @@ static int rb_compile_shader(const char *source, GLenum shader_type,
return 1;
}
static void rb_destroy_program(struct shader_program *program) {
static void r_destroy_program(struct shader_program *program) {
if (program->vertex_shader > 0) {
glDeleteShader(program->vertex_shader);
}
@ -297,10 +297,10 @@ static void rb_destroy_program(struct shader_program *program) {
glDeleteProgram(program->program);
}
static int rb_compile_program(struct render_backend *rb,
struct shader_program *program,
const char *header, const char *vertex_source,
const char *fragment_source) {
static int r_compile_program(struct render_backend *r,
struct shader_program *program, const char *header,
const char *vertex_source,
const char *fragment_source) {
char buffer[16384] = {0};
memset(program, 0, sizeof(*program));
@ -313,8 +313,8 @@ static int rb_compile_program(struct render_backend *rb,
header ? header : "", vertex_source);
buffer[sizeof(buffer) - 1] = 0;
if (!rb_compile_shader(buffer, GL_VERTEX_SHADER, &program->vertex_shader)) {
rb_destroy_program(program);
if (!r_compile_shader(buffer, GL_VERTEX_SHADER, &program->vertex_shader)) {
r_destroy_program(program);
return 0;
}
@ -328,9 +328,9 @@ static int rb_compile_program(struct render_backend *rb,
header ? header : "", fragment_source);
buffer[sizeof(buffer) - 1] = 0;
if (!rb_compile_shader(buffer, GL_FRAGMENT_SHADER,
&program->fragment_shader)) {
rb_destroy_program(program);
if (!r_compile_shader(buffer, GL_FRAGMENT_SHADER,
&program->fragment_shader)) {
r_destroy_program(program);
return 0;
}
@ -343,7 +343,7 @@ static int rb_compile_program(struct render_backend *rb,
glGetProgramiv(program->program, GL_LINK_STATUS, &linked);
if (!linked) {
rb_destroy_program(program);
r_destroy_program(program);
return 0;
}
@ -353,22 +353,22 @@ static int rb_compile_program(struct render_backend *rb,
}
/* bind diffuse sampler once after compile, this currently never changes */
rb_bind_program(rb, program);
glUniform1i(rb_get_uniform(rb, UNIFORM_DIFFUSE), MAP_DIFFUSE);
rb_bind_program(rb, NULL);
r_bind_program(r, program);
glUniform1i(r_get_uniform(r, UNIFORM_DIFFUSE), MAP_DIFFUSE);
r_bind_program(r, NULL);
return 1;
}
static void rb_destroy_textures(struct render_backend *rb) {
if (!rb->ctx) {
static void r_destroy_textures(struct render_backend *r) {
if (!r->ctx) {
return;
}
glDeleteTextures(1, &rb->white.texture);
glDeleteTextures(1, &r->white.texture);
for (int i = 1; i < MAX_TEXTURES; i++) {
struct texture *tex = &rb->textures[i];
struct texture *tex = &r->textures[i];
if (!tex->texture) {
continue;
@ -378,12 +378,12 @@ static void rb_destroy_textures(struct render_backend *rb) {
}
}
static void rb_create_textures(struct render_backend *rb) {
static void r_create_textures(struct render_backend *r) {
uint8_t pixels[64 * 64 * 4];
memset(pixels, 0xff, sizeof(pixels));
glGenTextures(1, &rb->white.texture);
glBindTexture(GL_TEXTURE_2D, rb->white.texture);
glGenTextures(1, &r->white.texture);
glBindTexture(GL_TEXTURE_2D, r->white.texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE,
@ -391,23 +391,23 @@ static void rb_create_textures(struct render_backend *rb) {
glBindTexture(GL_TEXTURE_2D, 0);
}
static void rb_destroy_shaders(struct render_backend *rb) {
if (!rb->ctx) {
static void r_destroy_shaders(struct render_backend *r) {
if (!r->ctx) {
return;
}
for (int i = 0; i < ATTR_COUNT; i++) {
rb_destroy_program(&rb->ta_programs[i]);
r_destroy_program(&r->ta_programs[i]);
}
rb_destroy_program(&rb->ui_program);
r_destroy_program(&r->ui_program);
}
static void rb_create_shaders(struct render_backend *rb) {
static void r_create_shaders(struct render_backend *r) {
char header[1024];
for (int i = 0; i < ATTR_COUNT; i++) {
struct shader_program *program = &rb->ta_programs[i];
struct shader_program *program = &r->ta_programs[i];
header[0] = 0;
@ -446,40 +446,40 @@ static void rb_create_shaders(struct render_backend *rb) {
strcat(header, "#define PT_ALPHA_TEST\n");
}
if (!rb_compile_program(rb, program, header, ta_vp, ta_fp)) {
if (!r_compile_program(r, program, header, ta_vp, ta_fp)) {
LOG_FATAL("Failed to compile ta shader.");
}
}
if (!rb_compile_program(rb, &rb->ui_program, NULL, ui_vp, ui_fp)) {
if (!r_compile_program(r, &r->ui_program, NULL, ui_vp, ui_fp)) {
LOG_FATAL("Failed to compile ui shader.");
}
}
static void rb_destroy_vertex_buffers(struct render_backend *rb) {
if (!rb->ctx) {
static void r_destroy_vertex_buffers(struct render_backend *r) {
if (!r->ctx) {
return;
}
glDeleteBuffers(1, &rb->ui_ibo);
glDeleteBuffers(1, &rb->ui_vbo);
glDeleteVertexArrays(1, &rb->ui_vao);
glDeleteBuffers(1, &r->ui_ibo);
glDeleteBuffers(1, &r->ui_vbo);
glDeleteVertexArrays(1, &r->ui_vao);
glDeleteBuffers(1, &rb->ta_vbo);
glDeleteVertexArrays(1, &rb->ta_vao);
glDeleteBuffers(1, &r->ta_vbo);
glDeleteVertexArrays(1, &r->ta_vao);
}
static void rb_create_vertex_buffers(struct render_backend *rb) {
static void r_create_vertex_buffers(struct render_backend *r) {
/* ui vao */
{
glGenVertexArrays(1, &rb->ui_vao);
glBindVertexArray(rb->ui_vao);
glGenVertexArrays(1, &r->ui_vao);
glBindVertexArray(r->ui_vao);
glGenBuffers(1, &rb->ui_vbo);
glBindBuffer(GL_ARRAY_BUFFER, rb->ui_vbo);
glGenBuffers(1, &r->ui_vbo);
glBindBuffer(GL_ARRAY_BUFFER, r->ui_vbo);
glGenBuffers(1, &rb->ui_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rb->ui_ibo);
glGenBuffers(1, &r->ui_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, r->ui_ibo);
/* xy */
glEnableVertexAttribArray(0);
@ -503,11 +503,11 @@ static void rb_create_vertex_buffers(struct render_backend *rb) {
/* ta vao */
{
glGenVertexArrays(1, &rb->ta_vao);
glBindVertexArray(rb->ta_vao);
glGenVertexArrays(1, &r->ta_vao);
glBindVertexArray(r->ta_vao);
glGenBuffers(1, &rb->ta_vbo);
glBindBuffer(GL_ARRAY_BUFFER, rb->ta_vbo);
glGenBuffers(1, &r->ta_vbo);
glBindBuffer(GL_ARRAY_BUFFER, r->ta_vbo);
/* xyz */
glEnableVertexAttribArray(0);
@ -537,15 +537,15 @@ static void rb_create_vertex_buffers(struct render_backend *rb) {
}
}
static void rb_set_initial_state(struct render_backend *rb) {
rb_set_depth_mask(rb, 1);
rb_set_depth_func(rb, DEPTH_NONE);
rb_set_cull_face(rb, CULL_BACK);
rb_set_blend_func(rb, BLEND_NONE, BLEND_NONE);
static void r_set_initial_state(struct render_backend *r) {
r_set_depth_mask(r, 1);
r_set_depth_func(r, DEPTH_NONE);
r_set_cull_face(r, CULL_BACK);
r_set_blend_func(r, BLEND_NONE, BLEND_NONE);
}
static struct shader_program *rb_get_ta_program(struct render_backend *rb,
const struct surface *surf) {
static struct shader_program *r_get_ta_program(struct render_backend *r,
const struct surface *surf) {
int idx = surf->shade;
if (surf->texture) {
idx |= ATTR_TEXTURE;
@ -562,77 +562,76 @@ static struct shader_program *rb_get_ta_program(struct render_backend *rb,
if (surf->pt_alpha_test) {
idx |= ATTR_PT_ALPHA_TEST;
}
struct shader_program *program = &rb->ta_programs[idx];
struct shader_program *program = &r->ta_programs[idx];
CHECK_NOTNULL(program);
return program;
}
void rb_end_surfaces(struct render_backend *rb) {
}
void r_end_surfaces(struct render_backend *r) {}
void rb_draw_surface(struct render_backend *rb, const struct surface *surf) {
rb_set_depth_mask(rb, surf->depth_write);
rb_set_depth_func(rb, surf->depth_func);
rb_set_cull_face(rb, surf->cull);
rb_set_blend_func(rb, surf->src_blend, surf->dst_blend);
void r_draw_surface(struct render_backend *r, const struct surface *surf) {
r_set_depth_mask(r, surf->depth_write);
r_set_depth_func(r, surf->depth_func);
r_set_cull_face(r, surf->cull);
r_set_blend_func(r, surf->src_blend, surf->dst_blend);
struct shader_program *program = rb_get_ta_program(rb, surf);
rb_bind_program(rb, program);
struct shader_program *program = r_get_ta_program(r, surf);
r_bind_program(r, program);
/* if uniforms have yet to be bound for this program, do so now */
if (program->uniform_token != rb->uniform_token) {
glUniformMatrix4fv(rb_get_uniform(rb, UNIFORM_MVP), 1, GL_FALSE,
rb->uniform_mvp);
glUniform1f(rb_get_uniform(rb, UNIFORM_PT_ALPHA_REF), surf->pt_alpha_ref);
program->uniform_token = rb->uniform_token;
if (program->uniform_token != r->uniform_token) {
glUniformMatrix4fv(r_get_uniform(r, UNIFORM_MVP), 1, GL_FALSE,
r->uniform_mvp);
glUniform1f(r_get_uniform(r, UNIFORM_PT_ALPHA_REF), surf->pt_alpha_ref);
program->uniform_token = r->uniform_token;
}
if (surf->texture) {
struct texture *tex = &rb->textures[surf->texture];
rb_bind_texture(rb, MAP_DIFFUSE, tex->texture);
struct texture *tex = &r->textures[surf->texture];
r_bind_texture(r, MAP_DIFFUSE, tex->texture);
}
glDrawArrays(GL_TRIANGLE_STRIP, surf->first_vert, surf->num_verts);
}
void rb_begin_surfaces(struct render_backend *rb, const float *projection,
const struct vertex *verts, int num_verts) {
/* uniforms will be lazily bound for each program inside of rb_draw_surface */
rb->uniform_token++;
rb->uniform_mvp = projection;
void r_begin_surfaces(struct render_backend *r, const float *projection,
const struct vertex *verts, int num_verts) {
/* uniforms will be lazily bound for each program inside of r_draw_surface */
r->uniform_token++;
r->uniform_mvp = projection;
glBindBuffer(GL_ARRAY_BUFFER, rb->ta_vbo);
glBindBuffer(GL_ARRAY_BUFFER, r->ta_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(struct vertex) * num_verts, verts,
GL_DYNAMIC_DRAW);
rb_bind_vao(rb, rb->ta_vao);
r_bind_vao(r, r->ta_vao);
}
void rb_end_surfaces2(struct render_backend *rb) {}
void r_end_surfaces2(struct render_backend *r) {}
void rb_draw_surface2(struct render_backend *rb, const struct surface2 *surf) {
void r_draw_surface2(struct render_backend *r, const struct surface2 *surf) {
if (surf->scissor) {
rb_set_scissor_test(rb, 1);
rb_set_scissor_clip(rb, (int)surf->scissor_rect[0],
(int)surf->scissor_rect[1], (int)surf->scissor_rect[2],
(int)surf->scissor_rect[3]);
r_set_scissor_test(r, 1);
r_set_scissor_clip(r, (int)surf->scissor_rect[0],
(int)surf->scissor_rect[1], (int)surf->scissor_rect[2],
(int)surf->scissor_rect[3]);
} else {
rb_set_scissor_test(rb, 0);
r_set_scissor_test(r, 0);
}
rb_set_blend_func(rb, surf->src_blend, surf->dst_blend);
r_set_blend_func(r, surf->src_blend, surf->dst_blend);
if (surf->framebuffer) {
struct framebuffer *fb = &rb->framebuffers[surf->framebuffer];
rb_bind_texture(rb, MAP_DIFFUSE, fb->color_component);
struct framebuffer *fb = &r->framebuffers[surf->framebuffer];
r_bind_texture(r, MAP_DIFFUSE, fb->color_component);
} else if (surf->texture) {
struct texture *tex = &rb->textures[surf->texture];
rb_bind_texture(rb, MAP_DIFFUSE, tex->texture);
struct texture *tex = &r->textures[surf->texture];
r_bind_texture(r, MAP_DIFFUSE, tex->texture);
} else {
rb_bind_texture(rb, MAP_DIFFUSE, rb->white.texture);
r_bind_texture(r, MAP_DIFFUSE, r->white.texture);
}
if (rb->ui_use_ibo) {
if (r->ui_use_ibo) {
glDrawElements(prim_types[surf->prim_type], surf->num_verts,
GL_UNSIGNED_SHORT,
(void *)(intptr_t)(sizeof(uint16_t) * surf->first_vert));
@ -642,37 +641,37 @@ void rb_draw_surface2(struct render_backend *rb, const struct surface2 *surf) {
}
}
void rb_begin_surfaces2(struct render_backend *rb, const struct vertex2 *verts,
int num_verts, uint16_t *indices, int num_indices) {
glBindBuffer(GL_ARRAY_BUFFER, rb->ui_vbo);
void r_begin_surfaces2(struct render_backend *r, const struct vertex2 *verts,
int num_verts, uint16_t *indices, int num_indices) {
glBindBuffer(GL_ARRAY_BUFFER, r->ui_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(struct vertex2) * num_verts, verts,
GL_DYNAMIC_DRAW);
if (indices) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rb->ui_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, r->ui_ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint16_t) * num_indices,
indices, GL_DYNAMIC_DRAW);
rb->ui_use_ibo = 1;
r->ui_use_ibo = 1;
} else {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, -1);
rb->ui_use_ibo = 0;
r->ui_use_ibo = 0;
}
}
void rb_end_ortho(struct render_backend *rb) {
rb_set_scissor_test(rb, 0);
void r_end_ortho(struct render_backend *r) {
r_set_scissor_test(r, 0);
}
void rb_begin_ortho(struct render_backend *rb) {
void r_begin_ortho(struct render_backend *r) {
float ortho[16];
ortho[0] = 2.0f / (float)rb->window->width;
ortho[0] = 2.0f / (float)r->window->width;
ortho[4] = 0.0f;
ortho[8] = 0.0f;
ortho[12] = -1.0f;
ortho[1] = 0.0f;
ortho[5] = -2.0f / (float)rb->window->height;
ortho[5] = -2.0f / (float)r->window->height;
ortho[9] = 0.0f;
ortho[13] = 1.0f;
@ -686,28 +685,28 @@ void rb_begin_ortho(struct render_backend *rb) {
ortho[11] = 0.0f;
ortho[15] = 1.0f;
rb_set_depth_mask(rb, 0);
rb_set_depth_func(rb, DEPTH_NONE);
rb_set_cull_face(rb, CULL_NONE);
r_set_depth_mask(r, 0);
r_set_depth_func(r, DEPTH_NONE);
r_set_cull_face(r, CULL_NONE);
rb_bind_vao(rb, rb->ui_vao);
rb_bind_program(rb, &rb->ui_program);
glUniformMatrix4fv(rb_get_uniform(rb, UNIFORM_MVP), 1, GL_FALSE, ortho);
r_bind_vao(r, r->ui_vao);
r_bind_program(r, &r->ui_program);
glUniformMatrix4fv(r_get_uniform(r, UNIFORM_MVP), 1, GL_FALSE, ortho);
}
void rb_end_frame(struct render_backend *rb) {
SDL_GL_SwapWindow(rb->window->handle);
void r_end_frame(struct render_backend *r) {
SDL_GL_SwapWindow(r->window->handle);
}
void rb_begin_frame(struct render_backend *rb) {
rb_set_depth_mask(rb, 1);
void r_begin_frame(struct render_backend *r) {
r_set_depth_mask(r, 1);
glViewport(0, 0, rb->window->width, rb->window->height);
glViewport(0, 0, r->window->width, r->window->height);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void rb_wait(sync_handle_t on) {
void r_wait(sync_handle_t on) {
GLsync sync = on;
CHECK(glIsSync(sync));
@ -716,28 +715,28 @@ void rb_wait(sync_handle_t on) {
glDeleteSync(sync);
}
sync_handle_t rb_sync(struct render_backend *rb) {
sync_handle_t r_sync(struct render_backend *r) {
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
return sync;
}
void rb_destroy_texture(struct render_backend *rb, texture_handle_t handle) {
struct texture *tex = &rb->textures[handle];
void r_destroy_texture(struct render_backend *r, texture_handle_t handle) {
struct texture *tex = &r->textures[handle];
glDeleteTextures(1, &tex->texture);
tex->texture = 0;
}
texture_handle_t rb_create_texture(struct render_backend *rb,
enum pxl_format format,
enum filter_mode filter,
enum wrap_mode wrap_u, enum wrap_mode wrap_v,
int mipmaps, int width, int height,
const uint8_t *buffer) {
texture_handle_t r_create_texture(struct render_backend *r,
enum pxl_format format,
enum filter_mode filter,
enum wrap_mode wrap_u, enum wrap_mode wrap_v,
int mipmaps, int width, int height,
const uint8_t *buffer) {
/* find next open texture handle */
texture_handle_t handle;
for (handle = 1; handle < MAX_TEXTURES; handle++) {
struct texture *tex = &rb->textures[handle];
struct texture *tex = &r->textures[handle];
if (!tex->texture) {
break;
}
@ -772,7 +771,7 @@ texture_handle_t rb_create_texture(struct render_backend *rb,
break;
}
struct texture *tex = &rb->textures[handle];
struct texture *tex = &r->textures[handle];
glGenTextures(1, &tex->texture);
glBindTexture(GL_TEXTURE_2D, tex->texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
@ -792,9 +791,9 @@ texture_handle_t rb_create_texture(struct render_backend *rb,
return handle;
}
void rb_destroy_framebuffer(struct render_backend *rb,
framebuffer_handle_t handle) {
struct framebuffer *fb = &rb->framebuffers[handle];
void r_destroy_framebuffer(struct render_backend *r,
framebuffer_handle_t handle) {
struct framebuffer *fb = &r->framebuffers[handle];
glDeleteTextures(1, &fb->color_component);
fb->color_component = 0;
@ -806,30 +805,29 @@ void rb_destroy_framebuffer(struct render_backend *rb,
fb->fbo = 0;
}
void rb_bind_framebuffer(struct render_backend *rb,
framebuffer_handle_t handle) {
struct framebuffer *fb = &rb->framebuffers[handle];
void r_bind_framebuffer(struct render_backend *r, framebuffer_handle_t handle) {
struct framebuffer *fb = &r->framebuffers[handle];
glBindFramebuffer(GL_FRAMEBUFFER, fb->fbo);
}
framebuffer_handle_t rb_create_framebuffer(struct render_backend *rb) {
framebuffer_handle_t r_create_framebuffer(struct render_backend *r) {
/* find next open framebuffer handle */
framebuffer_handle_t handle;
for (handle = 1; handle < MAX_FRAMEBUFFERS; handle++) {
struct framebuffer *fb = &rb->framebuffers[handle];
struct framebuffer *fb = &r->framebuffers[handle];
if (!fb->fbo) {
break;
}
}
CHECK_LT(handle, MAX_FRAMEBUFFERS);
struct framebuffer *fb = &rb->framebuffers[handle];
struct framebuffer *fb = &r->framebuffers[handle];
/* create color component */
glGenTextures(1, &fb->color_component);
glBindTexture(GL_TEXTURE_2D, fb->color_component);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rb->window->width, rb->window->height,
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, r->window->width, r->window->height,
0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@ -838,8 +836,8 @@ framebuffer_handle_t rb_create_framebuffer(struct render_backend *rb) {
/* create depth component */
glGenRenderbuffers(1, &fb->depth_component);
glBindRenderbuffer(GL_RENDERBUFFER, fb->depth_component);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, rb->window->width,
rb->window->height);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, r->window->width,
r->window->height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
/* create fbo */
@ -859,28 +857,28 @@ framebuffer_handle_t rb_create_framebuffer(struct render_backend *rb) {
return handle;
}
void rb_destroy(struct render_backend *rb) {
rb_destroy_vertex_buffers(rb);
rb_destroy_shaders(rb);
rb_destroy_textures(rb);
void r_destroy(struct render_backend *r) {
r_destroy_vertex_buffers(r);
r_destroy_shaders(r);
r_destroy_textures(r);
win_gl_destroy_context(rb->window, rb->ctx);
win_gl_destroy_context(r->window, r->ctx);
free(rb);
free(r);
}
struct render_backend *rb_create(struct window *window) {
struct render_backend *rb = calloc(1, sizeof(struct render_backend));
struct render_backend *r_create(struct window *window) {
struct render_backend *r = calloc(1, sizeof(struct render_backend));
rb->window = window;
r->window = window;
/* setup gl context */
rb->ctx = win_gl_create_context(rb->window);
r->ctx = win_gl_create_context(r->window);
rb_create_textures(rb);
rb_create_shaders(rb);
rb_create_vertex_buffers(rb);
rb_set_initial_state(rb);
r_create_textures(r);
r_create_shaders(r);
r_create_vertex_buffers(r);
r_set_initial_state(r);
return rb;
return r;
}

View File

@ -129,40 +129,39 @@ struct surface2 {
struct render_backend;
struct render_backend *rb_create(struct window *window);
void rb_destroy(struct render_backend *rb);
struct render_backend *r_create(struct window *window);
void r_destroy(struct render_backend *r);
framebuffer_handle_t rb_create_framebuffer(struct render_backend *rb);
void rb_bind_framebuffer(struct render_backend *rb,
framebuffer_handle_t handle);
void rb_destroy_framebuffer(struct render_backend *rb,
framebuffer_handle_t handle);
framebuffer_handle_t r_create_framebuffer(struct render_backend *r);
void r_bind_framebuffer(struct render_backend *r, framebuffer_handle_t handle);
void r_destroy_framebuffer(struct render_backend *r,
framebuffer_handle_t handle);
texture_handle_t rb_create_texture(struct render_backend *rb,
enum pxl_format format,
enum filter_mode filter,
enum wrap_mode wrap_u, enum wrap_mode wrap_v,
int mipmaps, int width, int height,
const uint8_t *buffer);
void rb_destroy_texture(struct render_backend *rb, texture_handle_t handle);
texture_handle_t r_create_texture(struct render_backend *r,
enum pxl_format format,
enum filter_mode filter,
enum wrap_mode wrap_u, enum wrap_mode wrap_v,
int mipmaps, int width, int height,
const uint8_t *buffer);
void r_destroy_texture(struct render_backend *r, texture_handle_t handle);
sync_handle_t rb_sync(struct render_backend *rb);
void rb_wait(sync_handle_t on);
sync_handle_t r_sync(struct render_backend *r);
void r_wait(sync_handle_t on);
void rb_begin_frame(struct render_backend *rb);
void rb_end_frame(struct render_backend *rb);
void r_begin_frame(struct render_backend *r);
void r_end_frame(struct render_backend *r);
void rb_begin_ortho(struct render_backend *rb);
void rb_end_ortho(struct render_backend *rb);
void r_begin_ortho(struct render_backend *r);
void r_end_ortho(struct render_backend *r);
void rb_begin_surfaces(struct render_backend *rb, const float *projection,
const struct vertex *verts, int num_verts);
void rb_draw_surface(struct render_backend *rb, const struct surface *surf);
void rb_end_surfaces(struct render_backend *rb);
void r_begin_surfaces(struct render_backend *r, const float *projection,
const struct vertex *verts, int num_verts);
void r_draw_surface(struct render_backend *r, const struct surface *surf);
void r_end_surfaces(struct render_backend *r);
void rb_begin_surfaces2(struct render_backend *rb, const struct vertex2 *verts,
int num_verts, uint16_t *indices, int num_indices);
void rb_draw_surface2(struct render_backend *rb, const struct surface2 *surf);
void rb_end_surfaces2(struct render_backend *rb);
void r_begin_surfaces2(struct render_backend *r, const struct vertex2 *verts,
int num_verts, uint16_t *indices, int num_indices);
void r_draw_surface2(struct render_backend *r, const struct surface2 *surf);
void r_end_surfaces2(struct render_backend *r);
#endif