mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-01-22 20:57:06 +00:00
[client] egl/downscale: implement filter switching
This commit is contained in:
parent
2c02e6c4a0
commit
f66486b0c7
@ -23,21 +23,43 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "common/array.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/option.h"
|
#include "common/option.h"
|
||||||
#include "cimgui.h"
|
#include "cimgui.h"
|
||||||
|
|
||||||
#include "basic.vert.h"
|
#include "basic.vert.h"
|
||||||
#include "downscale.frag.h"
|
#include "downscale.frag.h"
|
||||||
|
#include "downscale_lanczos2.frag.h"
|
||||||
|
#include "downscale_linear.frag.h"
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DOWNSCALE_NEAREST = 0,
|
||||||
|
DOWNSCALE_LINEAR,
|
||||||
|
DOWNSCALE_LANCZOS2,
|
||||||
|
}
|
||||||
|
DownscaleFilter;
|
||||||
|
|
||||||
|
#define DOWNSCALE_COUNT (DOWNSCALE_LANCZOS2 + 1)
|
||||||
|
|
||||||
|
const char *filterNames[DOWNSCALE_COUNT] = {
|
||||||
|
"Nearest pixel",
|
||||||
|
"Linear",
|
||||||
|
"Lanczos",
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct EGL_FilterDownscale
|
typedef struct EGL_FilterDownscale
|
||||||
{
|
{
|
||||||
EGL_Filter base;
|
EGL_Filter base;
|
||||||
|
|
||||||
EGL_Shader * shader;
|
|
||||||
bool enable;
|
bool enable;
|
||||||
EGL_Uniform uniform;
|
EGL_Shader * nearest;
|
||||||
|
EGL_Uniform uNearest;
|
||||||
|
EGL_Shader * linear;
|
||||||
|
EGL_Shader * lanczos2;
|
||||||
|
|
||||||
|
DownscaleFilter filter;
|
||||||
enum EGL_PixelFormat pixFmt;
|
enum EGL_PixelFormat pixFmt;
|
||||||
unsigned int width, height;
|
unsigned int width, height;
|
||||||
float pixelSize;
|
float pixelSize;
|
||||||
@ -45,7 +67,7 @@ typedef struct EGL_FilterDownscale
|
|||||||
bool prepared;
|
bool prepared;
|
||||||
|
|
||||||
EGL_Framebuffer * fb;
|
EGL_Framebuffer * fb;
|
||||||
GLuint sampler;
|
GLuint sampler[2];
|
||||||
}
|
}
|
||||||
EGL_FilterDownscale;
|
EGL_FilterDownscale;
|
||||||
|
|
||||||
@ -70,13 +92,13 @@ static bool egl_filterDownscaleInit(EGL_Filter ** filter)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!egl_shaderInit(&this->shader))
|
if (!egl_shaderInit(&this->nearest))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to initialize the shader");
|
DEBUG_ERROR("Failed to initialize the shader");
|
||||||
goto error_this;
|
goto error_this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!egl_shaderCompile(this->shader,
|
if (!egl_shaderCompile(this->nearest,
|
||||||
b_shader_basic_vert , b_shader_basic_vert_size,
|
b_shader_basic_vert , b_shader_basic_vert_size,
|
||||||
b_shader_downscale_frag, b_shader_downscale_frag_size)
|
b_shader_downscale_frag, b_shader_downscale_frag_size)
|
||||||
)
|
)
|
||||||
@ -85,9 +107,39 @@ static bool egl_filterDownscaleInit(EGL_Filter ** filter)
|
|||||||
goto error_shader;
|
goto error_shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->uniform.type = EGL_UNIFORM_TYPE_3F;
|
if (!egl_shaderInit(&this->linear))
|
||||||
this->uniform.location =
|
{
|
||||||
egl_shaderGetUniform(this->shader, "uConfig");
|
DEBUG_ERROR("Failed to initialize the shader");
|
||||||
|
goto error_this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!egl_shaderCompile(this->linear,
|
||||||
|
b_shader_basic_vert, b_shader_basic_vert_size,
|
||||||
|
b_shader_downscale_linear_frag, b_shader_downscale_linear_frag_size)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to compile the shader");
|
||||||
|
goto error_shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!egl_shaderInit(&this->lanczos2))
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to initialize the shader");
|
||||||
|
goto error_this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!egl_shaderCompile(this->lanczos2,
|
||||||
|
b_shader_basic_vert, b_shader_basic_vert_size,
|
||||||
|
b_shader_downscale_lanczos2_frag, b_shader_downscale_lanczos2_frag_size)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to compile the shader");
|
||||||
|
goto error_shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->uNearest.type = EGL_UNIFORM_TYPE_3F;
|
||||||
|
this->uNearest.location =
|
||||||
|
egl_shaderGetUniform(this->nearest, "uConfig");
|
||||||
|
|
||||||
if (!egl_framebufferInit(&this->fb))
|
if (!egl_framebufferInit(&this->fb))
|
||||||
{
|
{
|
||||||
@ -95,11 +147,15 @@ static bool egl_filterDownscaleInit(EGL_Filter ** filter)
|
|||||||
goto error_shader;
|
goto error_shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
glGenSamplers(1, &this->sampler);
|
glGenSamplers(ARRAY_LENGTH(this->sampler), this->sampler);
|
||||||
glSamplerParameteri(this->sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glSamplerParameteri(this->sampler[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glSamplerParameteri(this->sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glSamplerParameteri(this->sampler[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glSamplerParameteri(this->sampler, GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE);
|
glSamplerParameteri(this->sampler[0], GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE);
|
||||||
glSamplerParameteri(this->sampler, GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE);
|
glSamplerParameteri(this->sampler[0], GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE);
|
||||||
|
glSamplerParameteri(this->sampler[1], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glSamplerParameteri(this->sampler[1], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glSamplerParameteri(this->sampler[1], GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE);
|
||||||
|
glSamplerParameteri(this->sampler[1], GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
this->enable = false;
|
this->enable = false;
|
||||||
this->pixelSize = 2.0f;
|
this->pixelSize = 2.0f;
|
||||||
@ -110,7 +166,9 @@ static bool egl_filterDownscaleInit(EGL_Filter ** filter)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
error_shader:
|
error_shader:
|
||||||
egl_shaderFree(&this->shader);
|
egl_shaderFree(&this->nearest);
|
||||||
|
egl_shaderFree(&this->linear);
|
||||||
|
egl_shaderFree(&this->lanczos2);
|
||||||
|
|
||||||
error_this:
|
error_this:
|
||||||
free(this);
|
free(this);
|
||||||
@ -121,9 +179,11 @@ static void egl_filterDownscaleFree(EGL_Filter * filter)
|
|||||||
{
|
{
|
||||||
EGL_FilterDownscale * this = UPCAST(EGL_FilterDownscale, filter);
|
EGL_FilterDownscale * this = UPCAST(EGL_FilterDownscale, filter);
|
||||||
|
|
||||||
egl_shaderFree(&this->shader);
|
egl_shaderFree(&this->nearest);
|
||||||
|
egl_shaderFree(&this->linear);
|
||||||
|
egl_shaderFree(&this->lanczos2);
|
||||||
egl_framebufferFree(&this->fb);
|
egl_framebufferFree(&this->fb);
|
||||||
glDeleteSamplers(1, &this->sampler);
|
glDeleteSamplers(ARRAY_LENGTH(this->sampler), this->sampler);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,8 +201,24 @@ static bool egl_filterDownscaleImguiConfig(EGL_Filter * filter)
|
|||||||
redraw = true;
|
redraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (igBeginCombo("Filter", filterNames[this->filter], 0))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < DOWNSCALE_COUNT; ++i)
|
||||||
|
{
|
||||||
|
bool selected = i == this->filter;
|
||||||
|
if (igSelectableBool(filterNames[i], selected, 0, (ImVec2) { 0.0f, 0.0f }))
|
||||||
|
{
|
||||||
|
redraw = true;
|
||||||
|
this->filter = i;
|
||||||
|
}
|
||||||
|
if (selected)
|
||||||
|
igSetItemDefaultFocus();
|
||||||
|
}
|
||||||
|
igEndCombo();
|
||||||
|
}
|
||||||
|
|
||||||
int majorPixelSize = floor(this->pixelSize);
|
int majorPixelSize = floor(this->pixelSize);
|
||||||
int minorPixelSize = (this->pixelSize - majorPixelSize) * 10.0f;
|
int minorPixelSize = round((this->pixelSize - majorPixelSize) * 10.0f);
|
||||||
|
|
||||||
igSliderInt("Major Pixel Size", &majorPixelSize, 1, 10, NULL, 0);
|
igSliderInt("Major Pixel Size", &majorPixelSize, 1, 10, NULL, 0);
|
||||||
igSliderInt("Minor Pixel Size", &minorPixelSize, 0, 9, NULL, 0);
|
igSliderInt("Minor Pixel Size", &minorPixelSize, 0, 9, NULL, 0);
|
||||||
@ -156,6 +232,10 @@ static bool egl_filterDownscaleImguiConfig(EGL_Filter * filter)
|
|||||||
redraw = true;
|
redraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (this->filter)
|
||||||
|
{
|
||||||
|
case DOWNSCALE_NEAREST:
|
||||||
|
{
|
||||||
float vOffset = this->vOffset;
|
float vOffset = this->vOffset;
|
||||||
igSliderFloat("V-Offset", &vOffset, -2, 2, NULL, 0);
|
igSliderFloat("V-Offset", &vOffset, -2, 2, NULL, 0);
|
||||||
if (vOffset != this->vOffset)
|
if (vOffset != this->vOffset)
|
||||||
@ -171,6 +251,12 @@ static bool egl_filterDownscaleImguiConfig(EGL_Filter * filter)
|
|||||||
this->hOffset = hOffset;
|
this->hOffset = hOffset;
|
||||||
redraw = true;
|
redraw = true;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (redraw)
|
if (redraw)
|
||||||
this->prepared = false;
|
this->prepared = false;
|
||||||
@ -221,10 +307,18 @@ static bool egl_filterDownscalePrepare(EGL_Filter * filter)
|
|||||||
if (this->prepared)
|
if (this->prepared)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
this->uniform.f[0] = this->pixelSize;
|
switch (this->filter)
|
||||||
this->uniform.f[1] = this->vOffset;
|
{
|
||||||
this->uniform.f[2] = this->hOffset;
|
case DOWNSCALE_NEAREST:
|
||||||
egl_shaderSetUniforms(this->shader, &this->uniform, 1);
|
this->uNearest.f[0] = this->pixelSize;
|
||||||
|
this->uNearest.f[1] = this->vOffset;
|
||||||
|
this->uNearest.f[2] = this->hOffset;
|
||||||
|
egl_shaderSetUniforms(this->nearest, &this->uNearest, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
this->prepared = true;
|
this->prepared = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -239,9 +333,25 @@ static GLuint egl_filterDownscaleRun(EGL_Filter * filter, EGL_Model * model,
|
|||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, texture);
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
glBindSampler(0, this->sampler);
|
|
||||||
|
|
||||||
egl_shaderUse(this->shader);
|
switch (this->filter)
|
||||||
|
{
|
||||||
|
case DOWNSCALE_NEAREST:
|
||||||
|
glBindSampler(0, this->sampler[0]);
|
||||||
|
egl_shaderUse(this->nearest);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DOWNSCALE_LINEAR:
|
||||||
|
glBindSampler(0, this->sampler[1]);
|
||||||
|
egl_shaderUse(this->linear);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DOWNSCALE_LANCZOS2:
|
||||||
|
glBindSampler(0, this->sampler[0]);
|
||||||
|
egl_shaderUse(this->lanczos2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
egl_modelRender(model);
|
egl_modelRender(model);
|
||||||
|
|
||||||
return egl_framebufferGetTexture(this->fb);
|
return egl_framebufferGetTexture(this->fb);
|
||||||
|
Loading…
Reference in New Issue
Block a user