# HG changeset patch # User Mike Pavone # Date 1546233044 28800 # Node ID fa9ae059e4d32f851168c12cb9b610a019bcff04 # Parent 774096402918aebcb12be0d898bdc3cd4eb582ff Added support for GLES in addition to desktop GL diff -r 774096402918 -r fa9ae059e4d3 Makefile --- a/Makefile Sun Dec 30 19:40:32 2018 -0800 +++ b/Makefile Sun Dec 30 21:10:44 2018 -0800 @@ -31,23 +31,36 @@ NET:=net.o EXE:= +HAS_PROC:=$(shell if [ -d /proc ]; then /bin/echo -e -DHAS_PROC; fi) +CFLAGS:=-std=gnu99 -Wreturn-type -Werror=return-type -Werror=implicit-function-declaration -Wno-unused-value $(HAS_PROC) -DHAVE_UNISTD_H + ifeq ($(OS),Darwin) LIBS=sdl2 glew FONT:=nuklear_ui/font_mac.o else +ifdef USE_GLES +LIBS=sdl2 glesv2 +CFLAGS+= -DUSE_GLES +else LIBS=sdl2 glew gl +endif #USE_GLES FONT:=nuklear_ui/font.o endif #Darwin -HAS_PROC:=$(shell if [ -d /proc ]; then /bin/echo -e -DHAS_PROC; fi) -CFLAGS:=-std=gnu99 -Wreturn-type -Werror=return-type -Werror=implicit-function-declaration -Wno-unused-value $(HAS_PROC) -DHAVE_UNISTD_H ifeq ($(OS),Darwin) #This should really be based on whether or not the C compiler is clang rather than based on the OS CFLAGS+= -Wno-logical-op-parentheses endif ifdef PORTABLE +ifdef USE_GLES +ifndef GLES_LIB +GLES_LIB:=$(shell pkg-config --libs glesv2) +endif +LDFLAGS:=-lm $(GLES_LIB) +else CFLAGS+= -DGLEW_STATIC -Iglew/include LDFLAGS:=-lm glew/lib/libGLEW.a +endif ifeq ($(OS),Darwin) CFLAGS+= -IFrameworks/SDL2.framework/Headers @@ -55,7 +68,10 @@ FIXUP:=install_name_tool -change @rpath/SDL2.framework/Versions/A/SDL2 @executable_path/Frameworks/SDL2.framework/Versions/A/SDL2 else CFLAGS+= -Isdl/include -LDFLAGS+= -Wl,-rpath='$$ORIGIN/lib' -Llib -lSDL2 $(shell pkg-config --libs gl) +LDFLAGS+= -Wl,-rpath='$$ORIGIN/lib' -Llib -lSDL2 +ifndef USE_GLES +LDFLAGS+= $(shell pkg-config --libs gl) +endif endif #Darwin else diff -r 774096402918 -r fa9ae059e4d3 nuklear_ui/blastem_nuklear.c --- a/nuklear_ui/blastem_nuklear.c Sun Dec 30 19:40:32 2018 -0800 +++ b/nuklear_ui/blastem_nuklear.c Sun Dec 30 21:10:44 2018 -0800 @@ -1789,10 +1789,12 @@ void blastem_nuklear_render(void) { - nk_input_end(context); - current_view(context); - nk_sdl_render(NK_ANTI_ALIASING_ON, 512 * 1024, 128 * 1024); - nk_input_begin(context); + if (current_view != view_play) { + nk_input_end(context); + current_view(context); + nk_sdl_render(NK_ANTI_ALIASING_ON, 512 * 1024, 128 * 1024); + nk_input_begin(context); + } } void ui_idle_loop(void) @@ -1849,7 +1851,11 @@ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +#ifdef USE_GLES + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf); +#else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, buf); +#endif return nk_image_id((int)tex); } @@ -1929,6 +1935,14 @@ } ui_image *this_image = ui_images[num_ui_images-1] = calloc(1, sizeof(ui_image)); this_image->image_data = load_png(buf, buf_size, &this_image->width, &this_image->height); +#ifdef USE_GLES + uint32_t *cur = this_image->image_data; + for (int i = 0; i < this_image->width*this_image->height; i++, cur++) + { + uint32_t pixel = *cur; + *cur = (pixel & 0xFF00FF00) | (pixel << 16 & 0xFF0000) | (pixel >> 16 & 0xFF); + } +#endif free(buf); if (!this_image->image_data) { num_ui_images--; diff -r 774096402918 -r fa9ae059e4d3 nuklear_ui/nuklear_sdl_gles2.h --- a/nuklear_ui/nuklear_sdl_gles2.h Sun Dec 30 19:40:32 2018 -0800 +++ b/nuklear_ui/nuklear_sdl_gles2.h Sun Dec 30 21:10:44 2018 -0800 @@ -17,8 +17,12 @@ #include #ifndef DISABLE_OPENGL +#ifdef USE_GLES +#include +#else #include #endif +#endif NK_API struct nk_context* nk_sdl_init(SDL_Window *win); diff -r 774096402918 -r fa9ae059e4d3 render_sdl.c --- a/render_sdl.c Sun Dec 30 19:40:32 2018 -0800 +++ b/render_sdl.c Sun Dec 30 21:10:44 2018 -0800 @@ -19,8 +19,12 @@ #include "controller_info.h" #ifndef DISABLE_OPENGL +#ifdef USE_GLES +#include +#else #include #endif +#endif #define MAX_EVENT_POLL_PER_FRAME 2 @@ -437,7 +441,11 @@ uint32_t render_map_color(uint8_t r, uint8_t g, uint8_t b) { +#ifdef USE_GLES + return 255 << 24 | b << 16 | g << 8 | r; +#else return 255 << 24 | r << 16 | g << 8 | b; +#endif } #ifndef DISABLE_OPENGL @@ -454,6 +462,16 @@ static const GLushort element_data[] = {0, 1, 2, 3}; +static const GLchar shader_prefix[] = +#ifdef USE_GLES + "#version 100\n"; +#else + "#version 110\n" + "#define lowp\n" + "#define mediump\n" + "#define highp\n"; +#endif + static GLuint load_shader(char * fname, GLenum shader_type) { char const * parts[] = {get_home_dir(), "/.config/blastem/shaders/", fname}; @@ -478,6 +496,12 @@ free(text); return 0; } + if (strncmp(text, "#version", strlen("#version"))) { + GLchar *tmp = text; + text = alloc_concat(shader_prefix, tmp); + free(tmp); + fsize += strlen(shader_prefix); + } GLuint ret = glCreateShader(shader_type); glShaderSource(ret, 1, (const GLchar **)&text, (const GLint *)&fsize); free(text); @@ -499,6 +523,15 @@ static uint32_t texture_buf[512 * 513]; #ifndef DISABLE_OPENGL +#ifdef USE_GLES +#define INTERNAL_FORMAT GL_RGBA +#define SRC_FORMAT GL_RGBA +#define RENDER_FORMAT SDL_PIXELFORMAT_ABGR8888 +#else +#define INTERNAL_FORMAT GL_RGBA8 +#define SRC_FORMAT GL_BGRA +#define RENDER_FORMAT SDL_PIXELFORMAT_ARGB8888 +#endif static void gl_setup() { tern_val def = {.ptrval = "linear"}; @@ -514,10 +547,10 @@ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (i < 2) { //TODO: Fixme for PAL + invalid display mode - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 512, 0, GL_BGRA, GL_UNSIGNED_BYTE, texture_buf); + glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, 512, 512, 0, SRC_FORMAT, GL_UNSIGNED_BYTE, texture_buf); } else { uint32_t blank = 255 << 24; - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_BGRA, GL_UNSIGNED_BYTE, &blank); + glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, 1, 1, 0, SRC_FORMAT, GL_UNSIGNED_BYTE, &blank); } } glGenBuffers(2, buffers); @@ -575,7 +608,7 @@ char *scaling = tern_find_path_default(config, "video\0scaling\0", def, TVAL_PTR).ptrval; SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, scaling); //TODO: Fixme for invalid display mode - sdl_textures[0] = sdl_textures[1] = SDL_CreateTexture(main_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, LINEBUF_SIZE, 588); + sdl_textures[0] = sdl_textures[1] = SDL_CreateTexture(main_renderer, RENDER_FORMAT, SDL_TEXTUREACCESS_STREAMING, LINEBUF_SIZE, 588); #ifndef DISABLE_OPENGL } #endif @@ -1066,6 +1099,11 @@ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); +#ifdef USE_GLES + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); +#endif } #endif main_window = SDL_CreateWindow(caption, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, main_width, main_height, flags); @@ -1076,13 +1114,19 @@ if (gl_enabled) { main_context = SDL_GL_CreateContext(main_window); +#ifdef USE_GLES + int major_version; + if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major_version) == 0 && major_version >= 2) { +#else GLenum res = glewInit(); if (res != GLEW_OK) { warning("Initialization of GLEW failed with code %d\n", res); } if (res == GLEW_OK && GLEW_VERSION_2_0) { +#endif render_gl = 1; + SDL_GL_MakeCurrent(main_window, main_context); if (!strcmp("tear", vsync)) { if (SDL_GL_SetSwapInterval(-1) < 0) { warning("late tear is not available (%s), using normal vsync\n", SDL_GetError()); @@ -1111,6 +1155,9 @@ if (!main_renderer) { fatal_error("unable to create SDL renderer: %s\n", SDL_GetError()); } + SDL_RendererInfo rinfo; + SDL_GetRendererInfo(main_renderer, &rinfo); + printf("SDL2 Render Driver: %s\n", rinfo.name); main_clip.x = main_clip.y = 0; main_clip.w = main_width; main_clip.h = main_height; @@ -1484,7 +1531,7 @@ if (render_gl && which <= FRAMEBUFFER_EVEN) { SDL_GL_MakeCurrent(main_window, main_context); glBindTexture(GL_TEXTURE_2D, textures[which]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, LINEBUF_SIZE, height, GL_BGRA, GL_UNSIGNED_BYTE, texture_buf + overscan_left[video_standard] + LINEBUF_SIZE * overscan_top[video_standard]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, LINEBUF_SIZE, height, SRC_FORMAT, GL_UNSIGNED_BYTE, texture_buf + overscan_left[video_standard] + LINEBUF_SIZE * overscan_top[video_standard]); if (screenshot_file) { //properly supporting interlaced modes here is non-trivial, so only save the odd field for now diff -r 774096402918 -r fa9ae059e4d3 shaders/default.f.glsl --- a/shaders/default.f.glsl Sun Dec 30 19:40:32 2018 -0800 +++ b/shaders/default.f.glsl Sun Dec 30 21:10:44 2018 -0800 @@ -1,13 +1,12 @@ -#version 110 uniform sampler2D textures[2]; -varying vec2 texcoord; +varying mediump vec2 texcoord; void main() { - vec2 modifiedCoord0 = vec2(texcoord.x, (floor(texcoord.y * 512.0 + 0.25) + 0.5)/512.0); - vec2 modifiedCoord1 = vec2(texcoord.x, (floor(texcoord.y * 512.0 - 0.25) + 0.5)/512.0); + mediump vec2 modifiedCoord0 = vec2(texcoord.x, (floor(texcoord.y * 512.0 + 0.25) + 0.5)/512.0); + mediump vec2 modifiedCoord1 = vec2(texcoord.x, (floor(texcoord.y * 512.0 - 0.25) + 0.5)/512.0); gl_FragColor = mix( texture2D(textures[1], modifiedCoord1), texture2D(textures[0], modifiedCoord0), diff -r 774096402918 -r fa9ae059e4d3 shaders/default.v.glsl --- a/shaders/default.v.glsl Sun Dec 30 19:40:32 2018 -0800 +++ b/shaders/default.v.glsl Sun Dec 30 21:10:44 2018 -0800 @@ -1,11 +1,10 @@ -#version 110 attribute vec2 pos; -varying vec2 texcoord; -uniform float width, height; +varying mediump vec2 texcoord; +uniform mediump float width, height; void main() { gl_Position = vec4(pos, 0.0, 1.0); - texcoord = sign(pos) * vec2(width/1024.0, height/-1024.0) + vec2(width/1024.0, height/1024.0); + texcoord = sign(pos) * vec2(width / 1024.0, height / -1024.0) + vec2(width / 1024.0, height / 1024.0); }