mirror of https://github.com/mgba-emu/mgba.git
OpenGL: Use VAOs
This commit is contained in:
parent
4bd788f715
commit
ee6cd36402
|
@ -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
|
||||
---------
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -227,7 +227,7 @@ PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent
|
|||
QStringList extensions = QString(reinterpret_cast<const char*>(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<mGLES2Context*>(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();
|
||||
|
|
Loading…
Reference in New Issue