diff --git a/README.md b/README.md index f07dc310d..b3350460a 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ Other Unix-like platforms, such as OpenBSD, are known to work as well, but are u ### System requirements -Requirements are minimal. Any computer that can run Windows Vista or newer should be able to handle emulation. Support for OpenGL 1.1 or newer is also required. +Requirements are minimal. Any computer that can run Windows Vista or newer should be able to handle emulation. Support for OpenGL 1.1 or newer is also required, with OpenGL 3.0 or newer for shaders and advanced features. Downloads --------- diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 6ac96a50e..a59569b80 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -125,6 +125,12 @@ enum { GBA_GL_UNIFORM_MAX = 12 }; +struct GBAVideoGLShader { + GLuint program; + GLuint vao; + GLuint uniforms[GBA_GL_UNIFORM_MAX]; +}; + struct GBAVideoGLRenderer { struct GBAVideoRenderer d; @@ -136,6 +142,7 @@ struct GBAVideoGLRenderer { GLuint fbo[GBA_GL_FBO_MAX]; GLuint layers[GBA_GL_TEX_MAX]; + GLuint vbo; GLuint outputTex; @@ -148,15 +155,10 @@ struct GBAVideoGLRenderer { GLuint vramTex; unsigned vramDirty; - GLuint bgProgram[6]; - GLuint bgUniforms[6][GBA_GL_UNIFORM_MAX]; - GLuint objProgram[2]; - GLuint objUniforms[2][GBA_GL_UNIFORM_MAX]; - - GLuint compositeProgram; - GLuint compositeUniforms[GBA_GL_UNIFORM_MAX]; - GLuint finalizeProgram; - GLuint finalizeUniforms[GBA_GL_UNIFORM_MAX]; + struct GBAVideoGLShader bgShader[6]; + struct GBAVideoGLShader objShader[2]; + struct GBAVideoGLShader compositeShader; + struct GBAVideoGLShader finalizeShader; GBARegisterDISPCNT dispcnt; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index bdd065cb8..1bfc1683e 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -399,7 +399,10 @@ void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer) { renderer->scale = 1; } -void _compileShader(struct GBAVideoGLRenderer* glRenderer, GLuint program, const char** shaderBuffer, int shaderBufferLines, GLuint vs, char* log) { +void _compileShader(struct GBAVideoGLRenderer* glRenderer, struct GBAVideoGLShader* shader, const char** shaderBuffer, int shaderBufferLines, GLuint vs, const struct GBAVideoGLUniform* uniforms, char* log) { + GLuint program = glCreateProgram(); + shader->program = program; + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); glAttachShader(program, vs); glAttachShader(program, fs); @@ -419,6 +422,18 @@ void _compileShader(struct GBAVideoGLRenderer* glRenderer, GLuint program, const glBindFragDataLocation(program, 0, "color"); glBindFragDataLocation(program, 1, "flags"); #endif + + glGenVertexArrays(1, &shader->vao); + glBindVertexArray(shader->vao); + glBindBuffer(GL_ARRAY_BUFFER, glRenderer->vbo); + GLuint positionLocation = glGetAttribLocation(program, "position"); + glVertexAttribPointer(positionLocation, 2, GL_INT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(positionLocation); + + size_t i; + for (i = 0; uniforms[i].name; ++i) { + shader->uniforms[uniforms[i].type] = glGetUniformLocation(program, uniforms[i].name); + } } static void _initFramebufferTexture(GLuint tex, GLenum format, GLenum attachment, int scale) { @@ -431,13 +446,6 @@ static void _initFramebufferTexture(GLuint tex, GLenum format, GLenum attachment glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, tex, 0); } -static void _lookupUniforms(GLuint program, GLuint* out, const struct GBAVideoGLUniform* uniforms) { - size_t i; - for (i = 0; uniforms[i].name; ++i) { - out[uniforms[i].type] = glGetUniformLocation(program, uniforms[i].name); - } -} - void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; glGenFramebuffers(GBA_GL_FBO_MAX, glRenderer->fbo); @@ -472,6 +480,10 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glBindFramebuffer(GL_FRAMEBUFFER, 0); + glGenBuffers(1, &glRenderer->vbo); + glBindBuffer(GL_ARRAY_BUFFER, glRenderer->vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(_vertices), _vertices, GL_STATIC_DRAW); + int i; for (i = 0; i < 4; ++i) { struct GBAVideoGLBackground* bg = &glRenderer->bg[i]; @@ -505,17 +517,6 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glBindFramebuffer(GL_FRAMEBUFFER, 0); } - glRenderer->compositeProgram = glCreateProgram(); - glRenderer->finalizeProgram = glCreateProgram(); - glRenderer->objProgram[0] = glCreateProgram(); - glRenderer->objProgram[1] = glCreateProgram(); - glRenderer->bgProgram[0] = glCreateProgram(); - glRenderer->bgProgram[1] = glCreateProgram(); - glRenderer->bgProgram[2] = glCreateProgram(); - glRenderer->bgProgram[3] = glCreateProgram(); - glRenderer->bgProgram[4] = glCreateProgram(); - glRenderer->bgProgram[5] = glCreateProgram(); - char log[1024]; const GLchar* shaderBuffer[8]; shaderBuffer[0] = _gl3Header; @@ -532,51 +533,44 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { shaderBuffer[1] = _renderMode0; shaderBuffer[2] = _renderTile16; - _compileShader(glRenderer, glRenderer->bgProgram[0], shaderBuffer, 3, vs, log); - _lookupUniforms(glRenderer->bgProgram[0], glRenderer->bgUniforms[0], _uniformsMode0); + _compileShader(glRenderer, &glRenderer->bgShader[0], shaderBuffer, 3, vs, _uniformsMode0, log); shaderBuffer[2] = _renderTile256; - _compileShader(glRenderer, glRenderer->bgProgram[1], shaderBuffer, 3, vs, log); - _lookupUniforms(glRenderer->bgProgram[1], glRenderer->bgUniforms[1], _uniformsMode0); + _compileShader(glRenderer, &glRenderer->bgShader[1], shaderBuffer, 3, vs, _uniformsMode0, log); shaderBuffer[1] = _renderMode2; shaderBuffer[2] = _fetchTileOverflow; - _compileShader(glRenderer, glRenderer->bgProgram[2], shaderBuffer, 3, vs, log); - _lookupUniforms(glRenderer->bgProgram[2], glRenderer->bgUniforms[2], _uniformsMode2); + _compileShader(glRenderer, &glRenderer->bgShader[2], shaderBuffer, 3, vs, _uniformsMode2, log); shaderBuffer[2] = _fetchTileNoOverflow; - _compileShader(glRenderer, glRenderer->bgProgram[3], shaderBuffer, 3, vs, log); - _lookupUniforms(glRenderer->bgProgram[3], glRenderer->bgUniforms[3], _uniformsMode2); + _compileShader(glRenderer, &glRenderer->bgShader[3], shaderBuffer, 3, vs, _uniformsMode2, log); shaderBuffer[1] = _renderObj; shaderBuffer[2] = _renderTile16; - _compileShader(glRenderer, glRenderer->objProgram[0], shaderBuffer, 3, vs, log); - _lookupUniforms(glRenderer->objProgram[0], glRenderer->objUniforms[0], _uniformsObj); + _compileShader(glRenderer, &glRenderer->objShader[0], shaderBuffer, 3, vs, _uniformsObj, log); #ifndef BUILD_GLES3 - glBindFragDataLocation(glRenderer->objProgram[0], 2, "window"); + glBindFragDataLocation(glRenderer->objShader[0].program, 2, "window"); #endif shaderBuffer[2] = _renderTile256; - _compileShader(glRenderer, glRenderer->objProgram[1], shaderBuffer, 3, vs, log); - _lookupUniforms(glRenderer->objProgram[1], glRenderer->objUniforms[1], _uniformsObj); + _compileShader(glRenderer, &glRenderer->objShader[1], shaderBuffer, 3, vs, _uniformsObj, log); #ifndef BUILD_GLES3 - glBindFragDataLocation(glRenderer->objProgram[1], 2, "window"); + glBindFragDataLocation(glRenderer->objShader[1].program, 2, "window"); #endif shaderBuffer[1] = _composite; - _compileShader(glRenderer, glRenderer->compositeProgram, shaderBuffer, 2, vs, log); - _lookupUniforms(glRenderer->compositeProgram, glRenderer->compositeUniforms, _uniformsComposite); + _compileShader(glRenderer, &glRenderer->compositeShader, shaderBuffer, 2, vs, _uniformsComposite, log); #ifndef BUILD_GLES3 - glBindFragDataLocation(glRenderer->compositeProgram, 2, "oldColor"); - glBindFragDataLocation(glRenderer->compositeProgram, 3, "oldFlags"); + glBindFragDataLocation(glRenderer->compositeShader.program, 2, "oldColor"); + glBindFragDataLocation(glRenderer->compositeShader.program, 3, "oldFlags"); #endif shaderBuffer[1] = _finalize; - _compileShader(glRenderer, glRenderer->finalizeProgram, shaderBuffer, 2, vs, log); - _lookupUniforms(glRenderer->finalizeProgram, glRenderer->finalizeUniforms, _uniformsFinalize); + _compileShader(glRenderer, &glRenderer->finalizeShader, shaderBuffer, 2, vs, _uniformsFinalize, log); + glBindVertexArray(0); glDeleteShader(vs); GBAVideoGLRendererReset(renderer); @@ -588,16 +582,6 @@ void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { glDeleteTextures(GBA_GL_TEX_MAX, glRenderer->layers); glDeleteTextures(1, &glRenderer->paletteTex); glDeleteTextures(1, &glRenderer->vramTex); - - glDeleteProgram(glRenderer->bgProgram[0]); - glDeleteProgram(glRenderer->bgProgram[1]); - glDeleteProgram(glRenderer->bgProgram[2]); - glDeleteProgram(glRenderer->bgProgram[3]); - glDeleteProgram(glRenderer->bgProgram[4]); - glDeleteProgram(glRenderer->bgProgram[5]); - glDeleteProgram(glRenderer->objProgram[0]); - glDeleteProgram(glRenderer->objProgram[1]); - glDeleteProgram(glRenderer->compositeProgram); } void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { @@ -1075,11 +1059,12 @@ static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLu if ((y & 0x1F) != 0x1F) { return; } - const GLuint* uniforms = renderer->compositeUniforms; + const GLuint* uniforms = renderer->compositeShader.uniforms; glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_COMPOSITE]); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, (y & ~0x1F) * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, 0x20 * renderer->scale); - glUseProgram(renderer->compositeProgram); + glUseProgram(renderer->compositeShader.program); + glBindVertexArray(renderer->compositeShader.vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); glActiveTexture(GL_TEXTURE0 + 1); @@ -1102,23 +1087,21 @@ static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLu glUniform1i(uniforms[GBA_GL_COMPOSITE_OLDLAYERFLAGS], 3); glUniform1i(uniforms[GBA_GL_COMPOSITE_OLDOLDFLAGS], 4); glUniform1i(uniforms[GBA_GL_COMPOSITE_WINDOW], 5); - glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); - glEnableVertexAttribArray(0); glDrawBuffers(4, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); - glBindFramebuffer(GL_FRAMEBUFFER, 0); } void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y) { if ((y & 0x1F) != 0x1F) { return; } - const GLuint* uniforms = renderer->finalizeUniforms; + const GLuint* uniforms = renderer->finalizeShader.uniforms; glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OUTPUT]); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, (y & ~0x1F) * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, 0x20 * renderer->scale); - glUseProgram(renderer->finalizeProgram); + glUseProgram(renderer->finalizeShader.program); + glBindVertexArray(renderer->finalizeShader.vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_COLOR]); glActiveTexture(GL_TEXTURE0 + 1); @@ -1134,8 +1117,6 @@ void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y) { glUniform1i(uniforms[GBA_GL_FINALIZE_LAYERFLAGS], 1); glUniform1i(uniforms[GBA_GL_FINALIZE_OLDLAYER], 2); glUniform1i(uniforms[GBA_GL_FINALIZE_OLDFLAGS], 3); - glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); - glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -1167,11 +1148,13 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB enum GBAVideoBlendEffect blendEffect = GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT ? BLEND_ALPHA : renderer->blendEffect; - const GLuint* uniforms = renderer->objUniforms[GBAObjAttributesAGet256Color(sprite->a)]; + const struct GBAVideoGLShader* shader = &renderer->objShader[GBAObjAttributesAGet256Color(sprite->a)]; + const GLuint* uniforms = shader->uniforms; glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OBJ]); glViewport(x * renderer->scale, spriteY * renderer->scale, totalWidth * renderer->scale, totalHeight * renderer->scale); glScissor(x * renderer->scale, y * renderer->scale, totalWidth * renderer->scale, renderer->scale); - glUseProgram(renderer->objProgram[GBAObjAttributesAGet256Color(sprite->a)]); + glUseProgram(shader->program); + glBindVertexArray(shader->vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); @@ -1198,8 +1181,6 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniformMatrix2fv(uniforms[GBA_GL_OBJ_TRANSFORM], 1, GL_FALSE, (GLfloat[]) { 1.f, 0, 0, 1.f }); } glUniform4i(uniforms[GBA_GL_OBJ_DIMS], width, height, totalWidth, totalHeight); - glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); - glEnableVertexAttribArray(0); if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_OBJWIN) { int window = ~renderer->objwin & 0xFF; glUniform3f(uniforms[GBA_GL_OBJ_OBJWIN], 1, (window & 0xF) / 32.f, (window >> 4) / 32.f); @@ -1220,11 +1201,14 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, } else if (background->size == 3) { yBase += (inY & 0x100) << 1; } - const GLuint* uniforms = renderer->bgUniforms[background->multipalette ? 1 : 0]; + + const struct GBAVideoGLShader* shader = &renderer->bgShader[background->multipalette ? 1 : 0]; + const GLuint* uniforms = shader->uniforms; glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, y * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale); - glUseProgram(renderer->bgProgram[background->multipalette ? 1 : 0]); + glUseProgram(shader->program); + glBindVertexArray(shader->vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); @@ -1240,8 +1224,6 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glUniform4i(uniforms[GBA_GL_BG_INFLAGS], (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), renderer->blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy, renderer->bldb); - glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); - glEnableVertexAttribArray(0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); @@ -1250,11 +1232,13 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, } void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { - const GLuint* uniforms = renderer->bgUniforms[background->overflow ? 2 : 3]; + const struct GBAVideoGLShader* shader = &renderer->bgShader[background->overflow ? 2 : 3]; + const GLuint* uniforms = shader->uniforms; glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, y * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale); - glUseProgram(renderer->bgProgram[background->overflow ? 2 : 3]); + glUseProgram(shader->program); + glBindVertexArray(shader->vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); @@ -1296,8 +1280,6 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, background->affine[0].dx, background->affine[0].dy, }); } - glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); - glEnableVertexAttribArray(0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index 94d0856ca..da09ecd60 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -84,6 +84,10 @@ static void mGLES2ContextInit(struct VideoBackend* v, WHandle handle) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glGenBuffers(1, &context->vbo); + glBindBuffer(GL_ARRAY_BUFFER, context->vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(_vertices), _vertices, GL_STATIC_DRAW); + glClearColor(0.f, 0.f, 0.f, 1.f); struct mGLES2Uniform* uniforms = malloc(sizeof(struct mGLES2Uniform) * 4); @@ -159,6 +163,7 @@ static void mGLES2ContextSetDimensions(struct VideoBackend* v, unsigned width, u static void mGLES2ContextDeinit(struct VideoBackend* v) { struct mGLES2Context* context = (struct mGLES2Context*) v; glDeleteTextures(1, &context->tex); + glDeleteBuffers(1, &context->vbo); mGLES2ShaderDeinit(&context->initialShader); mGLES2ShaderDeinit(&context->finalShader); free(context->initialShader.uniforms); @@ -239,8 +244,7 @@ void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) { glUseProgram(shader->program); glUniform1i(shader->texLocation, 0); glUniform2f(shader->texSizeLocation, context->d.width - padW, context->d.height - padH); - glVertexAttribPointer(shader->positionLocation, 2, GL_FLOAT, GL_FALSE, 0, _vertices); - glEnableVertexAttribArray(shader->positionLocation); + glBindVertexArray(shader->vao); size_t u; for (u = 0; u < shader->nUniforms; ++u) { struct mGLES2Uniform* uniform = &shader->uniforms[u]; @@ -420,6 +424,13 @@ void mGLES2ShaderInit(struct mGLES2Shader* shader, const char* vs, const char* f for (i = 0; i < shader->nUniforms; ++i) { shader->uniforms[i].location = glGetUniformLocation(shader->program, shader->uniforms[i].name); } + + glGenVertexArrays(1, &shader->vao); + glBindVertexArray(shader->vao); + glVertexAttribPointer(shader->positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(shader->positionLocation); + glBindVertexArray(0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -428,6 +439,7 @@ void mGLES2ShaderDeinit(struct mGLES2Shader* shader) { glDeleteShader(shader->fragmentShader); glDeleteProgram(shader->program); glDeleteFramebuffers(1, &shader->fbo); + glDeleteVertexArrays(1, &shader->vao); } void mGLES2ShaderAttach(struct mGLES2Context* context, struct mGLES2Shader* shaders, size_t nShaders) { @@ -443,7 +455,11 @@ void mGLES2ShaderAttach(struct mGLES2Context* context, struct mGLES2Shader* shad for (i = 0; i < nShaders; ++i) { glBindFramebuffer(GL_FRAMEBUFFER, context->shaders[i].fbo); glClear(GL_COLOR_BUFFER_BIT); + + glBindVertexArray(context->shaders[i].vao); + glBindBuffer(GL_ARRAY_BUFFER, context->vbo); } + glBindVertexArray(0); glBindFramebuffer(GL_FRAMEBUFFER, 0); } diff --git a/src/platform/opengl/gles2.h b/src/platform/opengl/gles2.h index f6d050bc9..59f3b7996 100644 --- a/src/platform/opengl/gles2.h +++ b/src/platform/opengl/gles2.h @@ -62,6 +62,7 @@ struct mGLES2Shader { bool blend; GLuint tex; GLuint fbo; + GLuint vao; GLuint fragmentShader; GLuint vertexShader; GLuint program; @@ -77,8 +78,7 @@ struct mGLES2Context { struct VideoBackend d; GLuint tex; - GLuint texLocation; - GLuint positionLocation; + GLuint vbo; struct mGLES2Shader initialShader; struct mGLES2Shader finalShader; diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 81d01f960..2405cbe07 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -227,7 +227,7 @@ PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent QStringList extensions = QString(reinterpret_cast(glGetString(GL_EXTENSIONS))).split(' '); #ifdef BUILD_GLES2 - if (extensions.contains("GL_ARB_framebuffer_object") && majorVersion >= 2) { + if ((majorVersion == 2 && extensions.contains("GL_ARB_framebuffer_object")) || majorVersion > 2) { gl2Backend = static_cast(malloc(sizeof(mGLES2Context))); mGLES2ContextCreate(gl2Backend); m_backend = &gl2Backend->d; @@ -500,8 +500,8 @@ void PainterGL::clearShaders() { if (!supportsShaders()) { return; } - if (!m_active) { #ifdef BUILD_GLES2 + if (!m_active) { m_gl->makeCurrent(m_surface); #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent();