renderer: add scissor test API
This commit is contained in:
parent
54e212d6c5
commit
a82b63045c
9 changed files with 95 additions and 1 deletions
|
@ -720,6 +720,19 @@ void r_vertex_array_layout(VertexArray *varr, uint nattribs, VertexAttribFormat
|
|||
B.vertex_array_layout(varr, nattribs, attribs);
|
||||
}
|
||||
|
||||
void r_scissor(int x, int y, int w, int h) {
|
||||
_r_state_touch_scissor();
|
||||
B.scissor((IntRect) { x, y, w, h });
|
||||
}
|
||||
|
||||
void r_scissor_rect(IntRect scissor) {
|
||||
B.scissor(scissor);
|
||||
}
|
||||
|
||||
void r_scissor_current(IntRect *scissor) {
|
||||
B.scissor_current(scissor);
|
||||
}
|
||||
|
||||
void r_vsync(VsyncMode mode) {
|
||||
B.vsync(mode);
|
||||
}
|
||||
|
|
|
@ -793,6 +793,11 @@ void r_vertex_array_attach_index_buffer(VertexArray *varr, IndexBuffer *ibuf) at
|
|||
IndexBuffer* r_vertex_array_get_index_attachment(VertexArray *varr) attr_nonnull(1);
|
||||
void r_vertex_array_layout(VertexArray *varr, uint nattribs, VertexAttribFormat attribs[nattribs]) attr_nonnull(1, 3);
|
||||
|
||||
// NOTE: setting all parameters to 0 disables the scissor test
|
||||
void r_scissor(int x, int y, int w, int h);
|
||||
void r_scissor_rect(IntRect scissor);
|
||||
void r_scissor_current(IntRect *scissor) attr_nonnull(1);
|
||||
|
||||
void r_model_add_static(Model *out_mdl, Primitive prim, size_t num_vertices, GenericModelVertex vertices[num_vertices], size_t num_indices, uint indices[num_indices]);
|
||||
const Model *r_model_get_quad(void) attr_returns_nonnull;
|
||||
|
||||
|
|
|
@ -121,6 +121,9 @@ typedef struct RendererFuncs {
|
|||
VertexBuffer* (*vertex_array_get_vertex_attachment)(VertexArray *varr, uint attachment);
|
||||
IndexBuffer* (*vertex_array_get_index_attachment)(VertexArray *varr);
|
||||
|
||||
void (*scissor)(IntRect scissor);
|
||||
void (*scissor_current)(IntRect *scissor);
|
||||
|
||||
void (*vsync)(VsyncMode mode);
|
||||
VsyncMode (*vsync_current)(void);
|
||||
|
||||
|
|
|
@ -85,6 +85,10 @@ void r_state_pop(void) {
|
|||
B.framebuffer(S.framebuffer);
|
||||
}
|
||||
|
||||
RESTORE(RSTATE_SCISSOR) {
|
||||
B.scissor(S.scissor);
|
||||
}
|
||||
|
||||
if(_r_state.head == _r_state.stack) {
|
||||
_r_state.head = NULL;
|
||||
} else {
|
||||
|
@ -136,3 +140,9 @@ void _r_state_touch_framebuffer(void) {
|
|||
S.framebuffer = B.framebuffer_current();
|
||||
});
|
||||
}
|
||||
|
||||
void _r_state_touch_scissor(void) {
|
||||
TAINT(RSTATE_SCISSOR, {
|
||||
B.scissor_current(&S.scissor);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
RSTATE(SHADER) \
|
||||
RSTATE(SHADER_UNIFORMS) \
|
||||
RSTATE(RENDERTARGET) \
|
||||
RSTATE(SCISSOR) \
|
||||
|
||||
typedef enum RendererStateID {
|
||||
#define RSTATE(id) RSTATE_ID_##id,
|
||||
|
@ -47,6 +48,7 @@ typedef struct RendererStateRollback {
|
|||
ShaderProgram *shader;
|
||||
// TODO uniforms
|
||||
Framebuffer *framebuffer;
|
||||
IntRect scissor;
|
||||
} RendererStateRollback;
|
||||
|
||||
void _r_state_touch_capabilities(void);
|
||||
|
@ -57,6 +59,7 @@ void _r_state_touch_depth_func(void);
|
|||
void _r_state_touch_shader(void);
|
||||
void _r_state_touch_uniform(Uniform *uniform);
|
||||
void _r_state_touch_framebuffer(void);
|
||||
void _r_state_touch_scissor(void);
|
||||
|
||||
void _r_state_init(void);
|
||||
void _r_state_shutdown(void);
|
||||
|
|
|
@ -181,6 +181,7 @@ void gl33_framebuffer_clear(Framebuffer *framebuffer, ClearBufferFlags flags, co
|
|||
Framebuffer *fb_saved = r_framebuffer_current();
|
||||
r_framebuffer(framebuffer);
|
||||
gl33_sync_framebuffer();
|
||||
gl33_sync_scissor();
|
||||
glClear(glflags);
|
||||
r_framebuffer(fb_saved);
|
||||
}
|
||||
|
|
|
@ -106,6 +106,12 @@ static struct {
|
|||
FloatRect default_framebuffer;
|
||||
} viewport;
|
||||
|
||||
struct {
|
||||
IntRect pending;
|
||||
IntRect active;
|
||||
bool active_enabled;
|
||||
} scissor;
|
||||
|
||||
Color color;
|
||||
Color clear_color;
|
||||
float clear_depth;
|
||||
|
@ -379,7 +385,7 @@ static void gl33_apply_capability(RendererCapability cap, bool value) {
|
|||
}
|
||||
}
|
||||
|
||||
static void transform_viewport_origin(Framebuffer *fb, FloatRect *vp) {
|
||||
static int get_framebuffer_height(Framebuffer *fb) {
|
||||
int fb_height = 0;
|
||||
|
||||
if(fb == NULL) {
|
||||
|
@ -396,6 +402,11 @@ static void transform_viewport_origin(Framebuffer *fb, FloatRect *vp) {
|
|||
}
|
||||
|
||||
assert(fb_height > 0);
|
||||
return fb_height;
|
||||
}
|
||||
|
||||
static void transform_viewport_origin(Framebuffer *fb, FloatRect *vp) {
|
||||
int fb_height = get_framebuffer_height(fb);
|
||||
vp->y = fb_height - vp->y - vp->h;
|
||||
}
|
||||
|
||||
|
@ -416,6 +427,37 @@ static void gl33_sync_viewport(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void gl33_sync_scissor(void) {
|
||||
bool pending_enabled =
|
||||
R.scissor.pending.x &&
|
||||
R.scissor.pending.y &&
|
||||
R.scissor.pending.w &&
|
||||
R.scissor.pending.h;
|
||||
|
||||
if(!pending_enabled) {
|
||||
if(R.scissor.active_enabled) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
R.scissor.active_enabled = false;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!R.scissor.active_enabled) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
R.scissor.active_enabled = true;
|
||||
}
|
||||
|
||||
IntRect scissor = R.scissor.pending;
|
||||
int fb_height = get_framebuffer_height(R.framebuffer.pending);
|
||||
scissor.y = fb_height - scissor.y - scissor.h;
|
||||
|
||||
if(memcmp(&R.scissor.active, &scissor, sizeof(R.scissor.active))) {
|
||||
glScissor(scissor.x, scissor.y, scissor.w, scissor.h);
|
||||
R.scissor.active = scissor;
|
||||
}
|
||||
}
|
||||
|
||||
static IntExtent gl33_get_default_framebuffer_size(void) {
|
||||
IntExtent s;
|
||||
// TODO: cache this at window creation time and refresh on resize events?
|
||||
|
@ -500,6 +542,7 @@ static void gl33_sync_state(void) {
|
|||
gl33_sync_framebuffer();
|
||||
gl33_sync_shader();
|
||||
gl33_sync_viewport();
|
||||
gl33_sync_scissor();
|
||||
gl33_sync_magic_uniforms();
|
||||
gl33_sync_uniforms(R.progs.active);
|
||||
gl33_sync_texunits(true);
|
||||
|
@ -1380,6 +1423,14 @@ static bool gl33_screenshot(Pixmap *out) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static void gl33_scissor(IntRect scissor) {
|
||||
R.scissor.pending = scissor;
|
||||
}
|
||||
|
||||
static void gl33_scissor_current(IntRect *scissor) {
|
||||
*scissor = R.scissor.pending;
|
||||
}
|
||||
|
||||
RendererBackend _r_backend_gl33 = {
|
||||
.name = "gl33",
|
||||
.funcs = {
|
||||
|
@ -1467,6 +1518,8 @@ RendererBackend _r_backend_gl33 = {
|
|||
.vertex_array_get_vertex_attachment = gl33_vertex_array_get_vertex_attachment,
|
||||
.vertex_array_attach_index_buffer = gl33_vertex_array_attach_index_buffer,
|
||||
.vertex_array_get_index_attachment = gl33_vertex_array_get_index_attachment,
|
||||
.scissor = gl33_scissor,
|
||||
.scissor_current = gl33_scissor_current,
|
||||
.vsync = gl33_vsync,
|
||||
.vsync_current = gl33_vsync_current,
|
||||
.swap = gl33_swap,
|
||||
|
|
|
@ -75,6 +75,7 @@ void gl33_sync_blend_mode(void);
|
|||
void gl33_sync_cull_face_mode(void);
|
||||
void gl33_sync_depth_test_func(void);
|
||||
void gl33_sync_capabilities(void);
|
||||
void gl33_sync_scissor(void);
|
||||
|
||||
void gl33_buffer_deleted(CommonBuffer *cbuf);
|
||||
void gl33_vertex_buffer_deleted(VertexBuffer *vbuf);
|
||||
|
|
|
@ -179,6 +179,9 @@ static VertexBuffer* null_vertex_array_get_vertex_attachment(VertexArray *varr,
|
|||
static IndexBuffer* null_vertex_array_get_index_attachment(VertexArray *varr) { return (void*)&placeholder; }
|
||||
static void null_vertex_array_layout(VertexArray *varr, uint nattribs, VertexAttribFormat attribs[nattribs]) { }
|
||||
|
||||
static void null_scissor(IntRect scissor) { }
|
||||
static void null_scissor_current(IntRect *scissor) { *scissor = (IntRect) { 0 }; }
|
||||
|
||||
static void null_vsync(VsyncMode mode) { }
|
||||
static VsyncMode null_vsync_current(void) { return VSYNC_NONE; }
|
||||
|
||||
|
@ -273,6 +276,8 @@ RendererBackend _r_backend_null = {
|
|||
.vertex_array_get_vertex_attachment = null_vertex_array_get_vertex_attachment,
|
||||
.vertex_array_attach_index_buffer = null_vertex_array_attach_index_buffer,
|
||||
.vertex_array_get_index_attachment = null_vertex_array_get_index_attachment,
|
||||
.scissor = null_scissor,
|
||||
.scissor_current = null_scissor_current,
|
||||
.vsync = null_vsync,
|
||||
.vsync_current = null_vsync_current,
|
||||
.swap = null_swap,
|
||||
|
|
Loading…
Reference in a new issue