mirror of
https://github.com/libretro/RetroArch
synced 2025-03-27 05:37:40 +00:00
Add overlay rendering to GL.
This allows e.g. Android to render a keypad overlay for touch.
This commit is contained in:
parent
c42bbaf191
commit
5eb7432fff
@ -548,6 +548,7 @@ const gfx_ctx_driver_t gfx_ctx_android = {
|
||||
NULL,
|
||||
gfx_ctx_init_egl_image_buffer,
|
||||
gfx_ctx_write_egl_image,
|
||||
NULL,
|
||||
"android",
|
||||
#ifdef HAVE_RMENU
|
||||
gfx_ctx_set_blend,
|
||||
|
@ -651,6 +651,7 @@ const gfx_ctx_driver_t gfx_ctx_drm_egl = {
|
||||
gfx_ctx_get_proc_address,
|
||||
gfx_ctx_init_egl_image_buffer,
|
||||
gfx_ctx_write_egl_image,
|
||||
NULL,
|
||||
"drm-egl",
|
||||
};
|
||||
|
||||
|
@ -598,6 +598,7 @@ const gfx_ctx_driver_t gfx_ctx_glx = {
|
||||
gfx_ctx_get_proc_address,
|
||||
gfx_ctx_init_egl_image_buffer,
|
||||
gfx_ctx_write_egl_image,
|
||||
NULL,
|
||||
"glx",
|
||||
};
|
||||
|
||||
|
@ -535,6 +535,7 @@ const gfx_ctx_driver_t gfx_ctx_ps3 = {
|
||||
NULL,
|
||||
gfx_ctx_init_egl_image_buffer,
|
||||
gfx_ctx_write_egl_image,
|
||||
NULL,
|
||||
"ps3",
|
||||
#ifdef HAVE_RMENU
|
||||
gfx_ctx_set_blend,
|
||||
|
@ -371,6 +371,7 @@ const gfx_ctx_driver_t gfx_ctx_sdl_gl = {
|
||||
gfx_ctx_get_proc_address,
|
||||
gfx_ctx_init_egl_image_buffer,
|
||||
gfx_ctx_write_egl_image,
|
||||
NULL,
|
||||
"sdl-gl",
|
||||
};
|
||||
|
||||
|
@ -480,5 +480,6 @@ const gfx_ctx_driver_t gfx_ctx_videocore = {
|
||||
gfx_ctx_get_proc_address,
|
||||
gfx_ctx_init_egl_image_buffer,
|
||||
gfx_ctx_write_egl_image,
|
||||
NULL,
|
||||
"videocore",
|
||||
};
|
||||
|
@ -456,6 +456,7 @@ const gfx_ctx_driver_t gfx_ctx_wgl = {
|
||||
gfx_ctx_get_proc_address,
|
||||
gfx_ctx_init_egl_image_buffer,
|
||||
gfx_ctx_write_egl_image,
|
||||
NULL,
|
||||
"wgl",
|
||||
};
|
||||
|
||||
|
@ -490,6 +490,7 @@ const gfx_ctx_driver_t gfx_ctx_xdk = {
|
||||
NULL,
|
||||
gfx_ctx_init_egl_image_buffer,
|
||||
gfx_ctx_write_egl_image,
|
||||
NULL,
|
||||
"xdk",
|
||||
|
||||
// RARCH_CONSOLE stuff.
|
||||
|
@ -549,6 +549,7 @@ const gfx_ctx_driver_t gfx_ctx_x_egl = {
|
||||
gfx_ctx_get_proc_address,
|
||||
gfx_ctx_init_egl_image_buffer,
|
||||
gfx_ctx_write_egl_image,
|
||||
NULL,
|
||||
"x-egl",
|
||||
};
|
||||
|
||||
|
@ -101,6 +101,10 @@ typedef struct gfx_ctx_driver
|
||||
// Always returns true the first time it's called for a new index. The graphics core must handle a change in the handle correctly.
|
||||
bool (*write_egl_image)(const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, unsigned index, void **image_handle);
|
||||
|
||||
// Called after frame is rendered, but before swap.
|
||||
// Can be used to render context-specific overlays and stuff.
|
||||
bool (*post_render)(void *gl);
|
||||
|
||||
// Human readable string.
|
||||
const char *ident;
|
||||
|
||||
|
77
gfx/gl.c
77
gfx/gl.c
@ -21,6 +21,7 @@
|
||||
#include "../driver.h"
|
||||
#include "../performance.h"
|
||||
#include "scaler/scaler.h"
|
||||
#include "image.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../libretro.h"
|
||||
@ -1182,6 +1183,9 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
||||
if (msg && gl->font_ctx)
|
||||
gl->font_ctx->render_msg(gl, msg);
|
||||
|
||||
if (gl->ctx_driver->post_render)
|
||||
context_post_render_func(gl);
|
||||
|
||||
#if !defined(RARCH_CONSOLE)
|
||||
context_update_window_title_func(false);
|
||||
#endif
|
||||
@ -1230,6 +1234,8 @@ static void gl_free(void *data)
|
||||
#endif
|
||||
|
||||
glDeleteTextures(TEXTURES, gl->texture);
|
||||
if (gl->tex_overlay)
|
||||
glDeleteTextures(1, &gl->tex_overlay);
|
||||
|
||||
#if defined(HAVE_PSGL)
|
||||
glBindBuffer(GL_TEXTURE_REFERENCE_BUFFER_SCE, 0);
|
||||
@ -1776,9 +1782,78 @@ static void gl_set_aspect_ratio(void *data, unsigned aspectratio_index)
|
||||
gl->keep_aspect = true;
|
||||
gl->should_resize = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool gl_load_overlay(gl_t *gl, const char *path)
|
||||
{
|
||||
if (!gl->tex_overlay)
|
||||
glGenTextures(1, &gl->tex_overlay);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gl->tex_overlay);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
struct texture_image img = {0};
|
||||
if (!texture_image_load(path, &img))
|
||||
{
|
||||
RARCH_ERR("Failed to load overlay image: %s.\n", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(img.width * sizeof(uint32_t)));
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, RARCH_GL_INTERNAL_FORMAT32,
|
||||
img.width, img.height, 0, RARCH_GL_TEXTURE_TYPE32,
|
||||
RARCH_GL_FORMAT32, img.pixels);
|
||||
|
||||
free(img.pixels);
|
||||
gl_set_overlay_tex_coord(gl, 0, 0, 1, 1); // Default. Stretch to whole screen.
|
||||
gl_set_overlay_vertex_coord(gl, 0, 0, 1, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void gl_set_overlay_tex_coord(gl_t *gl,
|
||||
GLfloat x, GLfloat y,
|
||||
GLfloat w, GLfloat h)
|
||||
{
|
||||
gl->overlay_tex_coord[0] = x; gl->overlay_tex_coord[1] = y;
|
||||
gl->overlay_tex_coord[2] = x + w; gl->overlay_tex_coord[3] = y;
|
||||
gl->overlay_tex_coord[4] = x; gl->overlay_tex_coord[5] = y + h;
|
||||
gl->overlay_tex_coord[6] = x + w; gl->overlay_tex_coord[7] = y + h;
|
||||
}
|
||||
|
||||
void gl_set_overlay_vertex_coord(gl_t *gl,
|
||||
GLfloat x, GLfloat y,
|
||||
GLfloat w, GLfloat h)
|
||||
{
|
||||
// Flipped, so we preserve top-down semantics.
|
||||
y = 1.0f - y;
|
||||
h = -h;
|
||||
|
||||
gl->overlay_vertex_coord[0] = x; gl->overlay_vertex_coord[1] = y;
|
||||
gl->overlay_vertex_coord[2] = x + w; gl->overlay_vertex_coord[3] = y;
|
||||
gl->overlay_vertex_coord[4] = x; gl->overlay_vertex_coord[5] = y + h;
|
||||
gl->overlay_vertex_coord[6] = x + w; gl->overlay_vertex_coord[7] = y + h;
|
||||
}
|
||||
|
||||
void gl_render_overlay(gl_t *gl)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, gl->tex_overlay);
|
||||
|
||||
gl_shader_use_func(gl, 0);
|
||||
glEnable(GL_BLEND);
|
||||
gl->coords.vertex = gl->overlay_vertex_coord;
|
||||
gl->coords.tex_coord = gl->overlay_tex_coord;
|
||||
gl_shader_set_coords_func(gl, &gl->coords, &gl->mvp);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
gl->coords.vertex = vertex_ptr;
|
||||
gl->coords.tex_coord = gl->tex_coords;
|
||||
}
|
||||
|
||||
const video_driver_t video_gl = {
|
||||
gl_init,
|
||||
gl_frame,
|
||||
|
@ -76,6 +76,7 @@
|
||||
#define context_translate_aspect_func(width, height) gl->ctx_driver->translate_aspect(width, height)
|
||||
#define context_set_resize_func(width, height) gl->ctx_driver->set_resize(width, height)
|
||||
#define context_swap_buffers_func() gl->ctx_driver->swap_buffers()
|
||||
#define context_post_render_func(gl) gl->ctx_driver->post_render(gl)
|
||||
#define context_swap_interval_func(var) gl->ctx_driver->swap_interval(var)
|
||||
#define context_has_focus_func() gl->ctx_driver->has_focus()
|
||||
#define context_check_window_func(quit, resize, width, height, frame_count) \
|
||||
@ -279,6 +280,12 @@ typedef struct gl
|
||||
|
||||
bool egl_images;
|
||||
|
||||
// Overlay rendering
|
||||
GLuint tex_overlay;
|
||||
GLfloat overlay_tex_coord[8];
|
||||
GLfloat overlay_vertex_coord[8];
|
||||
GLfloat overlay_alpha_mod; // TODO. Needs a specific shader.
|
||||
|
||||
#if !defined(HAVE_OPENGLES) && defined(HAVE_FFMPEG)
|
||||
// PBOs used for asynchronous viewport readbacks.
|
||||
GLuint pbo_readback[4];
|
||||
@ -359,4 +366,14 @@ void gl_shader_set_coords(gl_t *gl, const struct gl_coords *coords, const math_m
|
||||
void gl_init_fbo(gl_t *gl, unsigned width, unsigned height);
|
||||
void gl_deinit_fbo(gl_t *gl);
|
||||
|
||||
bool gl_load_overlay(gl_t *gl, const char *path);
|
||||
void gl_set_overlay_tex_coord(gl_t *gl,
|
||||
GLfloat x, GLfloat y, // Relative coordinates [0, 1] range for screen.
|
||||
GLfloat w, GLfloat h);
|
||||
void gl_set_overlay_vertex_coord(gl_t *gl,
|
||||
GLfloat x, GLfloat y, // Relative coordinates [0, 1] range for screen.
|
||||
GLfloat w, GLfloat h);
|
||||
void gl_render_overlay(gl_t *gl);
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user