mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-02-16 20:15:38 +00:00
Updated the GLSL shader logic and added a postprocessing function.
This commit is contained in:
parent
9da16dd00e
commit
fd10aba815
|
@ -70,7 +70,7 @@ namespace Renderer
|
||||||
LOG(LogInfo) << "Creating window...";
|
LOG(LogInfo) << "Creating window...";
|
||||||
|
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||||
LOG(LogError) << "Error initializing SDL!\n " << SDL_GetError();
|
LOG(LogError) << "Couldn't initialize SDL: " << SDL_GetError() << ".";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,17 +167,25 @@ namespace Renderer
|
||||||
#if defined(USE_OPENGL_21)
|
#if defined(USE_OPENGL_21)
|
||||||
LOG(LogInfo) << "Loading shaders...";
|
LOG(LogInfo) << "Loading shaders...";
|
||||||
|
|
||||||
Shader* desaturateShader = new Shader();
|
std::vector<std::string> shaderFiles;
|
||||||
|
shaderFiles.push_back(":/shaders/glsl/desaturate.glsl");
|
||||||
|
shaderFiles.push_back(":/shaders/glsl/blur_horizontal.glsl");
|
||||||
|
shaderFiles.push_back(":/shaders/glsl/blur_vertical.glsl");
|
||||||
|
shaderFiles.push_back(":/shaders/glsl/scanlines.glsl");
|
||||||
|
|
||||||
desaturateShader->loadShaderFile(":/shaders/glsl/desaturate.glsl", GL_VERTEX_SHADER);
|
for (auto it = shaderFiles.cbegin(); it != shaderFiles.cend(); it++) {
|
||||||
desaturateShader->loadShaderFile(":/shaders/glsl/desaturate.glsl", GL_FRAGMENT_SHADER);
|
Shader* loadShader = new Shader();
|
||||||
|
|
||||||
if (!desaturateShader->createProgram()) {
|
loadShader->loadShaderFile(*it, GL_VERTEX_SHADER);
|
||||||
|
loadShader->loadShaderFile(*it, GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
|
if (!loadShader->createProgram()) {
|
||||||
LOG(LogError) << "Could not create shader program.";
|
LOG(LogError) << "Could not create shader program.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sShaderProgramVector.push_back(desaturateShader);
|
sShaderProgramVector.push_back(loadShader);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -373,10 +381,19 @@ namespace Renderer
|
||||||
return red << 24 | green << 16 | blue << 8 | alpha;
|
return red << 24 | green << 16 | blue << 8 | alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader* getShaderProgram(unsigned int index)
|
Shader* getShaderProgram(unsigned int shaderID)
|
||||||
{
|
{
|
||||||
if (sShaderProgramVector.size() > index)
|
unsigned int index = 0;
|
||||||
return sShaderProgramVector[index];
|
|
||||||
|
// Find the index in sShaderProgramVector by counting the number
|
||||||
|
// of shifts required to reach 0.
|
||||||
|
while (shaderID > 0) {
|
||||||
|
shaderID = shaderID >> 1;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sShaderProgramVector.size() > index-1)
|
||||||
|
return sShaderProgramVector[index-1];
|
||||||
else
|
else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,27 @@ struct SDL_Window;
|
||||||
|
|
||||||
namespace Renderer
|
namespace Renderer
|
||||||
{
|
{
|
||||||
|
const unsigned int SHADER_DESATURATE = 1;
|
||||||
|
const unsigned int SHADER_BLUR_HORIZONTAL = 2;
|
||||||
|
const unsigned int SHADER_BLUR_VERTICAL = 4;
|
||||||
|
const unsigned int SHADER_SCANLINES = 8;
|
||||||
|
|
||||||
|
struct shaderParameters {
|
||||||
|
std::array<GLfloat, 2> textureSize;
|
||||||
|
std::array<GLfloat, 4> textureCoordinates;
|
||||||
|
float fragmentSaturation;
|
||||||
|
unsigned int shaderPasses;
|
||||||
|
|
||||||
|
shaderParameters()
|
||||||
|
: textureSize({0.0, 0.0}),
|
||||||
|
textureCoordinates({0.0, 0.0, 0.0, 0.0}),
|
||||||
|
fragmentSaturation(1.0),
|
||||||
|
shaderPasses(1)
|
||||||
|
{};
|
||||||
|
};
|
||||||
|
|
||||||
static std::vector<Shader*> sShaderProgramVector;
|
static std::vector<Shader*> sShaderProgramVector;
|
||||||
|
static GLuint shaderFBO;
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
#define GL_CHECK_ERROR(Function) (Function, _GLCheckError(#Function))
|
#define GL_CHECK_ERROR(Function) (Function, _GLCheckError(#Function))
|
||||||
|
@ -99,6 +119,7 @@ namespace Renderer
|
||||||
Vector2f tex;
|
Vector2f tex;
|
||||||
unsigned int col;
|
unsigned int col;
|
||||||
float saturation = 1.0;
|
float saturation = 1.0;
|
||||||
|
unsigned int shaders = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool init();
|
bool init();
|
||||||
|
@ -127,7 +148,10 @@ namespace Renderer
|
||||||
unsigned int rgbaToABGR(unsigned int color);
|
unsigned int rgbaToABGR(unsigned int color);
|
||||||
unsigned int abgrToRGBA(unsigned int color);
|
unsigned int abgrToRGBA(unsigned int color);
|
||||||
|
|
||||||
Shader* getShaderProgram(unsigned int index);
|
Shader* getShaderProgram(unsigned int shaderID);
|
||||||
|
void shaderPostprocessing(unsigned int shaders,
|
||||||
|
const Renderer::shaderParameters& parameters = shaderParameters(),
|
||||||
|
unsigned char* textureRGBA = nullptr);
|
||||||
|
|
||||||
// API specific.
|
// API specific.
|
||||||
unsigned int convertColor(const unsigned int _color);
|
unsigned int convertColor(const unsigned int _color);
|
||||||
|
@ -161,7 +185,8 @@ namespace Renderer
|
||||||
const Vertex* _vertices,
|
const Vertex* _vertices,
|
||||||
const unsigned int _numVertices,
|
const unsigned int _numVertices,
|
||||||
const Blend::Factor _srcBlendFactor = Blend::SRC_ALPHA,
|
const Blend::Factor _srcBlendFactor = Blend::SRC_ALPHA,
|
||||||
const Blend::Factor _dstBlendFactor = Blend::ONE_MINUS_SRC_ALPHA);
|
const Blend::Factor _dstBlendFactor = Blend::ONE_MINUS_SRC_ALPHA,
|
||||||
|
const shaderParameters& parameters = shaderParameters());
|
||||||
void setProjection(const Transform4x4f& _projection);
|
void setProjection(const Transform4x4f& _projection);
|
||||||
void setMatrix(const Transform4x4f& _matrix);
|
void setMatrix(const Transform4x4f& _matrix);
|
||||||
void setViewport(const Rect& _viewport);
|
void setViewport(const Rect& _viewport);
|
||||||
|
|
|
@ -127,6 +127,13 @@ namespace Renderer
|
||||||
else {
|
else {
|
||||||
LOG(LogInfo) << "GL_ARB_fragment_shader: OK";
|
LOG(LogInfo) << "GL_ARB_fragment_shader: OK";
|
||||||
}
|
}
|
||||||
|
if (extensions.find("GL_EXT_framebuffer_blit") == std::string::npos) {
|
||||||
|
LOG(LogError) << "GL_EXT_framebuffer_blit: MISSING";
|
||||||
|
missingExtension = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG(LogInfo) << "GL_EXT_framebuffer_blit: OK";
|
||||||
|
}
|
||||||
if (missingExtension) {
|
if (missingExtension) {
|
||||||
LOG(LogError) << "Required OpenGL extensions missing.";
|
LOG(LogError) << "Required OpenGL extensions missing.";
|
||||||
return false;
|
return false;
|
||||||
|
@ -144,11 +151,15 @@ namespace Renderer
|
||||||
GL_CHECK_ERROR(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
GL_CHECK_ERROR(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||||
GL_CHECK_ERROR(glEnableClientState(GL_COLOR_ARRAY));
|
GL_CHECK_ERROR(glEnableClientState(GL_COLOR_ARRAY));
|
||||||
|
|
||||||
|
// This is the framebuffer that will be used for shader rendering.
|
||||||
|
GL_CHECK_ERROR(glGenFramebuffers(1, &shaderFBO));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroyContext()
|
void destroyContext()
|
||||||
{
|
{
|
||||||
|
GL_CHECK_ERROR(glDeleteFramebuffers(1, &shaderFBO));
|
||||||
SDL_GL_DeleteContext(sdlContext);
|
SDL_GL_DeleteContext(sdlContext);
|
||||||
sdlContext = nullptr;
|
sdlContext = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -225,28 +236,17 @@ namespace Renderer
|
||||||
convertBlendFactor(_dstBlendFactor)));
|
convertBlendFactor(_dstBlendFactor)));
|
||||||
|
|
||||||
GL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, _numVertices));
|
GL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, _numVertices));
|
||||||
|
|
||||||
// If saturation is set below the maximum (default) value, run the desaturation shader.
|
|
||||||
if (_vertices->saturation < 1.0) {
|
|
||||||
Shader* desaturateShader = getShaderProgram(Shader::Desaturate);
|
|
||||||
|
|
||||||
// Only try to use the shader if it has been loaded properly.
|
|
||||||
if (desaturateShader) {
|
|
||||||
desaturateShader->activateShaders();
|
|
||||||
desaturateShader->getVariableLocations(desaturateShader->getProgramID());
|
|
||||||
desaturateShader->setVariable(_vertices->saturation);
|
|
||||||
GL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, _numVertices));
|
|
||||||
desaturateShader->deactivateShaders();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawTriangleStrips(
|
void drawTriangleStrips(
|
||||||
const Vertex* _vertices,
|
const Vertex* _vertices,
|
||||||
const unsigned int _numVertices,
|
const unsigned int _numVertices,
|
||||||
const Blend::Factor _srcBlendFactor,
|
const Blend::Factor _srcBlendFactor,
|
||||||
const Blend::Factor _dstBlendFactor)
|
const Blend::Factor _dstBlendFactor,
|
||||||
|
const shaderParameters& parameters)
|
||||||
{
|
{
|
||||||
|
float width = _vertices[3].pos[0];
|
||||||
|
float height = _vertices[3].pos[1];
|
||||||
GL_CHECK_ERROR(glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &_vertices[0].pos));
|
GL_CHECK_ERROR(glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &_vertices[0].pos));
|
||||||
GL_CHECK_ERROR(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &_vertices[0].tex));
|
GL_CHECK_ERROR(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &_vertices[0].tex));
|
||||||
GL_CHECK_ERROR(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &_vertices[0].col));
|
GL_CHECK_ERROR(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &_vertices[0].col));
|
||||||
|
@ -256,17 +256,56 @@ namespace Renderer
|
||||||
|
|
||||||
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, _numVertices));
|
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, _numVertices));
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < parameters.shaderPasses; i++) {
|
||||||
// If saturation is set below the maximum (default) value, run the desaturation shader.
|
// If saturation is set below the maximum (default) value, run the desaturation shader.
|
||||||
if (_vertices->saturation < 1.0) {
|
if (_vertices->saturation < 1.0 || parameters.fragmentSaturation < 1.0) {
|
||||||
Shader* desaturateShader = getShaderProgram(Shader::Desaturate);
|
Shader* runShader = getShaderProgram(SHADER_DESATURATE);
|
||||||
|
|
||||||
// Only try to use the shader if it has been loaded properly.
|
// Only try to use the shader if it has been loaded properly.
|
||||||
if (desaturateShader) {
|
if (runShader) {
|
||||||
desaturateShader->activateShaders();
|
runShader->activateShaders();
|
||||||
desaturateShader->getVariableLocations(desaturateShader->getProgramID());
|
runShader->getVariableLocations(runShader->getProgramID());
|
||||||
desaturateShader->setVariable(_vertices->saturation);
|
runShader->setSaturation(_vertices->saturation);
|
||||||
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, _numVertices));
|
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, _numVertices));
|
||||||
desaturateShader->deactivateShaders();
|
runShader->deactivateShaders();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if any other shaders are set to be used and if so, run them.
|
||||||
|
if (_vertices->shaders & SHADER_BLUR_HORIZONTAL) {
|
||||||
|
Shader* runShader = getShaderProgram(SHADER_BLUR_HORIZONTAL);
|
||||||
|
if (runShader) {
|
||||||
|
runShader->activateShaders();
|
||||||
|
runShader->getVariableLocations(runShader->getProgramID());
|
||||||
|
runShader->setTextureSize({width, height});
|
||||||
|
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, _numVertices));
|
||||||
|
runShader->deactivateShaders();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_vertices->shaders & SHADER_BLUR_VERTICAL) {
|
||||||
|
Shader* runShader = getShaderProgram(SHADER_BLUR_VERTICAL);
|
||||||
|
if (runShader) {
|
||||||
|
runShader->activateShaders();
|
||||||
|
runShader->getVariableLocations(runShader->getProgramID());
|
||||||
|
runShader->setTextureSize({width, height});
|
||||||
|
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, _numVertices));
|
||||||
|
runShader->deactivateShaders();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_vertices->shaders & SHADER_SCANLINES) {
|
||||||
|
Shader* runShader = getShaderProgram(SHADER_SCANLINES);
|
||||||
|
float shaderWidth = width * 1.2;
|
||||||
|
// Workaround to get the scanlines to render somehow proportional to the
|
||||||
|
// resolution. A better solution is for sure needed.
|
||||||
|
float shaderHeight = height + height / ((int)height >> 7) * 1.5;
|
||||||
|
if (runShader) {
|
||||||
|
runShader->activateShaders();
|
||||||
|
runShader->getVariableLocations(runShader->getProgramID());
|
||||||
|
runShader->setTextureSize({shaderWidth, shaderHeight});
|
||||||
|
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, _numVertices));
|
||||||
|
runShader->deactivateShaders();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -330,6 +369,81 @@ namespace Renderer
|
||||||
GL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
GL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void shaderPostprocessing(unsigned int shaders, const Renderer::shaderParameters& parameters,
|
||||||
|
unsigned char* textureRGBA)
|
||||||
|
{
|
||||||
|
Vertex vertices[4];
|
||||||
|
GLuint width = getScreenWidth();
|
||||||
|
GLuint height = getScreenHeight();
|
||||||
|
float widthf = static_cast<float>(width);
|
||||||
|
float heightf = static_cast<float>(height);
|
||||||
|
|
||||||
|
// Set vertex positions and texture coordinates to full screen as all
|
||||||
|
// postprocessing is applied to the complete screen area.
|
||||||
|
vertices[0] = { { 0, 0 }, { 0, 1 }, 0 };
|
||||||
|
vertices[1] = { { 0, heightf }, { 0, 0 }, 0 };
|
||||||
|
vertices[2] = { { widthf, 0 }, { 1, 1 }, 0 };
|
||||||
|
vertices[3] = { { widthf, heightf }, { 1, 0 }, 0};
|
||||||
|
|
||||||
|
vertices[0].shaders = shaders;
|
||||||
|
vertices[1].shaders = shaders;
|
||||||
|
vertices[2].shaders = shaders;
|
||||||
|
vertices[3].shaders = shaders;
|
||||||
|
|
||||||
|
if (parameters.fragmentSaturation < 1.0) {
|
||||||
|
vertices[0].saturation = parameters.fragmentSaturation;
|
||||||
|
vertices[1].saturation = parameters.fragmentSaturation;
|
||||||
|
vertices[2].saturation = parameters.fragmentSaturation;
|
||||||
|
vertices[3].saturation = parameters.fragmentSaturation;
|
||||||
|
}
|
||||||
|
|
||||||
|
setMatrix(Transform4x4f::Identity());
|
||||||
|
|
||||||
|
// The following method to apply the shaders is not optimal as it requires
|
||||||
|
// glBlitFramebuffer() to run twice. However, this function seems to be
|
||||||
|
// very fast so maybe it's not a practical issue.
|
||||||
|
GLuint screenTexture = createTexture(Texture::RGBA, false, false, width, height, nullptr);
|
||||||
|
|
||||||
|
GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0));
|
||||||
|
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, shaderFBO));
|
||||||
|
|
||||||
|
// Attach the texture to the shader framebuffer.
|
||||||
|
GL_CHECK_ERROR(glFramebufferTexture2D(
|
||||||
|
GL_FRAMEBUFFER,
|
||||||
|
GL_COLOR_ATTACHMENT0,
|
||||||
|
GL_TEXTURE_2D,
|
||||||
|
screenTexture,
|
||||||
|
0));
|
||||||
|
|
||||||
|
// Blit the screen contents to screenTexture.
|
||||||
|
GL_CHECK_ERROR(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_NEAREST));
|
||||||
|
|
||||||
|
// Apply/render the shaders.
|
||||||
|
drawTriangleStrips(vertices, 4, Blend::SRC_ALPHA, Blend::ONE_MINUS_SRC_ALPHA, parameters);
|
||||||
|
|
||||||
|
// If textureRGBA has an address, it means that the output should go to this texture
|
||||||
|
// rather than to the screen. The glReadPixels() function is slow, but since this would
|
||||||
|
// typically only run every now and then to create a cached screen texture, it doesn't
|
||||||
|
// really matter.
|
||||||
|
if (textureRGBA) {
|
||||||
|
GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, shaderFBO));
|
||||||
|
GL_CHECK_ERROR(glReadPixels(0, 0, width, height,
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE, textureRGBA));
|
||||||
|
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Blit the resulting postprocessed texture back to the primary framebuffer.
|
||||||
|
GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, shaderFBO));
|
||||||
|
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
|
||||||
|
GL_CHECK_ERROR(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_NEAREST));
|
||||||
|
}
|
||||||
|
|
||||||
|
GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0));
|
||||||
|
destroyTexture(screenTexture);
|
||||||
|
}
|
||||||
|
|
||||||
} // Renderer::
|
} // Renderer::
|
||||||
|
|
||||||
#endif // USE_OPENGL_21
|
#endif // USE_OPENGL_21
|
||||||
|
|
|
@ -16,12 +16,10 @@ namespace Renderer
|
||||||
{
|
{
|
||||||
Renderer::Shader::Shader()
|
Renderer::Shader::Shader()
|
||||||
: mProgramID(-1),
|
: mProgramID(-1),
|
||||||
shaderFloat_0(-1),
|
shaderTextureSize(-1),
|
||||||
shaderFloat_1(-1),
|
shaderTextureCoord(-1),
|
||||||
shaderFloat_2(-1),
|
shaderColor(-1),
|
||||||
shaderVec4_0(-1),
|
shaderSaturation(-1)
|
||||||
shaderVec4_1(-1),
|
|
||||||
shaderVec4_2(-1)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +40,7 @@ namespace Renderer
|
||||||
// Define the GLSL version (version 120 = OpenGL 2.1).
|
// Define the GLSL version (version 120 = OpenGL 2.1).
|
||||||
preprocessorDefines = "#version 120\n";
|
preprocessorDefines = "#version 120\n";
|
||||||
|
|
||||||
// Define the preprocessor macros that will let the shader compiler know whether
|
// Define the preprocessor constants that will let the shader compiler know whether
|
||||||
// the VERTEX or FRAGMENT portion of the code should be used.
|
// the VERTEX or FRAGMENT portion of the code should be used.
|
||||||
if (shaderType == GL_VERTEX_SHADER)
|
if (shaderType == GL_VERTEX_SHADER)
|
||||||
preprocessorDefines += "#define VERTEX\n";
|
preprocessorDefines += "#define VERTEX\n";
|
||||||
|
@ -73,7 +71,7 @@ namespace Renderer
|
||||||
if (shaderCompiled != GL_TRUE) {
|
if (shaderCompiled != GL_TRUE) {
|
||||||
LOG(LogError) << "OpenGL error: Unable to compile shader " <<
|
LOG(LogError) << "OpenGL error: Unable to compile shader " <<
|
||||||
currentShader << " (" << std::get<0>(*it) << ").";
|
currentShader << " (" << std::get<0>(*it) << ").";
|
||||||
printShaderInfoLog(currentShader);
|
printShaderInfoLog(currentShader, std::get<2>(*it));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,47 +97,34 @@ namespace Renderer
|
||||||
|
|
||||||
void Renderer::Shader::getVariableLocations(GLuint programID)
|
void Renderer::Shader::getVariableLocations(GLuint programID)
|
||||||
{
|
{
|
||||||
shaderFloat_0 = glGetUniformLocation(mProgramID, "shaderFloat_0");
|
// Some of the variable names are chosen to be compatible with the RetroArch GLSL shaders.
|
||||||
shaderFloat_1 = glGetUniformLocation(mProgramID, "shaderFloat_1");
|
shaderTextureSize = glGetUniformLocation(mProgramID, "TextureSize");
|
||||||
shaderFloat_2 = glGetUniformLocation(mProgramID, "shaderFloat_2");
|
shaderTextureCoord = glGetAttribLocation(mProgramID, "TexCoord");
|
||||||
shaderVec4_0 = glGetUniformLocation(mProgramID, "shaderVec4_0");
|
shaderColor = glGetAttribLocation(mProgramID, "COLOR");
|
||||||
shaderVec4_1 = glGetUniformLocation(mProgramID, "shaderVec4_1");
|
shaderSaturation = glGetUniformLocation(mProgramID, "saturation");
|
||||||
shaderVec4_2 = glGetUniformLocation(mProgramID, "shaderVec4_2");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Shader::setVariable(GLfloat shaderFloat, int index)
|
void Renderer::Shader::setTextureSize(std::array<GLfloat, 2> shaderVec2)
|
||||||
{
|
{
|
||||||
switch (index) {
|
GL_CHECK_ERROR(glUniform2f(shaderTextureSize, shaderVec2[0], shaderVec2[1]));
|
||||||
case 0:
|
|
||||||
GL_CHECK_ERROR(glUniform1f(shaderFloat_0, shaderFloat));
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
GL_CHECK_ERROR(glUniform1f(shaderFloat_1, shaderFloat));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
GL_CHECK_ERROR(glUniform1f(shaderFloat_2, shaderFloat));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Shader::setVariable(std::array<GLfloat, 4> shaderVec4, int index)
|
void Renderer::Shader::setTextureCoordinates(std::array<GLfloat, 4> shaderVec4)
|
||||||
{
|
{
|
||||||
switch (index) {
|
glEnableVertexAttribArray(shaderTextureCoord);
|
||||||
case 0:
|
glVertexAttribPointer(shaderTextureCoord, 4, GL_FLOAT, GL_FALSE, 0,
|
||||||
GL_CHECK_ERROR(glUniform4f(shaderVec4_0, shaderVec4[0],
|
(const GLvoid*)(uintptr_t)&shaderVec4);
|
||||||
shaderVec4[1], shaderVec4[2], shaderVec4[3]));
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
GL_CHECK_ERROR(glUniform4f(shaderVec4_1, shaderVec4[0],
|
|
||||||
shaderVec4[1], shaderVec4[2], shaderVec4[3]));
|
|
||||||
case 2:
|
|
||||||
GL_CHECK_ERROR(glUniform4f(shaderVec4_2, shaderVec4[0],
|
|
||||||
shaderVec4[1], shaderVec4[2], shaderVec4[3]));
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::Shader::setColor(std::array<GLfloat, 4> shaderVec4)
|
||||||
|
{
|
||||||
|
GL_CHECK_ERROR(glUniform4f(shaderColor, shaderVec4[0],
|
||||||
|
shaderVec4[1], shaderVec4[2], shaderVec4[3]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::Shader::setSaturation(GLfloat saturation)
|
||||||
|
{
|
||||||
|
GL_CHECK_ERROR(glUniform1f(shaderSaturation, saturation));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Shader::activateShaders()
|
void Renderer::Shader::activateShaders()
|
||||||
|
@ -178,7 +163,7 @@ namespace Renderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Shader::printShaderInfoLog(GLuint shaderID)
|
void Renderer::Shader::printShaderInfoLog(GLuint shaderID, GLenum shaderType)
|
||||||
{
|
{
|
||||||
if (glIsShader(shaderID)) {
|
if (glIsShader(shaderID)) {
|
||||||
int logLength;
|
int logLength;
|
||||||
|
@ -190,8 +175,9 @@ namespace Renderer
|
||||||
glGetShaderInfoLog(shaderID, maxLength, &logLength, &infoLog.front());
|
glGetShaderInfoLog(shaderID, maxLength, &logLength, &infoLog.front());
|
||||||
|
|
||||||
if (logLength > 0) {
|
if (logLength > 0) {
|
||||||
LOG(LogDebug) << "Renderer_GL21::printShaderLog():\n" <<
|
LOG(LogDebug) << "Renderer_GL21::printShaderLog(): Error in " <<
|
||||||
std::string(infoLog.begin(), infoLog.end());
|
(shaderType == GL_VERTEX_SHADER ? "VERTEX section:\n" :
|
||||||
|
"FRAGMENT section:\n") << std::string(infoLog.begin(), infoLog.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -20,10 +20,6 @@ namespace Renderer
|
||||||
class Shader
|
class Shader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum shaderNames {
|
|
||||||
Desaturate
|
|
||||||
};
|
|
||||||
|
|
||||||
Shader();
|
Shader();
|
||||||
~Shader();
|
~Shader();
|
||||||
|
|
||||||
|
@ -36,8 +32,10 @@ namespace Renderer
|
||||||
// Get references to the variables inside the compiled shaders.
|
// Get references to the variables inside the compiled shaders.
|
||||||
void getVariableLocations(GLuint programID);
|
void getVariableLocations(GLuint programID);
|
||||||
// One-way communication with the compiled shaders.
|
// One-way communication with the compiled shaders.
|
||||||
void setVariable(GLfloat shaderFloat, int index = 0);
|
void setTextureSize(std::array<GLfloat, 2> shaderVec2);
|
||||||
void setVariable(std::array<GLfloat, 4> shaderVec4, int index = 0);
|
void setTextureCoordinates(std::array<GLfloat, 4> shaderVec4);
|
||||||
|
void setColor(std::array<GLfloat, 4> shaderVec4);
|
||||||
|
void setSaturation(GLfloat saturation);
|
||||||
// Sets the shader program to use the loaded shaders.
|
// Sets the shader program to use the loaded shaders.
|
||||||
void activateShaders();
|
void activateShaders();
|
||||||
// Sets the shader program to 0 which reverts to the fixed function pipeline.
|
// Sets the shader program to 0 which reverts to the fixed function pipeline.
|
||||||
|
@ -46,20 +44,19 @@ namespace Renderer
|
||||||
GLuint getProgramID();
|
GLuint getProgramID();
|
||||||
// Only used for error logging if the shaders fail to compile or link.
|
// Only used for error logging if the shaders fail to compile or link.
|
||||||
void printProgramInfoLog(GLuint programID);
|
void printProgramInfoLog(GLuint programID);
|
||||||
void printShaderInfoLog(GLuint shaderID);
|
void printShaderInfoLog(GLuint shaderID, GLenum shaderType);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLuint mProgramID;
|
GLuint mProgramID;
|
||||||
std::vector<std::tuple<std::string, std::string, GLenum>> shaderVector;
|
std::vector<std::tuple<std::string, std::string, GLenum>> shaderVector;
|
||||||
|
|
||||||
// Variables used for communication with the compiled shaders.
|
// Variables used for communication with the compiled shaders.
|
||||||
GLint shaderFloat_0;
|
GLint shaderTextureSize;
|
||||||
GLint shaderFloat_1;
|
GLint shaderTextureCoord;
|
||||||
GLint shaderFloat_2;
|
GLint shaderColor;
|
||||||
GLint shaderVec4_0;
|
GLint shaderSaturation;
|
||||||
GLint shaderVec4_1;
|
|
||||||
GLint shaderVec4_2;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Renderer
|
} // Renderer
|
||||||
|
|
||||||
#endif // ES_CORE_RENDERER_SHADER_GL21_H
|
#endif // ES_CORE_RENDERER_SHADER_GL21_H
|
||||||
|
|
137
resources/shaders/glsl/blur_horizontal.glsl
Normal file
137
resources/shaders/glsl/blur_horizontal.glsl
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
// Implementation based on the article "Efficient Gaussian blur with linear sampling"
|
||||||
|
// http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
|
||||||
|
/* A version for MasterEffect Reborn, a standalone version, and a custom shader version for SweetFX can be
|
||||||
|
found at http://reshade.me/forum/shader-presentation/27-gaussian-blur-bloom-unsharpmask */
|
||||||
|
/*-----------------------------------------------------------.
|
||||||
|
/ Gaussian Blur settings /
|
||||||
|
'-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define HW 1.00
|
||||||
|
|
||||||
|
#if defined(VERTEX)
|
||||||
|
|
||||||
|
#if __VERSION__ >= 130
|
||||||
|
#define COMPAT_VARYING out
|
||||||
|
#define COMPAT_ATTRIBUTE in
|
||||||
|
#define COMPAT_TEXTURE texture
|
||||||
|
#else
|
||||||
|
#define COMPAT_VARYING varying
|
||||||
|
#define COMPAT_ATTRIBUTE attribute
|
||||||
|
#define COMPAT_TEXTURE texture2D
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GL_ES
|
||||||
|
#define COMPAT_PRECISION mediump
|
||||||
|
#else
|
||||||
|
#define COMPAT_PRECISION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
COMPAT_ATTRIBUTE vec4 VertexCoord;
|
||||||
|
COMPAT_ATTRIBUTE vec4 COLOR;
|
||||||
|
COMPAT_ATTRIBUTE vec4 TexCoord;
|
||||||
|
COMPAT_VARYING vec4 COL0;
|
||||||
|
COMPAT_VARYING vec4 TEX0;
|
||||||
|
|
||||||
|
vec4 _oPosition1;
|
||||||
|
uniform mat4 MVPMatrix;
|
||||||
|
uniform COMPAT_PRECISION int FrameDirection;
|
||||||
|
uniform COMPAT_PRECISION int FrameCount;
|
||||||
|
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||||
|
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||||
|
uniform COMPAT_PRECISION vec2 InputSize;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||||
|
// gl_Position = MVPMatrix * VertexCoord;
|
||||||
|
COL0 = COLOR;
|
||||||
|
TEX0.xy = gl_MultiTexCoord0.xy;
|
||||||
|
// TEX0.xy = TexCoord.xy;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(FRAGMENT)
|
||||||
|
|
||||||
|
#if __VERSION__ >= 130
|
||||||
|
#define COMPAT_VARYING in
|
||||||
|
#define COMPAT_TEXTURE texture
|
||||||
|
out vec4 FragColor;
|
||||||
|
#else
|
||||||
|
#define COMPAT_VARYING varying
|
||||||
|
#define FragColor gl_FragColor
|
||||||
|
#define COMPAT_TEXTURE texture2D
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GL_ES
|
||||||
|
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||||
|
precision highp float;
|
||||||
|
#else
|
||||||
|
precision mediump float;
|
||||||
|
#endif
|
||||||
|
#define COMPAT_PRECISION mediump
|
||||||
|
#else
|
||||||
|
#define COMPAT_PRECISION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform COMPAT_PRECISION int FrameDirection;
|
||||||
|
uniform COMPAT_PRECISION int FrameCount;
|
||||||
|
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||||
|
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||||
|
uniform COMPAT_PRECISION vec2 InputSize;
|
||||||
|
uniform sampler2D Texture;
|
||||||
|
COMPAT_VARYING vec4 TEX0;
|
||||||
|
|
||||||
|
// compatibility #defines
|
||||||
|
#define Source Texture
|
||||||
|
#define vTexCoord TEX0.xy
|
||||||
|
|
||||||
|
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||||
|
#define outsize vec4(OutputSize, 1.0 / OutputSize)
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 texcoord = vTexCoord;
|
||||||
|
// vec2 PIXEL_SIZE = SourceSize.zw;
|
||||||
|
vec2 PIXEL_SIZE = vec2(SourceSize.z, SourceSize.w);
|
||||||
|
#if __VERSION__ < 130
|
||||||
|
float sampleOffsets1 = 0.0;
|
||||||
|
float sampleOffsets2 = 1.4347826;
|
||||||
|
float sampleOffsets3 = 3.3478260;
|
||||||
|
float sampleOffsets4 = 5.2608695;
|
||||||
|
float sampleOffsets5 = 7.1739130;
|
||||||
|
|
||||||
|
float sampleWeights1 = 0.16818994;
|
||||||
|
float sampleWeights2 = 0.27276957;
|
||||||
|
float sampleWeights3 = 0.11690125;
|
||||||
|
float sampleWeights4 = 0.024067905;
|
||||||
|
float sampleWeights5 = 0.0021112196;
|
||||||
|
|
||||||
|
vec4 color = COMPAT_TEXTURE(Source, texcoord) * sampleWeights1;
|
||||||
|
|
||||||
|
// unroll the loop
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord + vec2(sampleOffsets2* HW * PIXEL_SIZE.x, 0.0)) * sampleWeights2;
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord - vec2(sampleOffsets2* HW * PIXEL_SIZE.x, 0.0)) * sampleWeights2;
|
||||||
|
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord + vec2(sampleOffsets3* HW * PIXEL_SIZE.x, 0.0)) * sampleWeights3;
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord - vec2(sampleOffsets3* HW * PIXEL_SIZE.x, 0.0)) * sampleWeights3;
|
||||||
|
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord + vec2(sampleOffsets4* HW * PIXEL_SIZE.x, 0.0)) * sampleWeights4;
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord - vec2(sampleOffsets4* HW * PIXEL_SIZE.x, 0.0)) * sampleWeights4;
|
||||||
|
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord + vec2(sampleOffsets5* HW * PIXEL_SIZE.x, 0.0)) * sampleWeights5;
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord - vec2(sampleOffsets5* HW * PIXEL_SIZE.x, 0.0)) * sampleWeights5;
|
||||||
|
#else
|
||||||
|
|
||||||
|
float sampleOffsets[5] = { 0.0, 1.4347826, 3.3478260, 5.2608695, 7.1739130 };
|
||||||
|
float sampleWeights[5] = { 0.16818994, 0.27276957, 0.11690125, 0.024067905, 0.0021112196 };
|
||||||
|
|
||||||
|
vec4 color = COMPAT_TEXTURE(Source, texcoord) * sampleWeights[0];
|
||||||
|
for(int i = 1; i < 5; ++i) {
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord + vec2(sampleOffsets[i]*HW * PIXEL_SIZE.x, 0.0)) * sampleWeights[i];
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord - vec2(sampleOffsets[i]*HW * PIXEL_SIZE.x, 0.0)) * sampleWeights[i];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FragColor = vec4(color);
|
||||||
|
// FragColor = vec4(0.4, 0.0, 0.2, 0.6);
|
||||||
|
}
|
||||||
|
#endif
|
137
resources/shaders/glsl/blur_vertical.glsl
Normal file
137
resources/shaders/glsl/blur_vertical.glsl
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
// Implementation based on the article "Efficient Gaussian blur with linear sampling"
|
||||||
|
// http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
|
||||||
|
/* A version for MasterEffect Reborn, a standalone version, and a custom shader version for SweetFX can be
|
||||||
|
found at http://reshade.me/forum/shader-presentation/27-gaussian-blur-bloom-unsharpmask */
|
||||||
|
/*-----------------------------------------------------------.
|
||||||
|
/ Gaussian Blur settings /
|
||||||
|
'-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define VW 1.00
|
||||||
|
|
||||||
|
#if defined(VERTEX)
|
||||||
|
|
||||||
|
#if __VERSION__ >= 130
|
||||||
|
#define COMPAT_VARYING out
|
||||||
|
#define COMPAT_ATTRIBUTE in
|
||||||
|
#define COMPAT_TEXTURE texture
|
||||||
|
#else
|
||||||
|
#define COMPAT_VARYING varying
|
||||||
|
#define COMPAT_ATTRIBUTE attribute
|
||||||
|
#define COMPAT_TEXTURE texture2D
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GL_ES
|
||||||
|
#define COMPAT_PRECISION mediump
|
||||||
|
#else
|
||||||
|
#define COMPAT_PRECISION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
COMPAT_ATTRIBUTE vec4 VertexCoord;
|
||||||
|
COMPAT_ATTRIBUTE vec4 COLOR;
|
||||||
|
COMPAT_ATTRIBUTE vec4 TexCoord;
|
||||||
|
COMPAT_VARYING vec4 COL0;
|
||||||
|
COMPAT_VARYING vec4 TEX0;
|
||||||
|
// out variables go here as COMPAT_VARYING whatever
|
||||||
|
|
||||||
|
vec4 _oPosition1;
|
||||||
|
uniform mat4 MVPMatrix;
|
||||||
|
uniform COMPAT_PRECISION int FrameDirection;
|
||||||
|
uniform COMPAT_PRECISION int FrameCount;
|
||||||
|
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||||
|
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||||
|
uniform COMPAT_PRECISION vec2 InputSize;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||||
|
// gl_Position = MVPMatrix * VertexCoord;
|
||||||
|
COL0 = COLOR;
|
||||||
|
TEX0.xy = gl_MultiTexCoord0.xy;
|
||||||
|
// TEX0.xy = TexCoord.xy;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(FRAGMENT)
|
||||||
|
|
||||||
|
#if __VERSION__ >= 130
|
||||||
|
#define COMPAT_VARYING in
|
||||||
|
#define COMPAT_TEXTURE texture
|
||||||
|
out vec4 FragColor;
|
||||||
|
#else
|
||||||
|
#define COMPAT_VARYING varying
|
||||||
|
#define FragColor gl_FragColor
|
||||||
|
#define COMPAT_TEXTURE texture2D
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GL_ES
|
||||||
|
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||||
|
precision highp float;
|
||||||
|
#else
|
||||||
|
precision mediump float;
|
||||||
|
#endif
|
||||||
|
#define COMPAT_PRECISION mediump
|
||||||
|
#else
|
||||||
|
#define COMPAT_PRECISION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform COMPAT_PRECISION int FrameDirection;
|
||||||
|
uniform COMPAT_PRECISION int FrameCount;
|
||||||
|
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||||
|
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||||
|
uniform COMPAT_PRECISION vec2 InputSize;
|
||||||
|
uniform sampler2D Texture;
|
||||||
|
COMPAT_VARYING vec4 TEX0;
|
||||||
|
|
||||||
|
// compatibility #defines
|
||||||
|
#define Source Texture
|
||||||
|
#define vTexCoord TEX0.xy
|
||||||
|
|
||||||
|
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||||
|
#define outsize vec4(OutputSize, 1.0 / OutputSize)
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 texcoord = vTexCoord;
|
||||||
|
// vec2 PIXEL_SIZE = SourceSize.zw;
|
||||||
|
vec2 PIXEL_SIZE = vec2(SourceSize.z, SourceSize.w);
|
||||||
|
#if __VERSION__ < 130
|
||||||
|
float sampleOffsets1 = 0.0;
|
||||||
|
float sampleOffsets2 = 1.4347826;
|
||||||
|
float sampleOffsets3 = 3.3478260;
|
||||||
|
float sampleOffsets4 = 5.2608695;
|
||||||
|
float sampleOffsets5 = 7.1739130;
|
||||||
|
|
||||||
|
float sampleWeights1 = 0.16818994;
|
||||||
|
float sampleWeights2 = 0.27276957;
|
||||||
|
float sampleWeights3 = 0.11690125;
|
||||||
|
float sampleWeights4 = 0.024067905;
|
||||||
|
float sampleWeights5 = 0.0021112196;
|
||||||
|
|
||||||
|
vec4 color = COMPAT_TEXTURE(Source, texcoord) * sampleWeights1;
|
||||||
|
|
||||||
|
// unroll the loop
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord + vec2(0.0, sampleOffsets2* VW * PIXEL_SIZE.y)) * sampleWeights2;
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord - vec2(0.0, sampleOffsets2* VW * PIXEL_SIZE.y)) * sampleWeights2;
|
||||||
|
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord + vec2(0.0, sampleOffsets3* VW * PIXEL_SIZE.y)) * sampleWeights3;
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord - vec2(0.0, sampleOffsets3* VW * PIXEL_SIZE.y)) * sampleWeights3;
|
||||||
|
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord + vec2(0.0, sampleOffsets4* VW * PIXEL_SIZE.y)) * sampleWeights4;
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord - vec2(0.0, sampleOffsets4* VW * PIXEL_SIZE.y)) * sampleWeights4;
|
||||||
|
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord + vec2(0.0, sampleOffsets5* VW * PIXEL_SIZE.y)) * sampleWeights5;
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord - vec2(0.0, sampleOffsets5* VW * PIXEL_SIZE.y)) * sampleWeights5;
|
||||||
|
#else
|
||||||
|
|
||||||
|
float sampleOffsets[5] = { 0.0, 1.4347826, 3.3478260, 5.2608695, 7.1739130 };
|
||||||
|
float sampleWeights[5] = { 0.16818994, 0.27276957, 0.11690125, 0.024067905, 0.0021112196 };
|
||||||
|
|
||||||
|
vec4 color = COMPAT_TEXTURE(Source, texcoord) * sampleWeights[0];
|
||||||
|
for(int i = 1; i < 5; ++i) {
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord + vec2(0.0, sampleOffsets[i]*VW * PIXEL_SIZE.y)) * sampleWeights[i];
|
||||||
|
color += COMPAT_TEXTURE(Source, texcoord - vec2(0.0, sampleOffsets[i]*VW * PIXEL_SIZE.y)) * sampleWeights[i];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FragColor = vec4(color);
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -2,13 +2,12 @@
|
||||||
// desaturate.glsl
|
// desaturate.glsl
|
||||||
//
|
//
|
||||||
// Desaturates textures such as game images.
|
// Desaturates textures such as game images.
|
||||||
// The uniform variable 'shaderFloat_0' sets the saturation intensity.
|
// The uniform variable 'saturation' sets the saturation intensity.
|
||||||
// Setting this to the value 0 results in complete desaturation (grayscale).
|
// Setting this to the value 0 results in complete desaturation (grayscale).
|
||||||
//
|
//
|
||||||
|
|
||||||
// Vertex section of code:
|
|
||||||
// -----------------------
|
|
||||||
#if defined(VERTEX)
|
#if defined(VERTEX)
|
||||||
|
// Vertex section of code:
|
||||||
|
|
||||||
varying vec2 vTexCoord;
|
varying vec2 vTexCoord;
|
||||||
|
|
||||||
|
@ -17,19 +16,16 @@ void main(void)
|
||||||
vTexCoord = gl_MultiTexCoord0.xy;
|
vTexCoord = gl_MultiTexCoord0.xy;
|
||||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#elif defined(FRAGMENT)
|
||||||
// Fragment section of code:
|
// Fragment section of code:
|
||||||
// -------------------------
|
|
||||||
#ifdef FRAGMENT
|
|
||||||
|
|
||||||
uniform float shaderFloat_0 = 1.0;
|
uniform float saturation = 1.0;
|
||||||
uniform sampler2D myTexture;
|
uniform sampler2D myTexture;
|
||||||
varying vec2 vTexCoord;
|
varying vec2 vTexCoord;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
float saturation = shaderFloat_0;
|
|
||||||
vec4 color = texture2D(myTexture, vTexCoord);
|
vec4 color = texture2D(myTexture, vTexCoord);
|
||||||
vec3 grayscale = vec3(dot(color.rgb, vec3(0.2125, 0.7154, 0.0721)));
|
vec3 grayscale = vec3(dot(color.rgb, vec3(0.2125, 0.7154, 0.0721)));
|
||||||
|
|
||||||
|
|
208
resources/shaders/glsl/scanlines.glsl
Normal file
208
resources/shaders/glsl/scanlines.glsl
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
/*
|
||||||
|
Phosphor shader - Copyright (C) 2011 caligari.
|
||||||
|
|
||||||
|
Ported by Hyllian.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Parameter lines go here:
|
||||||
|
// 0.5 = the spot stays inside the original pixel
|
||||||
|
// 1.0 = the spot bleeds up to the center of next pixel
|
||||||
|
#pragma parameter SPOT_WIDTH "CRTCaligari Spot Width" 0.9 0.1 1.5 0.05
|
||||||
|
#pragma parameter SPOT_HEIGHT "CRTCaligari Spot Height" 0.75 0.1 1.5 0.05
|
||||||
|
// Used to counteract the desaturation effect of weighting.
|
||||||
|
#pragma parameter COLOR_BOOST "CRTCaligari Color Boost" 1.45 1.0 2.0 0.05
|
||||||
|
// Constants used with gamma correction.
|
||||||
|
#pragma parameter InputGamma "CRTCaligari Input Gamma" 2.4 0.0 5.0 0.1
|
||||||
|
#pragma parameter OutputGamma "CRTCaligari Output Gamma" 2.2 0.0 5.0 0.1
|
||||||
|
|
||||||
|
#if defined(VERTEX)
|
||||||
|
|
||||||
|
#if __VERSION__ >= 130
|
||||||
|
#define COMPAT_VARYING out
|
||||||
|
#define COMPAT_ATTRIBUTE in
|
||||||
|
#define COMPAT_TEXTURE texture
|
||||||
|
#else
|
||||||
|
#define COMPAT_VARYING varying
|
||||||
|
#define COMPAT_ATTRIBUTE attribute
|
||||||
|
#define COMPAT_TEXTURE texture2D
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GL_ES
|
||||||
|
#define COMPAT_PRECISION mediump
|
||||||
|
#else
|
||||||
|
#define COMPAT_PRECISION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
COMPAT_ATTRIBUTE vec4 VertexCoord;
|
||||||
|
COMPAT_ATTRIBUTE vec4 COLOR;
|
||||||
|
COMPAT_ATTRIBUTE vec4 TexCoord;
|
||||||
|
COMPAT_VARYING vec4 COL0;
|
||||||
|
COMPAT_VARYING vec4 TEX0;
|
||||||
|
COMPAT_VARYING vec2 onex;
|
||||||
|
COMPAT_VARYING vec2 oney;
|
||||||
|
|
||||||
|
vec4 _oPosition1;
|
||||||
|
uniform mat4 MVPMatrix;
|
||||||
|
uniform COMPAT_PRECISION int FrameDirection;
|
||||||
|
uniform COMPAT_PRECISION int FrameCount;
|
||||||
|
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||||
|
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||||
|
uniform COMPAT_PRECISION vec2 InputSize;
|
||||||
|
|
||||||
|
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||||
|
// gl_Position = MVPMatrix * VertexCoord;
|
||||||
|
COL0 = COLOR;
|
||||||
|
TEX0.xy = gl_MultiTexCoord0.xy;
|
||||||
|
// TEX0.xy = TexCoord.xy;
|
||||||
|
onex = vec2(SourceSize.z, 0.0);
|
||||||
|
oney = vec2(0.0, SourceSize.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(FRAGMENT)
|
||||||
|
|
||||||
|
#if __VERSION__ >= 130
|
||||||
|
#define COMPAT_VARYING in
|
||||||
|
#define COMPAT_TEXTURE texture
|
||||||
|
out vec4 FragColor;
|
||||||
|
#else
|
||||||
|
#define COMPAT_VARYING varying
|
||||||
|
#define FragColor gl_FragColor
|
||||||
|
#define COMPAT_TEXTURE texture2D
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GL_ES
|
||||||
|
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||||
|
precision highp float;
|
||||||
|
#else
|
||||||
|
precision mediump float;
|
||||||
|
#endif
|
||||||
|
#define COMPAT_PRECISION mediump
|
||||||
|
#else
|
||||||
|
#define COMPAT_PRECISION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform COMPAT_PRECISION int FrameDirection;
|
||||||
|
uniform COMPAT_PRECISION int FrameCount;
|
||||||
|
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||||
|
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||||
|
uniform COMPAT_PRECISION vec2 InputSize;
|
||||||
|
uniform sampler2D Texture;
|
||||||
|
COMPAT_VARYING vec4 TEX0;
|
||||||
|
COMPAT_VARYING vec2 onex;
|
||||||
|
COMPAT_VARYING vec2 oney;
|
||||||
|
|
||||||
|
// compatibility #defines
|
||||||
|
#define Source Texture
|
||||||
|
#define vTexCoord TEX0.xy
|
||||||
|
|
||||||
|
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||||
|
#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
|
||||||
|
|
||||||
|
#ifdef PARAMETER_UNIFORM
|
||||||
|
// All parameter floats need to have COMPAT_PRECISION in front of them
|
||||||
|
uniform COMPAT_PRECISION float SPOT_WIDTH;
|
||||||
|
uniform COMPAT_PRECISION float SPOT_HEIGHT;
|
||||||
|
uniform COMPAT_PRECISION float COLOR_BOOST;
|
||||||
|
uniform COMPAT_PRECISION float InputGamma;
|
||||||
|
uniform COMPAT_PRECISION float OutputGamma;
|
||||||
|
#else
|
||||||
|
#define SPOT_WIDTH 0.9
|
||||||
|
#define SPOT_HEIGHT 0.75
|
||||||
|
#define COLOR_BOOST 1.45
|
||||||
|
#define InputGamma 2.4
|
||||||
|
#define OutputGamma 2.2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GAMMA_IN(color) pow(color,vec4(InputGamma))
|
||||||
|
#define GAMMA_OUT(color) pow(color, vec4(1.0 / OutputGamma))
|
||||||
|
|
||||||
|
#define TEX2D(coords) GAMMA_IN( COMPAT_TEXTURE(Source, coords) )
|
||||||
|
|
||||||
|
// Macro for weights computing
|
||||||
|
#define WEIGHT(w) \
|
||||||
|
if(w>1.0) w=1.0; \
|
||||||
|
w = 1.0 - w * w; \
|
||||||
|
w = w * w;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 coords = ( vTexCoord * SourceSize.xy );
|
||||||
|
vec2 pixel_center = floor( coords ) + vec2(0.5, 0.5);
|
||||||
|
vec2 texture_coords = pixel_center * SourceSize.zw;
|
||||||
|
|
||||||
|
vec4 color = TEX2D( texture_coords );
|
||||||
|
|
||||||
|
float dx = coords.x - pixel_center.x;
|
||||||
|
|
||||||
|
float h_weight_00 = dx / SPOT_WIDTH;
|
||||||
|
WEIGHT( h_weight_00 );
|
||||||
|
|
||||||
|
color *= vec4( h_weight_00, h_weight_00, h_weight_00, h_weight_00 );
|
||||||
|
|
||||||
|
// get closest horizontal neighbour to blend
|
||||||
|
vec2 coords01;
|
||||||
|
if (dx>0.0) {
|
||||||
|
coords01 = onex;
|
||||||
|
dx = 1.0 - dx;
|
||||||
|
} else {
|
||||||
|
coords01 = -onex;
|
||||||
|
dx = 1.0 + dx;
|
||||||
|
}
|
||||||
|
vec4 colorNB = TEX2D( texture_coords + coords01 );
|
||||||
|
|
||||||
|
float h_weight_01 = dx / SPOT_WIDTH;
|
||||||
|
WEIGHT( h_weight_01 );
|
||||||
|
|
||||||
|
color = color + colorNB * vec4( h_weight_01 );
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
// Vertical Blending
|
||||||
|
float dy = coords.y - pixel_center.y;
|
||||||
|
float v_weight_00 = dy / SPOT_HEIGHT;
|
||||||
|
WEIGHT( v_weight_00 );
|
||||||
|
color *= vec4( v_weight_00 );
|
||||||
|
|
||||||
|
// get closest vertical neighbour to blend
|
||||||
|
vec2 coords10;
|
||||||
|
if (dy>0.0) {
|
||||||
|
coords10 = oney;
|
||||||
|
dy = 1.0 - dy;
|
||||||
|
} else {
|
||||||
|
coords10 = -oney;
|
||||||
|
dy = 1.0 + dy;
|
||||||
|
}
|
||||||
|
colorNB = TEX2D( texture_coords + coords10 );
|
||||||
|
|
||||||
|
float v_weight_10 = dy / SPOT_HEIGHT;
|
||||||
|
WEIGHT( v_weight_10 );
|
||||||
|
|
||||||
|
color = color + colorNB * vec4( v_weight_10 * h_weight_00, v_weight_10 * h_weight_00, v_weight_10 * h_weight_00, v_weight_10 * h_weight_00 );
|
||||||
|
|
||||||
|
colorNB = TEX2D( texture_coords + coords01 + coords10 );
|
||||||
|
|
||||||
|
color = color + colorNB * vec4( v_weight_10 * h_weight_01, v_weight_10 * h_weight_01, v_weight_10 * h_weight_01, v_weight_10 * h_weight_01 );
|
||||||
|
|
||||||
|
color *= vec4( COLOR_BOOST );
|
||||||
|
|
||||||
|
FragColor = clamp( GAMMA_OUT(color), 0.0, 1.0 );
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
Reference in a new issue