diff --git a/README.md b/README.md index a1a2e9d..109e262 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ The exception is boost, which is weird in that it still hasn't managed to pull o ### Supported image/audio formats These depend on the SDL auxiliary libraries. For maximum RGSS compliance, build SDL2_image with png/jpg support, and SDL_sound with oggvorbis/wav/mp3 support. -To run mkxp, you should have a graphics card capable of at least **OpenGL 2.0** with an up-to-date driver installed. +To run mkxp, you should have a graphics card capable of at least **OpenGL (ES) 2.0** with an up-to-date driver installed. ## Configuration diff --git a/src/gl-fun.cpp b/src/gl-fun.cpp index be78249..46ddff3 100644 --- a/src/gl-fun.cpp +++ b/src/gl-fun.cpp @@ -82,11 +82,24 @@ void initGLFunctions() /* Determine GL version */ const char *ver = (const char*) gl.GetString(GL_VERSION); + const char *glesPrefix = "OpenGL ES "; + size_t glesPrefixN = strlen(glesPrefix); + + bool gles = false; + + if (!strncmp(ver, glesPrefix, glesPrefixN)) + { + gles = true; + gl.glsles = true; + + ver += glesPrefixN; + } + /* Assume single digit */ int glMajor = *ver - '0'; if (glMajor < 2) - throw EXC("At least OpenGL 2.0 is required"); + throw EXC("At least OpenGL (ES) 2.0 is required"); BoostSet ext; @@ -95,43 +108,53 @@ void initGLFunctions() else parseExtensionsCompat(gl.GetString, ext); - // FIXME: Set based on GL kind - gl.unpack_subimage = true; - gl.npot_repeat = true; - #define HAVE_EXT(_ext) ext.contains("GL_" #_ext) /* FBO entrypoints */ - if (!HAVE_EXT(ARB_framebuffer_object)) - { - if (!(HAVE_EXT(EXT_framebuffer_object) && HAVE_EXT(EXT_framebuffer_blit))) - throw EXC("No FBO extensions available"); - -#undef EXT_SUFFIX -#define EXT_SUFFIX "EXT" - GL_FBO_FUN; - } - else + if (glMajor >= 3 || HAVE_EXT(ARB_framebuffer_object)) { #undef EXT_SUFFIX #define EXT_SUFFIX "" GL_FBO_FUN; + GL_FBO_BLIT_FUN; + } + else if (gles && glMajor == 2) + { + GL_FBO_FUN; + } + else if (HAVE_EXT(EXT_framebuffer_object)) + { +#undef EXT_SUFFIX +#define EXT_SUFFIX "EXT" + GL_FBO_FUN; + + if (HAVE_EXT(EXT_framebuffer_blit)) + { + GL_FBO_BLIT_FUN; + } + } + else + { + throw EXC("No FBO support available"); } /* VAO entrypoints */ - if (!HAVE_EXT(ARB_vertex_array_object)) + if (HAVE_EXT(ARB_vertex_array_object) || glMajor >= 3) + { +#undef EXT_SUFFIX +#define EXT_SUFFIX "" + GL_VAO_FUN; + } + else if (HAVE_EXT(APPLE_vertex_array_object)) { - if (!HAVE_EXT(APPLE_vertex_array_object)) - throw EXC("No VAO extensions available"); - #undef EXT_SUFFIX #define EXT_SUFFIX "APPLE" GL_VAO_FUN; } - else + else if (HAVE_EXT(OES_vertex_array_object)) { #undef EXT_SUFFIX -#define EXT_SUFFIX "" +#define EXT_SUFFIX "OES" GL_VAO_FUN; } @@ -148,4 +171,11 @@ void initGLFunctions() #define EXT_SUFFIX "ARB" GL_DEBUG_KHR_FUN; } + + /* Misc caps */ + if (!gles || glMajor >= 3 || HAVE_EXT(EXT_unpack_subimage)) + gl.unpack_subimage = true; + + if (!gles || glMajor >= 3 || HAVE_EXT(OES_texture_npot)) + gl.npot_repeat = true; } diff --git a/src/gl-fun.h b/src/gl-fun.h index ab958c9..d1bb406 100644 --- a/src/gl-fun.h +++ b/src/gl-fun.h @@ -119,7 +119,9 @@ typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, co GL_FUN(DeleteFramebuffers, PFNGLDELETEFRAMEBUFFERSPROC) \ GL_FUN(BindFramebuffer, PFNGLBINDFRAMEBUFFERPROC) \ GL_FUN(FramebufferTexture2D, PFNGLFRAMEBUFFERTEXTURE2DPROC) \ - GL_FUN(FramebufferRenderbuffer, PFNGLFRAMEBUFFERRENDERBUFFERPROC) \ + GL_FUN(FramebufferRenderbuffer, PFNGLFRAMEBUFFERRENDERBUFFERPROC) + +#define GL_FBO_BLIT_FUN \ GL_FUN(BlitFramebuffer, PFNGLBLITFRAMEBUFFERPROC) #define GL_VAO_FUN \ @@ -138,9 +140,11 @@ struct GLFunctions GL_20_FUN GL_FBO_FUN + GL_FBO_BLIT_FUN GL_VAO_FUN GL_DEBUG_KHR_FUN + bool glsles; bool unpack_subimage; bool npot_repeat; diff --git a/src/shader.cpp b/src/shader.cpp index 2292780..428d0d7 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -25,6 +25,7 @@ #include "exception.h" #include +#include #include #include "../sprite.frag.xxd" @@ -107,6 +108,34 @@ void Shader::unbind() glState.program.set(0); } +static const char *glesHeader = "precision mediump float;\n"; +static const size_t glesHeaderSize = strlen(glesHeader); + +static void setupShaderSource(GLuint shader, + const unsigned char *src, int srcSize) +{ + GLuint shaderSrcN; + const GLchar *shaderSrc[2]; + GLint shaderSrcSize[2]; + + if (gl.glsles) + { + shaderSrcN = 2; + shaderSrc[0] = glesHeader; + shaderSrc[1] = (const GLchar*) src; + shaderSrcSize[0] = glesHeaderSize; + shaderSrcSize[1] = srcSize; + } + else + { + shaderSrcN = 1; + shaderSrc[0] = (const GLchar*) src; + shaderSrcSize[0] = srcSize; + } + + gl.ShaderSource(shader, shaderSrcN, shaderSrc, shaderSrcSize); +} + void Shader::init(const unsigned char *vert, int vertSize, const unsigned char *frag, int fragSize, const char *vertName, const char *fragName, @@ -115,7 +144,7 @@ void Shader::init(const unsigned char *vert, int vertSize, GLint success; /* Compile vertex shader */ - gl.ShaderSource(vertShader, 1, (const GLchar**) &vert, (const GLint*) &vertSize); + setupShaderSource(vertShader, vert, vertSize); gl.CompileShader(vertShader); gl.GetShaderiv(vertShader, GL_COMPILE_STATUS, &success); @@ -129,7 +158,7 @@ void Shader::init(const unsigned char *vert, int vertSize, } /* Compile fragment shader */ - gl.ShaderSource(fragShader, 1, (const GLchar**) &frag, (const GLint*) &fragSize); + setupShaderSource(fragShader, frag, fragSize); gl.CompileShader(fragShader); gl.GetShaderiv(fragShader, GL_COMPILE_STATUS, &success);