forked from enlightenment/efl
gl_common: Add API for redirecting render to texture
New API allows a context to be redirected to texture. When rendering is complete the texture can be unbound from the frame buffer and used for post-processing effects. Signed-off-by: Derek Foreman <derekf@osg.samsung.com> Signed-off-by: Mike Blumenkrantz <zmike@osg.samsung.com>
This commit is contained in:
parent
17bb2d60ca
commit
0f7f4b6de0
|
@ -348,6 +348,13 @@ struct _Evas_Engine_GL_Context
|
|||
int gles_version;
|
||||
|
||||
RGBA_Image *font_surface;
|
||||
|
||||
struct {
|
||||
GLuint fb;
|
||||
GLuint texture;
|
||||
GLuint depth_buffer;
|
||||
Eina_Bool active : 1;
|
||||
} redirect;
|
||||
};
|
||||
|
||||
struct _Evas_GL_Texture_Pool
|
||||
|
@ -525,6 +532,7 @@ EAPI void *evas_gl_common_current_context_get(void);
|
|||
typedef int (*Evas_GL_Preload)(void);
|
||||
typedef void (*Evas_GL_Common_Image_Call)(Evas_GL_Image *im);
|
||||
typedef void (*Evas_GL_Common_Context_Call)(Evas_Engine_GL_Context *gc);
|
||||
typedef GLuint (*Evas_GL_Common_Context_Call_GLuint_Return)(Evas_Engine_GL_Context *gc);
|
||||
typedef Evas_GL_Image *(*Evas_GL_Common_Image_New_From_Data)(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, Evas_Colorspace cspace);
|
||||
typedef void (*Evas_GL_Preload_Render_Call)(evas_gl_make_current_cb make_current, void *engine_data);
|
||||
typedef Evas_Engine_GL_Context *(*Evas_GL_Common_Context_New)(void);
|
||||
|
@ -534,6 +542,13 @@ typedef void (*Evas_Gl_Symbols)(void *(*GetProcAddress)(const char *sym));
|
|||
|
||||
EAPI void __evas_gl_err(int err, const char *file, const char *func, int line, const char *op);
|
||||
|
||||
EAPI void evas_gl_common_context_unredirect(Evas_Engine_GL_Context *gc);
|
||||
EAPI void evas_gl_common_context_redirect(Evas_Engine_GL_Context *gc);
|
||||
EAPI GLuint evas_gl_common_context_redirect_texture_get(Evas_Engine_GL_Context *gc);
|
||||
EAPI void evas_gl_common_context_redirect_bind(Evas_Engine_GL_Context *gc);
|
||||
EAPI void evas_gl_common_context_redirect_unbind(Evas_Engine_GL_Context *gc);
|
||||
|
||||
|
||||
void evas_gl_common_tiling_start(Evas_Engine_GL_Context *gc,
|
||||
int rot, int gw, int gh,
|
||||
int cx, int cy, int cw, int ch,
|
||||
|
|
|
@ -1164,6 +1164,7 @@ EAPI void
|
|||
evas_gl_common_context_resize(Evas_Engine_GL_Context *gc, int w, int h, int rot)
|
||||
{
|
||||
if ((gc->w == w) && (gc->h == h) && (gc->rot == rot)) return;
|
||||
if (gc->redirect.active) evas_gl_common_context_redirect(gc);
|
||||
evas_gl_common_context_flush(gc);
|
||||
gc->change.size = 1;
|
||||
gc->rot = rot;
|
||||
|
@ -1172,6 +1173,68 @@ evas_gl_common_context_resize(Evas_Engine_GL_Context *gc, int w, int h, int rot)
|
|||
if (_evas_gl_common_context == gc) _evas_gl_common_viewport_set(gc);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_gl_common_context_unredirect(Evas_Engine_GL_Context *gc)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteTextures(1, &gc->redirect.texture);
|
||||
glDeleteRenderbuffers(1, &gc->redirect.depth_buffer);
|
||||
glDeleteFramebuffers(1, &gc->redirect.fb);
|
||||
gc->redirect.active = EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_gl_common_context_redirect(Evas_Engine_GL_Context *gc)
|
||||
{
|
||||
if (gc->redirect.active) evas_gl_common_context_unredirect(gc);
|
||||
|
||||
/* Create a framebuffer object for RTT */
|
||||
glGenTextures(1, &gc->redirect.texture);
|
||||
glBindTexture(GL_TEXTURE_2D, gc->redirect.texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, gc->w, gc->h,
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
glGenFramebuffers(1, &gc->redirect.fb);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gc->redirect.fb);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D, gc->redirect.texture, 0);
|
||||
|
||||
glGenRenderbuffers(1, &gc->redirect.depth_buffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, gc->redirect.depth_buffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, gc->w, gc->h);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||
GL_RENDERBUFFER, gc->redirect.depth_buffer);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gc->redirect.fb);
|
||||
gc->redirect.active = EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI GLuint
|
||||
evas_gl_common_context_redirect_texture_get(Evas_Engine_GL_Context *gc)
|
||||
{
|
||||
if (!gc->redirect.active) return 0;
|
||||
return gc->redirect.texture;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_gl_common_context_redirect_bind(Evas_Engine_GL_Context *gc)
|
||||
{
|
||||
if (!gc->redirect.active) return;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gc->redirect.fb);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_gl_common_context_redirect_unbind(Evas_Engine_GL_Context *gc EINA_UNUSED)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void
|
||||
evas_gl_common_tiling_start(Evas_Engine_GL_Context *gc EINA_UNUSED,
|
||||
int rot, int gw, int gh,
|
||||
|
@ -1262,7 +1325,10 @@ evas_gl_common_context_target_surface_set(Evas_Engine_GL_Context *gc,
|
|||
# endif
|
||||
#endif
|
||||
if (gc->pipe[0].shader.surface == gc->def_surface)
|
||||
glsym_glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
{
|
||||
if (gc->redirect.active) glBindFramebuffer(GL_FRAMEBUFFER, gc->redirect.fb);
|
||||
else glsym_glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
else
|
||||
glsym_glBindFramebuffer(GL_FRAMEBUFFER, surface->tex->pt->fb);
|
||||
_evas_gl_common_viewport_set(gc);
|
||||
|
|
Loading…
Reference in New Issue