1
0
mirror of https://github.com/libretro/RetroArch synced 2025-02-24 09:40:07 +00:00

gl1: fix order of non-rgui menu drawing, add proper texture support

This commit is contained in:
Brad Parker 2019-02-11 12:05:31 -05:00
parent 17f90a3624
commit 5a3a58c8a6
5 changed files with 192 additions and 80 deletions
configuration.c
gfx
common
drivers
drivers_font
menu/drivers_display

@ -2485,7 +2485,7 @@ static bool check_menu_driver_compatibility(void)
string_is_equal(video_driver, "d3d12") ||
string_is_equal(video_driver, "gdi") ||
string_is_equal(video_driver, "gl") ||
/*string_is_equal(video_driver, "gl1") ||*/
string_is_equal(video_driver, "gl1") ||
string_is_equal(video_driver, "gx2") ||
string_is_equal(video_driver, "vulkan") ||
string_is_equal(video_driver, "metal") ||

@ -35,6 +35,10 @@
#include "../video_driver.h"
#define RARCH_GL1_INTERNAL_FORMAT32 GL_RGBA8
#define RARCH_GL1_TEXTURE_TYPE32 GL_BGRA_EXT
#define RARCH_GL1_FORMAT32 GL_UNSIGNED_BYTE
struct string_list;
typedef struct gl1
@ -73,17 +77,6 @@ typedef struct gl1
void *readback_buffer_screenshot;
} gl1_t;
typedef struct gl1_texture
{
int width;
int height;
int active_width;
int active_height;
enum texture_filter_type type;
void* data;
} gl1_texture_t;
static INLINE void gl1_bind_texture(GLuint id, GLint wrap_mode, GLint mag_filter,
GLint min_filter)
{

@ -46,6 +46,10 @@
#include "../common/win32_common.h"
#endif
#ifdef HAVE_THREADS
#include "../video_thread_wrapper.h"
#endif
static unsigned char *gl1_menu_frame = NULL;
static unsigned gl1_menu_width = 0;
static unsigned gl1_menu_height = 0;
@ -249,6 +253,7 @@ static void *gl1_gfx_init(const video_info_t *video,
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glDisable(GL_STENCIL_TEST);
glDisable(GL_SCISSOR_TEST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@ -408,6 +413,7 @@ static void draw_tex(gl1_t *gl1, int pot_width, int pot_height, int width, int h
GLenum type = GL_UNSIGNED_BYTE;
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glDisable(GL_STENCIL_TEST);
glDisable(GL_SCISSOR_TEST);
glEnable(GL_TEXTURE_2D);
@ -562,10 +568,11 @@ static bool gl1_gfx_frame(void *data, const void *frame,
gl1_gfx_set_viewport(gl1, video_info, video_info->width, video_info->height, false, true);
}
#ifdef HAVE_MENU
if (gl1->menu_texture_enable)
menu_driver_frame(video_info);
#endif
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if ( gl1_video_width != frame_width ||
gl1_video_height != frame_height ||
@ -644,13 +651,12 @@ static bool gl1_gfx_frame(void *data, const void *frame,
gl1->screen_width = mode.width;
gl1->screen_height = mode.height;
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
if (draw)
{
if (frame_to_copy)
{
draw_tex(gl1, pot_width, pot_height, width, height, gl1->tex, frame_to_copy);
}
}
if (gl1_menu_frame && video_info->menu_is_alive)
@ -699,8 +705,6 @@ static bool gl1_gfx_frame(void *data, const void *frame,
frame_to_copy = gl1_menu_video_buf;
glEnable(GL_BLEND);
if (gl1->menu_texture_full_screen)
{
glViewport(0, 0, video_info->width, video_info->height);
@ -709,11 +713,14 @@ static bool gl1_gfx_frame(void *data, const void *frame,
}
else
draw_tex(gl1, pot_width, pot_height, width, height, gl1->menu_tex, frame_to_copy);
glDisable(GL_BLEND);
}
}
#ifdef HAVE_MENU
if (gl1->menu_texture_enable)
menu_driver_frame(video_info);
#endif
if (msg)
font_driver_render_msg(video_info, NULL, msg, NULL);
@ -1044,41 +1051,143 @@ static void gl1_set_video_mode(void *data, unsigned width, unsigned height,
video_context_driver_set_video_mode(&mode);
}
static unsigned gl1_wrap_type_to_enum(enum gfx_wrap_type type)
{
switch (type)
{
case RARCH_WRAP_REPEAT:
case RARCH_WRAP_MIRRORED_REPEAT: /* mirrored not actually supported */
return GL_REPEAT;
default:
return GL_CLAMP;
break;
}
return 0;
}
static void gl1_load_texture_data(
GLuint id,
enum gfx_wrap_type wrap_type,
enum texture_filter_type filter_type,
unsigned alignment,
unsigned width, unsigned height,
const void *frame, unsigned base_size)
{
GLint mag_filter, min_filter;
bool use_rgba = video_driver_supports_rgba();
bool rgb32 = (base_size == (sizeof(uint32_t)));
GLenum wrap = gl1_wrap_type_to_enum(wrap_type);
/* Assume no mipmapping support. */
switch (filter_type)
{
case TEXTURE_FILTER_MIPMAP_LINEAR:
filter_type = TEXTURE_FILTER_LINEAR;
break;
case TEXTURE_FILTER_MIPMAP_NEAREST:
filter_type = TEXTURE_FILTER_NEAREST;
break;
default:
break;
}
switch (filter_type)
{
case TEXTURE_FILTER_MIPMAP_LINEAR:
min_filter = GL_LINEAR_MIPMAP_NEAREST;
mag_filter = GL_LINEAR;
break;
case TEXTURE_FILTER_MIPMAP_NEAREST:
min_filter = GL_NEAREST_MIPMAP_NEAREST;
mag_filter = GL_NEAREST;
break;
case TEXTURE_FILTER_NEAREST:
min_filter = GL_NEAREST;
mag_filter = GL_NEAREST;
break;
case TEXTURE_FILTER_LINEAR:
default:
min_filter = GL_LINEAR;
mag_filter = GL_LINEAR;
break;
}
gl1_bind_texture(id, wrap, mag_filter, min_filter);
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
glTexImage2D(GL_TEXTURE_2D,
0,
(use_rgba || !rgb32) ? GL_RGBA : RARCH_GL1_INTERNAL_FORMAT32,
width, height, 0,
(use_rgba || !rgb32) ? GL_RGBA : RARCH_GL1_TEXTURE_TYPE32,
(rgb32) ? RARCH_GL1_FORMAT32 : GL_UNSIGNED_BYTE, frame);
}
static void video_texture_load_gl1(
struct texture_image *ti,
enum texture_filter_type filter_type,
uintptr_t *id)
{
/* Generate the OpenGL texture object */
glGenTextures(1, (GLuint*)id);
gl1_load_texture_data((GLuint)*id,
RARCH_WRAP_EDGE, filter_type,
4 /* TODO/FIXME - dehardcode */,
ti->width, ti->height, ti->pixels,
sizeof(uint32_t) /* TODO/FIXME - dehardcode */
);
}
#ifdef HAVE_THREADS
static int video_texture_load_wrap_gl1_mipmap(void *data)
{
uintptr_t id = 0;
if (!data)
return 0;
video_texture_load_gl1((struct texture_image*)data,
TEXTURE_FILTER_MIPMAP_LINEAR, &id);
return (int)id;
}
static int video_texture_load_wrap_gl1(void *data)
{
uintptr_t id = 0;
if (!data)
return 0;
video_texture_load_gl1((struct texture_image*)data,
TEXTURE_FILTER_LINEAR, &id);
return (int)id;
}
#endif
static uintptr_t gl1_load_texture(void *video_data, void *data,
bool threaded, enum texture_filter_type filter_type)
{
void *tmpdata = NULL;
gl1_texture_t *texture = NULL;
struct texture_image *image = (struct texture_image*)data;
int size = image->width *
image->height * sizeof(uint32_t);
uintptr_t id = 0;
if (!image || image->width > 2048 || image->height > 2048)
return 0;
texture = (gl1_texture_t*)calloc(1, sizeof(*texture));
if (!texture)
return 0;
texture->width = image->width;
texture->height = image->height;
texture->active_width = image->width;
texture->active_height = image->height;
texture->data = calloc(1,
texture->width * texture->height * sizeof(uint32_t));
texture->type = filter_type;
if (!texture->data)
#ifdef HAVE_THREADS
if (threaded)
{
free(texture);
return 0;
custom_command_method_t func = video_texture_load_wrap_gl1;
switch (filter_type)
{
case TEXTURE_FILTER_MIPMAP_LINEAR:
case TEXTURE_FILTER_MIPMAP_NEAREST:
func = video_texture_load_wrap_gl1_mipmap;
break;
default:
break;
}
return video_thread_texture_load(data, func);
}
#endif
memcpy(texture->data, image->pixels,
texture->width * texture->height * sizeof(uint32_t));
return (uintptr_t)texture;
video_texture_load_gl1((struct texture_image*)data, filter_type, &id);
return id;
}
static void gl1_set_aspect_ratio(void *data, unsigned aspect_ratio_idx)
@ -1113,17 +1222,14 @@ static void gl1_set_aspect_ratio(void *data, unsigned aspect_ratio_idx)
gl1->should_resize = true;
}
static void gl1_unload_texture(void *data, uintptr_t handle)
static void gl1_unload_texture(void *data, uintptr_t id)
{
struct gl1_texture *texture = (struct gl1_texture*)handle;
if (!texture)
GLuint glid;
if (!id)
return;
if (texture->data)
free(texture->data);
free(texture);
glid = (GLuint)id;
glDeleteTextures(1, &glid);
}
static float gl1_get_refresh_rate(void *data)
@ -1155,10 +1261,37 @@ static uint32_t gl1_get_flags(void *data)
return flags;
}
static void gl1_set_mvp(void *data, void *shader_data, const void *mat_data)
{
(void)data;
(void)shader_data;
const math_matrix_4x4 *mat = (const math_matrix_4x4*)mat_data;
if (!mat)
return;
glLoadMatrixf(mat->data);
}
static void gl1_set_coords(void *handle_data, void *shader_data,
const struct video_coords *coords)
{
gl1_t *gl1 = (gl1_t*)handle_data;
if (!gl1)
return;
gl1->coords.vertex = coords->vertex;
gl1->coords.color = coords->color;
gl1->coords.tex_coord = coords->tex_coord;
gl1->coords.lut_tex_coord = coords->lut_tex_coord;
}
static const video_poke_interface_t gl1_poke_interface = {
gl1_get_flags,
NULL, /* set_coords */
NULL, /* set_mvp */
gl1_set_coords,
gl1_set_mvp,
gl1_load_texture,
gl1_unload_texture,
gl1_set_video_mode,
@ -1205,21 +1338,6 @@ bool gl1_has_menu_frame(void)
return (gl1_menu_frame != NULL);
}
static unsigned gl1_wrap_type_to_enum(enum gfx_wrap_type type)
{
switch (type)
{
case RARCH_WRAP_REPEAT:
case RARCH_WRAP_MIRRORED_REPEAT: /* mirrored not actually supported */
return GL_REPEAT;
default:
return GL_CLAMP;
break;
}
return 0;
}
video_driver_t video_gl1 = {
gl1_gfx_init,
gl1_gfx_frame,

@ -1,7 +1,7 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
* Copyright (C) 2016-2017 - Brad Parker
* Copyright (C) 2016-2019 - Brad Parker
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-

@ -1,5 +1,6 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2011-2017 - Daniel De Matteis
* Copyright (C) 2016-2019 - Brad Parker
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
@ -116,6 +117,7 @@ static void menu_display_gl1_draw(menu_display_ctx_draw_t *draw,
menu_display_gl1_viewport(draw, video_info);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, (GLuint)draw->texture);
coords.handle_data = gl1;
@ -127,11 +129,10 @@ static void menu_display_gl1_draw(menu_display_ctx_draw_t *draw,
mvp.matrix = draw->matrix_data ? (math_matrix_4x4*)draw->matrix_data
: (math_matrix_4x4*)menu_display_gl1_get_default_mvp(video_info);
video_driver_set_mvp(&mvp);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadMatrixf(((math_matrix_4x4*)mvp.matrix)->data);
video_driver_set_mvp(&mvp);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();