Add depth/stencil buffers to HW GL.

This commit is contained in:
Themaister 2013-03-29 02:50:42 +01:00
parent f4e9547e68
commit 50af927de6
4 changed files with 100 additions and 11 deletions

View File

@ -135,6 +135,11 @@ static PFNGLBINDFRAMEBUFFERPROC pglBindFramebuffer;
static PFNGLFRAMEBUFFERTEXTURE2DPROC pglFramebufferTexture2D; static PFNGLFRAMEBUFFERTEXTURE2DPROC pglFramebufferTexture2D;
static PFNGLCHECKFRAMEBUFFERSTATUSPROC pglCheckFramebufferStatus; static PFNGLCHECKFRAMEBUFFERSTATUSPROC pglCheckFramebufferStatus;
static PFNGLDELETEFRAMEBUFFERSPROC pglDeleteFramebuffers; static PFNGLDELETEFRAMEBUFFERSPROC pglDeleteFramebuffers;
static PFNGLGENRENDERBUFFERSPROC pglGenRenderbuffers;
static PFNGLBINDRENDERBUFFERPROC pglBindRenderbuffer;
static PFNGLFRAMEBUFFERRENDERBUFFERPROC pglFramebufferRenderbuffer;
static PFNGLRENDERBUFFERSTORAGEPROC pglRenderbufferStorage;
static PFNGLDELETERENDERBUFFERSPROC pglDeleteRenderbuffers;
static bool load_fbo_proc(gl_t *gl) static bool load_fbo_proc(gl_t *gl)
{ {
@ -143,9 +148,17 @@ static bool load_fbo_proc(gl_t *gl)
LOAD_GL_SYM(FramebufferTexture2D); LOAD_GL_SYM(FramebufferTexture2D);
LOAD_GL_SYM(CheckFramebufferStatus); LOAD_GL_SYM(CheckFramebufferStatus);
LOAD_GL_SYM(DeleteFramebuffers); LOAD_GL_SYM(DeleteFramebuffers);
LOAD_GL_SYM(GenRenderbuffers);
LOAD_GL_SYM(BindRenderbuffer);
LOAD_GL_SYM(FramebufferRenderbuffer);
LOAD_GL_SYM(RenderbufferStorage);
LOAD_GL_SYM(DeleteRenderbuffers);
return pglGenFramebuffers && pglBindFramebuffer && pglFramebufferTexture2D && return pglGenFramebuffers && pglBindFramebuffer && pglFramebufferTexture2D &&
pglCheckFramebufferStatus && pglDeleteFramebuffers; pglCheckFramebufferStatus && pglDeleteFramebuffers &&
pglGenRenderbuffers && pglBindRenderbuffer &&
pglFramebufferRenderbuffer && pglRenderbufferStorage &&
pglDeleteRenderbuffers;
} }
#elif defined(HAVE_OPENGLES2) #elif defined(HAVE_OPENGLES2)
#define pglGenFramebuffers glGenFramebuffers #define pglGenFramebuffers glGenFramebuffers
@ -153,6 +166,11 @@ static bool load_fbo_proc(gl_t *gl)
#define pglFramebufferTexture2D glFramebufferTexture2D #define pglFramebufferTexture2D glFramebufferTexture2D
#define pglCheckFramebufferStatus glCheckFramebufferStatus #define pglCheckFramebufferStatus glCheckFramebufferStatus
#define pglDeleteFramebuffers glDeleteFramebuffers #define pglDeleteFramebuffers glDeleteFramebuffers
#define pglGenRenderbuffers glGenRenderbuffers
#define pglBindRenderbuffer glBindRenderbuffer
#define pglFramebufferRenderbuffer glFramebufferRenderbuffer
#define pglRenderbufferStorage glRenderbufferStorage
#define pglDeleteRenderbuffers glDeleteRenderbuffers
#define load_fbo_proc(gl) (true) #define load_fbo_proc(gl) (true)
#elif defined(HAVE_OPENGLES) #elif defined(HAVE_OPENGLES)
#define pglGenFramebuffers glGenFramebuffersOES #define pglGenFramebuffers glGenFramebuffersOES
@ -160,6 +178,11 @@ static bool load_fbo_proc(gl_t *gl)
#define pglFramebufferTexture2D glFramebufferTexture2DOES #define pglFramebufferTexture2D glFramebufferTexture2DOES
#define pglCheckFramebufferStatus glCheckFramebufferStatusOES #define pglCheckFramebufferStatus glCheckFramebufferStatusOES
#define pglDeleteFramebuffers glDeleteFramebuffersOES #define pglDeleteFramebuffers glDeleteFramebuffersOES
#define pglGenRenderbuffers glGenRenderbuffersOES
#define pglBindRenderbuffer glBindRenderbufferOES
#define pglFramebufferRenderbuffer glFramebufferRenderbufferOES
#define pglRenderbufferStorage glRenderbufferStorageOES
#define pglDeleteRenderbuffers glDeleteRenderbuffersOES
#define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES #define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
#define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT #define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT
#define GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_OES #define GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_OES
@ -170,6 +193,11 @@ static bool load_fbo_proc(gl_t *gl)
#define pglFramebufferTexture2D glFramebufferTexture2D #define pglFramebufferTexture2D glFramebufferTexture2D
#define pglCheckFramebufferStatus glCheckFramebufferStatus #define pglCheckFramebufferStatus glCheckFramebufferStatus
#define pglDeleteFramebuffers glDeleteFramebuffers #define pglDeleteFramebuffers glDeleteFramebuffers
#define pglGenRenderbuffers glGenRenderbuffers
#define pglBindRenderbuffer glBindRenderbuffer
#define pglFramebufferRenderbuffer glFramebufferRenderbuffer
#define pglRenderbufferStorage glRenderbufferStorage
#define pglDeleteRenderbuffers glDeleteRenderbuffers
#define load_fbo_proc(gl) (true) #define load_fbo_proc(gl) (true)
#endif #endif
#endif #endif
@ -710,10 +738,44 @@ bool gl_init_hw_render(gl_t *gl, unsigned width, unsigned height)
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
pglGenFramebuffers(TEXTURES, gl->hw_render_fbo); pglGenFramebuffers(TEXTURES, gl->hw_render_fbo);
bool depth = g_extern.system.hw_render_callback.depth;
bool stencil = g_extern.system.hw_render_callback.stencil;
if (depth)
{
pglGenRenderbuffers(TEXTURES, gl->hw_render_depth);
gl->hw_render_depth_init = true;
}
if (stencil)
{
pglGenRenderbuffers(TEXTURES, gl->hw_render_stencil);
gl->hw_render_stencil_init = true;
}
for (unsigned i = 0; i < TEXTURES; i++) for (unsigned i = 0; i < TEXTURES; i++)
{ {
pglBindFramebuffer(GL_FRAMEBUFFER, gl->hw_render_fbo[i]); pglBindFramebuffer(GL_FRAMEBUFFER, gl->hw_render_fbo[i]);
pglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl->texture[i], 0); pglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl->texture[i], 0);
if (depth)
{
pglBindRenderbuffer(GL_RENDERBUFFER, gl->hw_render_depth[i]);
pglRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
width, height);
pglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, gl->hw_render_depth[i]);
}
if (stencil)
{
pglBindRenderbuffer(GL_RENDERBUFFER, gl->hw_render_stencil[i]);
pglRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
width, height);
pglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, gl->hw_render_stencil[i]);
}
GLenum status = pglCheckFramebufferStatus(GL_FRAMEBUFFER); GLenum status = pglCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) if (status != GL_FRAMEBUFFER_COMPLETE)
{ {
@ -723,6 +785,7 @@ bool gl_init_hw_render(gl_t *gl, unsigned width, unsigned height)
} }
pglBindFramebuffer(GL_FRAMEBUFFER, 0); pglBindFramebuffer(GL_FRAMEBUFFER, 0);
pglBindRenderbuffer(GL_RENDERBUFFER, 0);
gl->hw_render_fbo_init = true; gl->hw_render_fbo_init = true;
return true; return true;
} }
@ -1593,6 +1656,10 @@ static void gl_free(void *data)
if (gl->hw_render_fbo_init) if (gl->hw_render_fbo_init)
pglDeleteFramebuffers(TEXTURES, gl->hw_render_fbo); pglDeleteFramebuffers(TEXTURES, gl->hw_render_fbo);
if (gl->hw_render_depth)
pglDeleteRenderbuffers(TEXTURES, gl->hw_render_depth);
if (gl->hw_render_stencil)
pglDeleteRenderbuffers(TEXTURES, gl->hw_render_stencil);
gl->hw_render_fbo_init = false; gl->hw_render_fbo_init = false;
#endif #endif

View File

@ -244,7 +244,11 @@ typedef struct gl
bool fbo_inited; bool fbo_inited;
GLuint hw_render_fbo[TEXTURES]; GLuint hw_render_fbo[TEXTURES];
GLuint hw_render_depth[TEXTURES];
GLuint hw_render_stencil[TEXTURES];
bool hw_render_fbo_init; bool hw_render_fbo_init;
bool hw_render_depth_init;
bool hw_render_stencil_init;
#endif #endif
bool should_resize; bool should_resize;

View File

@ -218,10 +218,12 @@ void retro_run(void)
pglBindFramebuffer(GL_FRAMEBUFFER, hw_render.get_current_framebuffer()); pglBindFramebuffer(GL_FRAMEBUFFER, hw_render.get_current_framebuffer());
glClearColor(0.3, 0.4, 0.5, 1.0); glClearColor(0.3, 0.4, 0.5, 1.0);
glViewport(0, 0, 512, 512); glViewport(0, 0, 512, 512);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
pglUseProgram(prog); pglUseProgram(prog);
glEnable(GL_DEPTH_TEST);
int loc = pglGetUniformLocation(prog, "uMVP"); int loc = pglGetUniformLocation(prog, "uMVP");
static unsigned frame_count; static unsigned frame_count;
@ -230,15 +232,6 @@ void retro_run(void)
float cos_angle = cos(angle); float cos_angle = cos(angle);
float sin_angle = sin(angle); float sin_angle = sin(angle);
const GLfloat mvp[] = {
cos_angle, -sin_angle, 0, 0,
sin_angle, cos_angle, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
};
pglUniformMatrix4fv(loc, 1, GL_FALSE, mvp);
int vloc = pglGetAttribLocation(prog, "aVertex"); int vloc = pglGetAttribLocation(prog, "aVertex");
pglVertexAttribPointer(vloc, 2, GL_FLOAT, GL_FALSE, 0, vertex); pglVertexAttribPointer(vloc, 2, GL_FLOAT, GL_FALSE, 0, vertex);
pglEnableVertexAttribArray(vloc); pglEnableVertexAttribArray(vloc);
@ -246,7 +239,28 @@ void retro_run(void)
pglVertexAttribPointer(cloc, 4, GL_FLOAT, GL_FALSE, 0, color); pglVertexAttribPointer(cloc, 4, GL_FLOAT, GL_FALSE, 0, color);
pglEnableVertexAttribArray(cloc); pglEnableVertexAttribArray(cloc);
const GLfloat mvp[] = {
cos_angle, -sin_angle, 0, 0,
sin_angle, cos_angle, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
};
pglUniformMatrix4fv(loc, 1, GL_FALSE, mvp);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
cos_angle *= 0.5;
sin_angle *= 0.5;
const GLfloat mvp2[] = {
cos_angle, -sin_angle, 0, 0.0,
sin_angle, cos_angle, 0, 0.0,
0, 0, 1, 0,
0.4, 0.4, 0.2, 1,
};
pglUniformMatrix4fv(loc, 1, GL_FALSE, mvp2);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
pglUseProgram(0); pglUseProgram(0);
pglDisableVertexAttribArray(vloc); pglDisableVertexAttribArray(vloc);
pglDisableVertexAttribArray(cloc); pglDisableVertexAttribArray(cloc);
@ -274,6 +288,8 @@ bool retro_load_game(const struct retro_game_info *info)
hw_render.context_type = RETRO_HW_CONTEXT_OPENGL; hw_render.context_type = RETRO_HW_CONTEXT_OPENGL;
hw_render.context_reset = context_reset; hw_render.context_reset = context_reset;
hw_render.depth = true;
hw_render.stencil = true;
if (!environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, &hw_render)) if (!environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, &hw_render))
return false; return false;

View File

@ -462,6 +462,8 @@ struct retro_hw_render_callback
retro_hw_context_reset_t context_reset; // Set by libretro core. retro_hw_context_reset_t context_reset; // Set by libretro core.
retro_hw_get_current_framebuffer_t get_current_framebuffer; // Set by frontend. retro_hw_get_current_framebuffer_t get_current_framebuffer; // Set by frontend.
retro_hw_get_proc_address_t get_proc_address; // Set by frontend. retro_hw_get_proc_address_t get_proc_address; // Set by frontend.
bool depth; // Set if render buffers should have depth component attached.
bool stencil; // Set if render buffers should have stencil component attached.
}; };
// Callback type passed in RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK. Called by the frontend in response to keyboard events. // Callback type passed in RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK. Called by the frontend in response to keyboard events.