OpenGL: Add basic border rendering to modern GL driver

This commit is contained in:
Vicki Pfau 2023-02-22 23:36:57 -08:00
parent 09a53abe99
commit c7e4db58e3
2 changed files with 48 additions and 20 deletions

View File

@ -206,7 +206,10 @@ static void mGLES2ContextSetLayerDimensions(struct VideoBackend* v, enum VideoLa
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dims->width, dims->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dims->width, dims->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
#endif #endif
if (layer == VIDEO_LAYER_BACKGROUND) { unsigned newW;
unsigned newH;
VideoBackendGetFrameSize(v, &newW, &newH);
if (newW != context->width || newH != context->height) {
size_t n; size_t n;
for (n = 0; n < context->nShaders; ++n) { for (n = 0; n < context->nShaders; ++n) {
if (context->shaders[n].width < 0 || context->shaders[n].height < 0) { if (context->shaders[n].width < 0 || context->shaders[n].height < 0) {
@ -215,6 +218,8 @@ static void mGLES2ContextSetLayerDimensions(struct VideoBackend* v, enum VideoLa
} }
context->initialShader.dirty = true; context->initialShader.dirty = true;
context->interframeShader.dirty = true; context->interframeShader.dirty = true;
context->width = newW;
context->height = newH;
} }
} }
@ -241,9 +246,8 @@ static void mGLES2ContextResized(struct VideoBackend* v, unsigned w, unsigned h)
unsigned drawW = w; unsigned drawW = w;
unsigned drawH = h; unsigned drawH = h;
unsigned maxW; unsigned maxW = context->width;
unsigned maxH; unsigned maxH = context->height;
VideoBackendGetFrameSize(v, &maxW, &maxH);
if (v->lockAspectRatio) { if (v->lockAspectRatio) {
lockAspectRatioUInt(maxW, maxH, &drawW, &drawH); lockAspectRatioUInt(maxW, maxH, &drawW, &drawH);
@ -272,7 +276,7 @@ static void mGLES2ContextClear(struct VideoBackend* v) {
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
} }
void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) { static void _drawShaderEx(struct mGLES2Context* context, struct mGLES2Shader* shader, int layer) {
GLint viewport[4]; GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport); glGetIntegerv(GL_VIEWPORT, viewport);
int drawW = shader->width; int drawW = shader->width;
@ -283,19 +287,19 @@ void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) {
drawW = viewport[2]; drawW = viewport[2];
padW = viewport[0]; padW = viewport[0];
} else if (shader->width < 0) { } else if (shader->width < 0) {
drawW = context->layerDims[VIDEO_LAYER_IMAGE].width * -shader->width; drawW = context->width * -shader->width;
} }
if (!drawH) { if (!drawH) {
drawH = viewport[3]; drawH = viewport[3];
padH = viewport[1]; padH = viewport[1];
} else if (shader->height < 0) { } else if (shader->height < 0) {
drawH = context->layerDims[VIDEO_LAYER_IMAGE].height * -shader->height; drawH = context->height * -shader->height;
} }
if (shader->integerScaling) { if (shader->integerScaling) {
padW = 0; padW = 0;
padH = 0; padH = 0;
drawW -= drawW % context->layerDims[VIDEO_LAYER_IMAGE].width; drawW -= drawW % context->width;
drawH -= drawH % context->layerDims[VIDEO_LAYER_IMAGE].height; drawH -= drawH % context->height;
} }
if (shader->dirty) { if (shader->dirty) {
@ -309,22 +313,29 @@ void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) {
shader->dirty = false; shader->dirty = false;
} }
if (layer >= 0 && layer < VIDEO_LAYER_MAX) {
glViewport(context->layerDims[layer].x, context->layerDims[layer].y, context->layerDims[layer].width, context->layerDims[layer].height);
} else {
glViewport(padW, padH, drawW, drawH);
}
glBindFramebuffer(GL_FRAMEBUFFER, shader->fbo); glBindFramebuffer(GL_FRAMEBUFFER, shader->fbo);
glViewport(padW, padH, drawW, drawH);
if (shader->blend) { if (shader->blend) {
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
} else { } else {
glDisable(GL_BLEND); glDisable(GL_BLEND);
glClearColor(0.f, 0.f, 0.f, 1.f); if (layer <= VIDEO_LAYER_BACKGROUND) {
glClear(GL_COLOR_BUFFER_BIT); glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
}
} }
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, shader->filter ? GL_LINEAR : GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, shader->filter ? GL_LINEAR : GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shader->filter ? GL_LINEAR : GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shader->filter ? GL_LINEAR : GL_NEAREST);
glUseProgram(shader->program); glUseProgram(shader->program);
glUniform1i(shader->texLocation, 0); glUniform1i(shader->texLocation, 0);
glUniform2f(shader->texSizeLocation, context->layerDims[VIDEO_LAYER_IMAGE].width, context->layerDims[VIDEO_LAYER_IMAGE].height); glUniform2f(shader->texSizeLocation, context->width, context->height);
glUniform2f(shader->outputSizeLocation, drawW, drawH); glUniform2f(shader->outputSizeLocation, drawW, drawH);
#ifdef BUILD_GLES3 #ifdef BUILD_GLES3
if (shader->vao != (GLuint) -1) { if (shader->vao != (GLuint) -1) {
@ -391,21 +402,36 @@ void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) {
glBindTexture(GL_TEXTURE_2D, shader->tex); glBindTexture(GL_TEXTURE_2D, shader->tex);
} }
static void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) {
_drawShaderEx(context, shader, -1);
}
void mGLES2ContextDrawFrame(struct VideoBackend* v) { void mGLES2ContextDrawFrame(struct VideoBackend* v) {
struct mGLES2Context* context = (struct mGLES2Context*) v; struct mGLES2Context* context = (struct mGLES2Context*) v;
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, context->tex[VIDEO_LAYER_IMAGE]);
GLint viewport[4]; GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport); glGetIntegerv(GL_VIEWPORT, viewport);
context->finalShader.filter = v->filter; context->finalShader.filter = v->filter;
_drawShader(context, &context->initialShader);
if (v->interframeBlending) { int layer;
context->interframeShader.blend = true; for (layer = 0; layer <= VIDEO_LAYER_IMAGE; ++layer) {
glViewport(0, 0, viewport[2], viewport[3]); if (context->layerDims[layer].width < 1 || context->layerDims[layer].height < 1) {
_drawShader(context, &context->interframeShader); continue;
}
glBindTexture(GL_TEXTURE_2D, context->tex[layer]);
_drawShaderEx(context, &context->initialShader, layer);
if (layer != VIDEO_LAYER_IMAGE) {
continue;
}
if (v->interframeBlending) {
context->interframeShader.blend = true;
glViewport(0, 0, viewport[2], viewport[3]);
_drawShader(context, &context->interframeShader);
}
} }
size_t n; size_t n;
for (n = 0; n < context->nShaders; ++n) { for (n = 0; n < context->nShaders; ++n) {
glViewport(0, 0, viewport[2], viewport[3]); glViewport(0, 0, viewport[2], viewport[3]);
@ -416,7 +442,7 @@ void mGLES2ContextDrawFrame(struct VideoBackend* v) {
if (v->interframeBlending) { if (v->interframeBlending) {
context->interframeShader.blend = false; context->interframeShader.blend = false;
glBindTexture(GL_TEXTURE_2D, context->tex[VIDEO_LAYER_IMAGE]); glBindTexture(GL_TEXTURE_2D, context->tex[VIDEO_LAYER_IMAGE]);
_drawShader(context, &context->initialShader); _drawShaderEx(context, &context->initialShader, VIDEO_LAYER_IMAGE);
glViewport(0, 0, viewport[2], viewport[3]); glViewport(0, 0, viewport[2], viewport[3]);
_drawShader(context, &context->interframeShader); _drawShader(context, &context->interframeShader);
} }

View File

@ -83,6 +83,8 @@ struct mGLES2Context {
GLuint vbo; GLuint vbo;
struct Rectangle layerDims[VIDEO_LAYER_MAX]; struct Rectangle layerDims[VIDEO_LAYER_MAX];
unsigned width;
unsigned height;
struct mGLES2Shader initialShader; struct mGLES2Shader initialShader;
struct mGLES2Shader finalShader; struct mGLES2Shader finalShader;