From 1eabde6b555c04961c329c5370fc6cd7e88e4f65 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Sun, 23 Feb 2020 17:56:36 +0100 Subject: [PATCH] GL3: Make GLES3 work on Raspberry Pi 4B (older Raspberry Pi versions don't support OpenGL ES 3.0, only 2.0) --- src/client/refresh/gl3/gl3_image.c | 14 +++++--------- src/client/refresh/gl3/gl3_main.c | 7 +++++-- src/client/refresh/gl3/gl3_misc.c | 17 +++++++++++++---- src/client/refresh/gl3/gl3_sdl.c | 10 +++++++++- src/client/refresh/gl3/header/local.h | 7 ++++--- src/client/vid/glimp_sdl.c | 1 + 6 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/client/refresh/gl3/gl3_image.c b/src/client/refresh/gl3/gl3_image.c index 00b9a505..4e462498 100644 --- a/src/client/refresh/gl3/gl3_image.c +++ b/src/client/refresh/gl3/gl3_image.c @@ -191,15 +191,11 @@ GL3_Upload32(unsigned *data, int width, int height, qboolean mipmap) { qboolean res; - int samples; - int i, c; - byte *scan; - int comp; - - c = width * height; - scan = ((byte *)data) + 3; - samples = gl3_solid_format; - comp = gl3_tex_solid_format; + int i; + int c = width * height; + byte *scan = ((byte *)data) + 3; + int comp = gl3_tex_solid_format; + int samples = gl3_solid_format; for (i = 0; i < c; i++, scan += 4) { diff --git a/src/client/refresh/gl3/gl3_main.c b/src/client/refresh/gl3/gl3_main.c index 23e91cfa..41849ade 100644 --- a/src/client/refresh/gl3/gl3_main.c +++ b/src/client/refresh/gl3/gl3_main.c @@ -35,8 +35,11 @@ #define DG_DYNARR_IMPLEMENTATION #include "header/DG_dynarr.h" - -#define REF_VERSION "Yamagi Quake II OpenGL3 Refresher" +#ifdef YQ2_GL3_GLES3 + #define REF_VERSION "Yamagi Quake II OpenGL ES3 Refresher" +#else + #define REF_VERSION "Yamagi Quake II OpenGL3 Refresher" +#endif refimport_t ri; diff --git a/src/client/refresh/gl3/gl3_misc.c b/src/client/refresh/gl3/gl3_misc.c index 468f6532..1fb24fef 100644 --- a/src/client/refresh/gl3/gl3_misc.c +++ b/src/client/refresh/gl3/gl3_misc.c @@ -125,7 +125,16 @@ void GL3_ScreenShot(void) { int w=vid.width, h=vid.height; - byte *buffer = malloc(w*h*3); + +#ifdef YQ2_GL3_GLES + // My RPi4's GLES3 doesn't like GL_RGB, so use GL_RGBA with GLES + // TODO: we could convert the screenshot to RGB before writing + // so the resulting file is smaller + static const int comps = 4; +#else // Desktop GL + static const int comps = 3; +#endif + byte *buffer = malloc(w*h*comps); if (!buffer) { @@ -134,13 +143,13 @@ GL3_ScreenShot(void) } glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, buffer); + glReadPixels(0, 0, w, h, (comps == 4) ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, buffer); // the pixels are now row-wise left to right, bottom to top, // but we need them row-wise left to right, top to bottom. // so swap bottom rows with top rows { - size_t bytesPerRow = 3*w; + size_t bytesPerRow = comps*w; YQ2_VLA(byte, rowBuffer, bytesPerRow); byte *curRowL = buffer; // first byte of first row byte *curRowH = buffer + bytesPerRow*(h-1); // first byte of last row @@ -156,7 +165,7 @@ GL3_ScreenShot(void) YQ2_VLAFREE(rowBuffer); } - ri.Vid_WriteScreenshot(w, h, 3, buffer); + ri.Vid_WriteScreenshot(w, h, comps, buffer); free(buffer); } diff --git a/src/client/refresh/gl3/gl3_sdl.c b/src/client/refresh/gl3/gl3_sdl.c index 46b45a9e..10cafd04 100644 --- a/src/client/refresh/gl3/gl3_sdl.c +++ b/src/client/refresh/gl3/gl3_sdl.c @@ -236,7 +236,11 @@ int GL3_PrepareForWindow(void) #endif // Set GL context flags. - int contextFlags = SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG; + int contextFlags = 0; + +#ifndef YQ2_GL3_GLES // Desktop GL (at least RPi4 doesn't like this for GLES3) + contextFlags |= SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG; +#endif if (gl3_debugcontext && gl3_debugcontext->value) { @@ -347,7 +351,11 @@ int GL3_InitContext(void* win) return false; } +#ifdef YQ2_GL3_GLES3 + else if (GLVersion.major < 3) +#else // Desktop GL else if (GLVersion.major < 3 || (GLVersion.major == 3 && GLVersion.minor < 2)) +#endif { R_Printf(PRINT_ALL, "GL3_InitContext(): ERROR: glad only got GL version %d.%d!\n", GLVersion.major, GLVersion.minor); diff --git a/src/client/refresh/gl3/header/local.h b/src/client/refresh/gl3/header/local.h index 6f7b27af..45d0e503 100644 --- a/src/client/refresh/gl3/header/local.h +++ b/src/client/refresh/gl3/header/local.h @@ -94,10 +94,11 @@ enum { GL3_ATTRIB_LIGHTFLAGS = 5 // uint, each set bit means "dyn light i affects this surface" }; -// TODO: do we need the following configurable? -static const int gl3_solid_format = GL_RGB; +// always using RGBA now, GLES3 on RPi4 doesn't work otherwise +// and I think all modern GPUs prefer 4byte pixels over 3bytes +static const int gl3_solid_format = GL_RGBA; static const int gl3_alpha_format = GL_RGBA; -static const int gl3_tex_solid_format = GL_RGB; +static const int gl3_tex_solid_format = GL_RGBA; static const int gl3_tex_alpha_format = GL_RGBA; extern unsigned gl3_rawpalette[256]; diff --git a/src/client/vid/glimp_sdl.c b/src/client/vid/glimp_sdl.c index bc70d551..8650f1cb 100755 --- a/src/client/vid/glimp_sdl.c +++ b/src/client/vid/glimp_sdl.c @@ -217,6 +217,7 @@ CreateSDLWindow(int flags, int w, int h) } else { + Com_Printf("Creating window failed: %s\n", SDL_GetError()); return false; }