mirror of https://github.com/inolen/redream.git
added framebuffer objects to render_backend
added rb_sync / rb_wait rename vertex2d / surface2d to vertex2 / surface2
This commit is contained in:
parent
20e3a0b8ae
commit
bcdddec36c
|
@ -29,9 +29,9 @@ struct microprofile {
|
|||
struct render_backend *rb;
|
||||
struct window_listener listener;
|
||||
texture_handle_t font_texture;
|
||||
struct surface2d surfs[MAX_2D_SURFACES];
|
||||
struct surface2 surfs[MAX_2D_SURFACES];
|
||||
int num_surfs;
|
||||
struct vertex2d verts[MAX_2D_VERTICES];
|
||||
struct vertex2 verts[MAX_2D_VERTICES];
|
||||
int num_verts;
|
||||
};
|
||||
|
||||
|
@ -65,16 +65,15 @@ static void mp_mousemove(void *data, int x, int y) {
|
|||
MicroProfileMousePosition(x, y, 0);
|
||||
}
|
||||
|
||||
static struct vertex2d *mp_alloc_verts(struct microprofile *mp,
|
||||
const struct surface2d &desc,
|
||||
int count) {
|
||||
static struct vertex2 *mp_alloc_verts(struct microprofile *mp,
|
||||
const struct surface2 &desc, int count) {
|
||||
CHECK(mp->num_verts + count <= MAX_2D_VERTICES);
|
||||
uint32_t first_vert = mp->num_verts;
|
||||
mp->num_verts += count;
|
||||
|
||||
/* try to batch with the last surface if possible */
|
||||
if (mp->num_surfs) {
|
||||
struct surface2d &last_surf = mp->surfs[mp->num_surfs - 1];
|
||||
struct surface2 &last_surf = mp->surfs[mp->num_surfs - 1];
|
||||
|
||||
if (last_surf.prim_type == desc.prim_type &&
|
||||
last_surf.texture == desc.texture &&
|
||||
|
@ -87,7 +86,7 @@ static struct vertex2d *mp_alloc_verts(struct microprofile *mp,
|
|||
|
||||
/* else, allocate a new surface */
|
||||
CHECK(mp->num_surfs < MAX_2D_SURFACES);
|
||||
struct surface2d &next_surf = mp->surfs[mp->num_surfs];
|
||||
struct surface2 &next_surf = mp->surfs[mp->num_surfs];
|
||||
next_surf.prim_type = desc.prim_type;
|
||||
next_surf.texture = desc.texture;
|
||||
next_surf.src_blend = desc.src_blend;
|
||||
|
@ -106,15 +105,16 @@ static void mp_draw_text(struct microprofile *mp, int x, int y, uint32_t color,
|
|||
float fy2 = fy + (MICROPROFILE_TEXT_HEIGHT + 1);
|
||||
int text_len = static_cast<int>(strlen(text));
|
||||
|
||||
struct vertex2d *vertex = mp_alloc_verts(mp, {PRIM_TRIANGLES,
|
||||
mp->font_texture,
|
||||
BLEND_SRC_ALPHA,
|
||||
BLEND_ONE_MINUS_SRC_ALPHA,
|
||||
false,
|
||||
{0.0f, 0.0f, 0.0f, 0.0f},
|
||||
0,
|
||||
0},
|
||||
6 * text_len);
|
||||
struct vertex2 *vertex = mp_alloc_verts(mp, {PRIM_TRIANGLES,
|
||||
0,
|
||||
mp->font_texture,
|
||||
BLEND_SRC_ALPHA,
|
||||
BLEND_ONE_MINUS_SRC_ALPHA,
|
||||
false,
|
||||
{0.0f, 0.0f, 0.0f, 0.0f},
|
||||
0,
|
||||
0},
|
||||
6 * text_len);
|
||||
|
||||
for (int i = 0; i < text_len; i++) {
|
||||
float fx2 = fx + MICROPROFILE_TEXT_WIDTH;
|
||||
|
@ -154,15 +154,16 @@ static void mp_draw_text(struct microprofile *mp, int x, int y, uint32_t color,
|
|||
|
||||
static void mp_draw_box(struct microprofile *mp, int x0, int y0, int x1, int y1,
|
||||
uint32_t color, enum box_type type) {
|
||||
struct vertex2d *vertex = mp_alloc_verts(mp, {PRIM_TRIANGLES,
|
||||
0,
|
||||
BLEND_SRC_ALPHA,
|
||||
BLEND_ONE_MINUS_SRC_ALPHA,
|
||||
false,
|
||||
{0.0f, 0.0f, 0.0f, 0.0f},
|
||||
0,
|
||||
0},
|
||||
6);
|
||||
struct vertex2 *vertex = mp_alloc_verts(mp, {PRIM_TRIANGLES,
|
||||
0,
|
||||
0,
|
||||
BLEND_SRC_ALPHA,
|
||||
BLEND_ONE_MINUS_SRC_ALPHA,
|
||||
false,
|
||||
{0.0f, 0.0f, 0.0f, 0.0f},
|
||||
0,
|
||||
0},
|
||||
6);
|
||||
|
||||
if (type == BOX_FLAT) {
|
||||
Q0(vertex, xy[0], (float)x0);
|
||||
|
@ -213,15 +214,16 @@ static void mp_draw_line(struct microprofile *mp, float *verts, int num_verts,
|
|||
uint32_t color) {
|
||||
CHECK(num_verts);
|
||||
|
||||
struct vertex2d *vertex = mp_alloc_verts(mp, {PRIM_LINES,
|
||||
0,
|
||||
BLEND_SRC_ALPHA,
|
||||
BLEND_ONE_MINUS_SRC_ALPHA,
|
||||
false,
|
||||
{0.0f, 0.0f, 0.0f, 0.0f},
|
||||
0,
|
||||
0},
|
||||
2 * (num_verts - 1));
|
||||
struct vertex2 *vertex = mp_alloc_verts(mp, {PRIM_LINES,
|
||||
0,
|
||||
0,
|
||||
BLEND_SRC_ALPHA,
|
||||
BLEND_ONE_MINUS_SRC_ALPHA,
|
||||
false,
|
||||
{0.0f, 0.0f, 0.0f, 0.0f},
|
||||
0,
|
||||
0},
|
||||
2 * (num_verts - 1));
|
||||
|
||||
for (int i = 0; i < num_verts - 1; ++i) {
|
||||
vertex[0].xy[0] = verts[i * 2];
|
||||
|
@ -242,14 +244,14 @@ void mp_end_frame(struct microprofile *mp) {
|
|||
|
||||
/* render the surfaces */
|
||||
rb_begin_ortho(mp->rb);
|
||||
rb_begin_surfaces2d(mp->rb, mp->verts, mp->num_verts, nullptr, 0);
|
||||
rb_begin_surfaces2(mp->rb, mp->verts, mp->num_verts, nullptr, 0);
|
||||
|
||||
for (int i = 0; i < mp->num_surfs; i++) {
|
||||
struct surface2d *surf = &mp->surfs[i];
|
||||
rb_draw_surface2d(mp->rb, surf);
|
||||
struct surface2 *surf = &mp->surfs[i];
|
||||
rb_draw_surface2(mp->rb, surf);
|
||||
}
|
||||
|
||||
rb_end_surfaces2d(mp->rb);
|
||||
rb_end_surfaces2(mp->rb);
|
||||
rb_end_ortho(mp->rb);
|
||||
|
||||
/* reset surfaces */
|
||||
|
|
|
@ -53,10 +53,9 @@ static void nk_mousemove(void *data, int x, int y) {
|
|||
void nk_end_frame(struct nuklear *nk) {
|
||||
/* convert draw list into vertex / element buffers */
|
||||
static const struct nk_draw_vertex_layout_element vertex_layout[] = {
|
||||
{NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct vertex2d, xy)},
|
||||
{NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct vertex2d, uv)},
|
||||
{NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8,
|
||||
NK_OFFSETOF(struct vertex2d, color)},
|
||||
{NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct vertex2, xy)},
|
||||
{NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct vertex2, uv)},
|
||||
{NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct vertex2, color)},
|
||||
{NK_VERTEX_LAYOUT_END}};
|
||||
|
||||
struct nk_buffer vbuf, ebuf;
|
||||
|
@ -65,8 +64,8 @@ void nk_end_frame(struct nuklear *nk) {
|
|||
|
||||
struct nk_convert_config config = {0};
|
||||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct vertex2d);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct vertex2d);
|
||||
config.vertex_size = sizeof(struct vertex2);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct vertex2);
|
||||
config.null = nk->null;
|
||||
config.global_alpha = 1.0f;
|
||||
config.shape_AA = NK_ANTI_ALIASING_OFF;
|
||||
|
@ -76,14 +75,14 @@ void nk_end_frame(struct nuklear *nk) {
|
|||
|
||||
/* bind buffers */
|
||||
rb_begin_ortho(nk->rb);
|
||||
rb_begin_surfaces2d(nk->rb, nk->vertices, nk->ctx.draw_list.vertex_count,
|
||||
nk->elements, nk->ctx.draw_list.element_count);
|
||||
rb_begin_surfaces2(nk->rb, 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;
|
||||
int offset = 0;
|
||||
|
||||
struct surface2d surf = {0};
|
||||
struct surface2 surf = {0};
|
||||
surf.prim_type = PRIM_TRIANGLES;
|
||||
surf.src_blend = BLEND_SRC_ALPHA;
|
||||
surf.dst_blend = BLEND_ONE_MINUS_SRC_ALPHA;
|
||||
|
@ -103,13 +102,13 @@ void nk_end_frame(struct nuklear *nk) {
|
|||
surf.first_vert = offset;
|
||||
surf.num_verts = cmd->elem_count;
|
||||
|
||||
rb_draw_surface2d(nk->rb, &surf);
|
||||
rb_draw_surface2(nk->rb, &surf);
|
||||
|
||||
offset += cmd->elem_count;
|
||||
}
|
||||
nk_clear(&nk->ctx);
|
||||
|
||||
rb_end_surfaces2d(nk->rb);
|
||||
rb_end_surfaces2(nk->rb);
|
||||
rb_end_ortho(nk->rb);
|
||||
|
||||
/* reset mouse wheel state as it won't be reset through any event */
|
||||
|
|
|
@ -30,7 +30,7 @@ struct nuklear {
|
|||
texture_handle_t font_texture;
|
||||
|
||||
/* render buffers */
|
||||
struct vertex2d vertices[NK_MAX_VERTICES];
|
||||
struct vertex2 vertices[NK_MAX_VERTICES];
|
||||
uint16_t elements[NK_MAX_ELEMENTS];
|
||||
|
||||
/* input state */
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "ui/window.h"
|
||||
#include "video/render_backend.h"
|
||||
|
||||
#define MAX_FRAMEBUFFERS 8
|
||||
#define MAX_TEXTURES 8192
|
||||
|
||||
enum texture_map {
|
||||
|
@ -39,7 +40,6 @@ enum shader_attr {
|
|||
ATTR_OFFSET_COLOR = 0x20,
|
||||
ATTR_PT_ALPHA_TEST = 0x40,
|
||||
ATTR_COUNT = 0x80
|
||||
|
||||
};
|
||||
|
||||
struct shader_program {
|
||||
|
@ -50,6 +50,16 @@ struct shader_program {
|
|||
uint64_t uniform_token;
|
||||
};
|
||||
|
||||
struct framebuffer {
|
||||
GLuint fbo;
|
||||
GLuint color_component;
|
||||
GLuint depth_component;
|
||||
};
|
||||
|
||||
struct texture {
|
||||
GLuint texture;
|
||||
};
|
||||
|
||||
struct render_backend {
|
||||
struct window *window;
|
||||
|
||||
|
@ -57,8 +67,9 @@ struct render_backend {
|
|||
int debug_wireframe;
|
||||
|
||||
/* resources */
|
||||
GLuint textures[MAX_TEXTURES];
|
||||
GLuint white_tex;
|
||||
struct framebuffer framebuffers[MAX_FRAMEBUFFERS];
|
||||
struct texture textures[MAX_TEXTURES];
|
||||
struct texture white;
|
||||
|
||||
struct shader_program ta_programs[ATTR_COUNT];
|
||||
struct shader_program ui_program;
|
||||
|
@ -355,13 +366,16 @@ static void rb_destroy_textures(struct render_backend *rb) {
|
|||
return;
|
||||
}
|
||||
|
||||
glDeleteTextures(1, &rb->white_tex);
|
||||
glDeleteTextures(1, &rb->white.texture);
|
||||
|
||||
for (int i = 1; i < MAX_TEXTURES; i++) {
|
||||
if (!rb->textures[i]) {
|
||||
struct texture *tex = &rb->textures[i];
|
||||
|
||||
if (!tex->texture) {
|
||||
continue;
|
||||
}
|
||||
glDeleteTextures(1, &rb->textures[i]);
|
||||
|
||||
glDeleteTextures(1, &tex->texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -369,8 +383,8 @@ static void rb_create_textures(struct render_backend *rb) {
|
|||
uint8_t pixels[64 * 64 * 4];
|
||||
|
||||
memset(pixels, 0xff, sizeof(pixels));
|
||||
glGenTextures(1, &rb->white_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, rb->white_tex);
|
||||
glGenTextures(1, &rb->white.texture);
|
||||
glBindTexture(GL_TEXTURE_2D, rb->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,
|
||||
|
@ -470,19 +484,19 @@ static void rb_create_vertex_buffers(struct render_backend *rb) {
|
|||
|
||||
/* xy */
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct vertex2d),
|
||||
(void *)offsetof(struct vertex2d, xy));
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct vertex2),
|
||||
(void *)offsetof(struct vertex2, xy));
|
||||
|
||||
/* texcoord */
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct vertex2d),
|
||||
(void *)offsetof(struct vertex2d, uv));
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct vertex2),
|
||||
(void *)offsetof(struct vertex2, uv));
|
||||
|
||||
/* color */
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE,
|
||||
sizeof(struct vertex2d),
|
||||
(void *)offsetof(struct vertex2d, color));
|
||||
sizeof(struct vertex2),
|
||||
(void *)offsetof(struct vertex2, color));
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
@ -578,7 +592,8 @@ void rb_draw_surface(struct render_backend *rb, const struct surface *surf) {
|
|||
}
|
||||
|
||||
if (surf->texture) {
|
||||
rb_bind_texture(rb, MAP_DIFFUSE, rb->textures[surf->texture]);
|
||||
struct texture *tex = &rb->textures[surf->texture];
|
||||
rb_bind_texture(rb, MAP_DIFFUSE, tex->texture);
|
||||
}
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, surf->first_vert, surf->num_verts);
|
||||
|
@ -601,10 +616,9 @@ void rb_begin_surfaces(struct render_backend *rb, const float *projection,
|
|||
}
|
||||
}
|
||||
|
||||
void rb_end_surfaces2d(struct render_backend *rb) {}
|
||||
void rb_end_surfaces2(struct render_backend *rb) {}
|
||||
|
||||
void rb_draw_surface2d(struct render_backend *rb,
|
||||
const struct surface2d *surf) {
|
||||
void rb_draw_surface2(struct render_backend *rb, const struct surface2 *surf) {
|
||||
if (surf->scissor) {
|
||||
rb_set_scissor_test(rb, 1);
|
||||
rb_set_scissor_clip(rb, (int)surf->scissor_rect[0],
|
||||
|
@ -615,8 +629,16 @@ void rb_draw_surface2d(struct render_backend *rb,
|
|||
}
|
||||
|
||||
rb_set_blend_func(rb, surf->src_blend, surf->dst_blend);
|
||||
rb_bind_texture(rb, MAP_DIFFUSE,
|
||||
surf->texture ? rb->textures[surf->texture] : rb->white_tex);
|
||||
|
||||
if (surf->framebuffer) {
|
||||
struct framebuffer *fb = &rb->framebuffers[surf->framebuffer];
|
||||
rb_bind_texture(rb, MAP_DIFFUSE, fb->color_component);
|
||||
} else if (surf->texture) {
|
||||
struct texture *tex = &rb->textures[surf->texture];
|
||||
rb_bind_texture(rb, MAP_DIFFUSE, tex->texture);
|
||||
} else {
|
||||
rb_bind_texture(rb, MAP_DIFFUSE, rb->white.texture);
|
||||
}
|
||||
|
||||
if (rb->ui_use_ibo) {
|
||||
glDrawElements(prim_types[surf->prim_type], surf->num_verts,
|
||||
|
@ -628,11 +650,10 @@ void rb_draw_surface2d(struct render_backend *rb,
|
|||
}
|
||||
}
|
||||
|
||||
void rb_begin_surfaces2d(struct render_backend *rb,
|
||||
const struct vertex2d *verts, int num_verts,
|
||||
uint16_t *indices, int num_indices) {
|
||||
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);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(struct vertex2d) * num_verts, verts,
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(struct vertex2) * num_verts, verts,
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
if (indices) {
|
||||
|
@ -690,15 +711,29 @@ void rb_begin_frame(struct render_backend *rb) {
|
|||
rb_set_depth_mask(rb, 1);
|
||||
|
||||
glViewport(0, 0, rb->window->width, rb->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) {
|
||||
GLsync sync = on;
|
||||
CHECK(glIsSync(sync));
|
||||
|
||||
GLenum res = glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, UINT64_MAX);
|
||||
CHECK(res == GL_ALREADY_SIGNALED || res == GL_CONDITION_SATISFIED);
|
||||
glDeleteSync(sync);
|
||||
}
|
||||
|
||||
sync_handle_t rb_sync(struct render_backend *rb) {
|
||||
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
glFlush();
|
||||
return sync;
|
||||
}
|
||||
|
||||
void rb_destroy_texture(struct render_backend *rb, texture_handle_t handle) {
|
||||
GLuint *gltex = &rb->textures[handle];
|
||||
glDeleteTextures(1, gltex);
|
||||
*gltex = 0;
|
||||
struct texture *tex = &rb->textures[handle];
|
||||
glDeleteTextures(1, &tex->texture);
|
||||
tex->texture = 0;
|
||||
}
|
||||
|
||||
texture_handle_t rb_create_texture(struct render_backend *rb,
|
||||
|
@ -710,7 +745,8 @@ texture_handle_t rb_create_texture(struct render_backend *rb,
|
|||
/* find next open texture handle */
|
||||
texture_handle_t handle;
|
||||
for (handle = 1; handle < MAX_TEXTURES; handle++) {
|
||||
if (!rb->textures[handle]) {
|
||||
struct texture *tex = &rb->textures[handle];
|
||||
if (!tex->texture) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -744,9 +780,9 @@ texture_handle_t rb_create_texture(struct render_backend *rb,
|
|||
break;
|
||||
}
|
||||
|
||||
GLuint *gltex = &rb->textures[handle];
|
||||
glGenTextures(1, gltex);
|
||||
glBindTexture(GL_TEXTURE_2D, *gltex);
|
||||
struct texture *tex = &rb->textures[handle];
|
||||
glGenTextures(1, &tex->texture);
|
||||
glBindTexture(GL_TEXTURE_2D, tex->texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
filter_funcs[mipmaps * NUM_FILTER_MODES + filter]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_funcs[filter]);
|
||||
|
@ -764,6 +800,73 @@ 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];
|
||||
|
||||
glDeleteTextures(1, &fb->color_component);
|
||||
fb->color_component = 0;
|
||||
|
||||
glDeleteRenderbuffers(1, &fb->depth_component);
|
||||
fb->depth_component = 0;
|
||||
|
||||
glDeleteFramebuffers(1, &fb->fbo);
|
||||
fb->fbo = 0;
|
||||
}
|
||||
|
||||
void rb_bind_framebuffer(struct render_backend *rb,
|
||||
framebuffer_handle_t handle) {
|
||||
struct framebuffer *fb = &rb->framebuffers[handle];
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb->fbo);
|
||||
}
|
||||
|
||||
framebuffer_handle_t rb_create_framebuffer(struct render_backend *rb) {
|
||||
/* find next open framebuffer handle */
|
||||
framebuffer_handle_t handle;
|
||||
for (handle = 1; handle < MAX_FRAMEBUFFERS; handle++) {
|
||||
struct framebuffer *fb = &rb->framebuffers[handle];
|
||||
if (!fb->fbo) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
CHECK_LT(handle, MAX_FRAMEBUFFERS);
|
||||
|
||||
struct framebuffer *fb = &rb->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,
|
||||
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);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
/* 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);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
/* create fbo */
|
||||
glGenFramebuffers(1, &fb->fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb->fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
fb->color_component, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||
GL_RENDERBUFFER, fb->depth_component);
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
CHECK_EQ(status, GL_FRAMEBUFFER_COMPLETE);
|
||||
|
||||
/* switch back to default framebuffer */
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void rb_destroy(struct render_backend *rb) {
|
||||
rb_destroy_vertex_buffers(rb);
|
||||
rb_destroy_shaders(rb);
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
struct window;
|
||||
|
||||
typedef int framebuffer_handle_t;
|
||||
typedef int texture_handle_t;
|
||||
typedef void *sync_handle_t;
|
||||
|
||||
enum pxl_format {
|
||||
PXL_INVALID,
|
||||
|
@ -103,19 +105,24 @@ struct surface {
|
|||
int num_verts;
|
||||
};
|
||||
|
||||
struct vertex2d {
|
||||
struct vertex2 {
|
||||
float xy[2];
|
||||
float uv[2];
|
||||
uint32_t color;
|
||||
};
|
||||
|
||||
struct surface2d {
|
||||
struct surface2 {
|
||||
enum prim_type prim_type;
|
||||
|
||||
framebuffer_handle_t framebuffer;
|
||||
texture_handle_t texture;
|
||||
|
||||
enum blend_func src_blend;
|
||||
enum blend_func dst_blend;
|
||||
|
||||
int scissor;
|
||||
float scissor_rect[4];
|
||||
|
||||
int first_vert;
|
||||
int num_verts;
|
||||
};
|
||||
|
@ -125,6 +132,12 @@ struct render_backend;
|
|||
struct render_backend *rb_create(struct window *window);
|
||||
void rb_destroy(struct render_backend *rb);
|
||||
|
||||
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);
|
||||
|
||||
texture_handle_t rb_create_texture(struct render_backend *rb,
|
||||
enum pxl_format format,
|
||||
enum filter_mode filter,
|
||||
|
@ -133,6 +146,9 @@ texture_handle_t rb_create_texture(struct render_backend *rb,
|
|||
const uint8_t *buffer);
|
||||
void rb_destroy_texture(struct render_backend *rb, texture_handle_t handle);
|
||||
|
||||
sync_handle_t rb_sync(struct render_backend *rb);
|
||||
void rb_wait(sync_handle_t on);
|
||||
|
||||
void rb_begin_frame(struct render_backend *rb);
|
||||
void rb_end_frame(struct render_backend *rb);
|
||||
|
||||
|
@ -144,10 +160,9 @@ void rb_begin_surfaces(struct render_backend *rb, const float *projection,
|
|||
void rb_draw_surface(struct render_backend *rb, const struct surface *surf);
|
||||
void rb_end_surfaces(struct render_backend *rb);
|
||||
|
||||
void rb_begin_surfaces2d(struct render_backend *rb,
|
||||
const struct vertex2d *verts, int num_verts,
|
||||
uint16_t *indices, int num_indices);
|
||||
void rb_draw_surface2d(struct render_backend *rb, const struct surface2d *surf);
|
||||
void rb_end_surfaces2d(struct render_backend *rb);
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue