mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 14:15:38 +00:00
Added a GLSL shader to convert the color model BGRA to RGBA.
Also added support for specifying a separate format as compared to internalFormat when creating textures, although the shader should be used primarily as this is not really supported by the OpenGL standard.
This commit is contained in:
parent
7430a8b5f5
commit
0c552dd8fb
|
@ -271,6 +271,7 @@ namespace Renderer
|
|||
shaderFiles.push_back(":/shaders/glsl/blur_horizontal.glsl");
|
||||
shaderFiles.push_back(":/shaders/glsl/blur_vertical.glsl");
|
||||
shaderFiles.push_back(":/shaders/glsl/scanlines.glsl");
|
||||
shaderFiles.push_back(":/shaders/glsl/bgra_to_rgba.glsl");
|
||||
|
||||
for (auto it = shaderFiles.cbegin(); it != shaderFiles.cend(); ++it) {
|
||||
Shader* loadShader = new Shader();
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace Renderer
|
|||
const unsigned int SHADER_BLUR_HORIZONTAL{8};
|
||||
const unsigned int SHADER_BLUR_VERTICAL{16};
|
||||
const unsigned int SHADER_SCANLINES{32};
|
||||
const unsigned int SHADER_BGRA_TO_RGBA{64};
|
||||
|
||||
struct shaderParameters {
|
||||
std::array<GLfloat, 2> textureSize;
|
||||
|
@ -94,6 +95,7 @@ namespace Renderer
|
|||
{
|
||||
enum Type {
|
||||
RGBA, // Replace with AllowShortEnumsOnASingleLine: false (clang-format >=11.0).
|
||||
BGRA,
|
||||
ALPHA
|
||||
};
|
||||
}
|
||||
|
@ -170,6 +172,7 @@ namespace Renderer
|
|||
bool createContext();
|
||||
void destroyContext();
|
||||
unsigned int createTexture(const Texture::Type type,
|
||||
const Texture::Type format,
|
||||
const bool linearMinify,
|
||||
const bool linearMagnify,
|
||||
const bool repeat,
|
||||
|
|
|
@ -45,6 +45,7 @@ namespace Renderer
|
|||
// clang-format off
|
||||
switch (_type) {
|
||||
case Texture::RGBA: { return GL_RGBA; } break;
|
||||
case Texture::BGRA: { return GL_BGRA; } break;
|
||||
case Texture::ALPHA: { return GL_ALPHA; } break;
|
||||
default: { return GL_ZERO; }
|
||||
}
|
||||
|
@ -142,7 +143,7 @@ namespace Renderer
|
|||
}
|
||||
|
||||
uint8_t data[4] = {255, 255, 255, 255};
|
||||
whiteTexture = createTexture(Texture::RGBA, false, false, true, 1, 1, data);
|
||||
whiteTexture = createTexture(Texture::RGBA, Texture::RGBA, false, false, true, 1, 1, data);
|
||||
|
||||
GL_CHECK_ERROR(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
GL_CHECK_ERROR(glEnable(GL_TEXTURE_2D));
|
||||
|
@ -167,6 +168,7 @@ namespace Renderer
|
|||
}
|
||||
|
||||
unsigned int createTexture(const Texture::Type type,
|
||||
const Texture::Type format,
|
||||
const bool linearMinify,
|
||||
const bool linearMagnify,
|
||||
const bool repeat,
|
||||
|
@ -175,6 +177,7 @@ namespace Renderer
|
|||
void* data)
|
||||
{
|
||||
const GLenum textureType = convertTextureType(type);
|
||||
const GLenum textureFormat = convertTextureType(format);
|
||||
unsigned int texture;
|
||||
|
||||
GL_CHECK_ERROR(glGenTextures(1, &texture));
|
||||
|
@ -192,8 +195,11 @@ namespace Renderer
|
|||
GL_CHECK_ERROR(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||
linearMagnify ? static_cast<GLfloat>(GL_LINEAR) :
|
||||
static_cast<GLfloat>(GL_NEAREST)));
|
||||
|
||||
GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, textureType, width, height, 0, textureType,
|
||||
// Setting different values for internalFormat and format is not really supported by the
|
||||
// OpenGL standard so hopefully it works with all drivers and on all operating systems.
|
||||
// This is only intended as a last resort anyway, normally the BGRA_TO_RGBA shader should
|
||||
// be used for color model conversion.
|
||||
GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, textureType, width, height, 0, textureFormat,
|
||||
GL_UNSIGNED_BYTE, data));
|
||||
|
||||
return texture;
|
||||
|
@ -355,6 +361,16 @@ namespace Renderer
|
|||
runShader->deactivateShaders();
|
||||
}
|
||||
}
|
||||
|
||||
if (vertices->shaders & SHADER_BGRA_TO_RGBA) {
|
||||
Shader* runShader = getShaderProgram(SHADER_BGRA_TO_RGBA);
|
||||
if (runShader) {
|
||||
runShader->activateShaders();
|
||||
runShader->setModelViewProjectionMatrix(getProjectionMatrix() * trans);
|
||||
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, numVertices));
|
||||
runShader->deactivateShaders();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -470,8 +486,8 @@ namespace Renderer
|
|||
vertices[0].saturation = parameters.fragmentSaturation;
|
||||
|
||||
setMatrix(getIdentity());
|
||||
GLuint screenTexture =
|
||||
createTexture(Texture::RGBA, false, false, false, width, height, nullptr);
|
||||
GLuint screenTexture = createTexture(Texture::RGBA, Texture::RGBA, false, false, false,
|
||||
width, height, nullptr);
|
||||
|
||||
GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0));
|
||||
|
||||
|
|
|
@ -43,9 +43,10 @@ namespace Renderer
|
|||
{
|
||||
// clang-format off
|
||||
switch (_type) {
|
||||
case Texture::RGBA: { return GL_RGBA; } break;
|
||||
case Texture::ALPHA: { return GL_ALPHA; } break;
|
||||
default: { return GL_ZERO; }
|
||||
case Texture::RGBA: { return GL_RGBA; } break;
|
||||
case Texture::BGRA: { return GL_BGRA_EXT; } break;
|
||||
case Texture::ALPHA: { return GL_ALPHA; } break;
|
||||
default: { return GL_ZERO; }
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
@ -91,7 +92,7 @@ namespace Renderer
|
|||
"MISSING");
|
||||
|
||||
uint8_t data[4] = {255, 255, 255, 255};
|
||||
whiteTexture = createTexture(Texture::RGBA, false, false, true, 1, 1, data);
|
||||
whiteTexture = createTexture(Texture::RGBA, Texture::RGBA, false, false, true, 1, 1, data);
|
||||
|
||||
GL_CHECK_ERROR(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
GL_CHECK_ERROR(glEnable(GL_TEXTURE_2D));
|
||||
|
@ -112,6 +113,7 @@ namespace Renderer
|
|||
}
|
||||
|
||||
unsigned int createTexture(const Texture::Type type,
|
||||
const Texture::Type format,
|
||||
const bool linearMinify,
|
||||
const bool linearMagnify,
|
||||
const bool repeat,
|
||||
|
@ -120,6 +122,7 @@ namespace Renderer
|
|||
void* data)
|
||||
{
|
||||
const GLenum textureType = convertTextureType(type);
|
||||
const GLenum textureFormat = convertTextureType(format);
|
||||
unsigned int texture;
|
||||
|
||||
GL_CHECK_ERROR(glGenTextures(1, &texture));
|
||||
|
@ -134,7 +137,11 @@ namespace Renderer
|
|||
GL_CHECK_ERROR(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||
linearMagnify ? GL_LINEAR : GL_NEAREST));
|
||||
|
||||
GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, textureType, width, height, 0, textureType,
|
||||
// Setting different values for internalFormat and format is not really supported by the
|
||||
// OpenGL standard so hopefully it works with all drivers and on all operating systems.
|
||||
// This is only intended as a last resort anyway, normally the BGRA_TO_RGBA shader should
|
||||
// be used for color model conversion.
|
||||
GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, textureType, width, height, 0, textureFormat,
|
||||
GL_UNSIGNED_BYTE, data));
|
||||
|
||||
return texture;
|
||||
|
|
|
@ -199,8 +199,8 @@ bool Font::FontTexture::findEmpty(const glm::ivec2& size, glm::ivec2& cursor_out
|
|||
void Font::FontTexture::initTexture()
|
||||
{
|
||||
assert(textureId == 0);
|
||||
textureId = Renderer::createTexture(Renderer::Texture::ALPHA, false, false, false,
|
||||
textureSize.x, textureSize.y, nullptr);
|
||||
textureId = Renderer::createTexture(Renderer::Texture::ALPHA, Renderer::Texture::ALPHA, false,
|
||||
false, false, textureSize.x, textureSize.y, nullptr);
|
||||
}
|
||||
|
||||
void Font::FontTexture::deinitTexture()
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
#include "ImageIO.h"
|
||||
#include "Log.h"
|
||||
#include "renderers/Renderer.h"
|
||||
#include "resources/ResourceManager.h"
|
||||
#include "utils/StringUtil.h"
|
||||
|
||||
|
@ -28,6 +27,7 @@ TextureData::TextureData(bool tile)
|
|||
: mTile{tile}
|
||||
, mTextureID{0}
|
||||
, mDataRGBA({})
|
||||
, mFormat{Renderer::Texture::RGBA}
|
||||
, mWidth{0}
|
||||
, mHeight{0}
|
||||
, mSourceWidth{0.0f}
|
||||
|
@ -219,7 +219,7 @@ bool TextureData::uploadAndBind()
|
|||
|
||||
// Upload texture.
|
||||
mTextureID =
|
||||
Renderer::createTexture(Renderer::Texture::RGBA, true, mLinearMagnify, mTile,
|
||||
Renderer::createTexture(Renderer::Texture::RGBA, mFormat, true, mLinearMagnify, mTile,
|
||||
static_cast<const unsigned int>(mWidth),
|
||||
static_cast<const unsigned int>(mHeight), mDataRGBA.data());
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef ES_CORE_RESOURCES_TEXTURE_DATA_H
|
||||
#define ES_CORE_RESOURCES_TEXTURE_DATA_H
|
||||
|
||||
#include "renderers/Renderer.h"
|
||||
#include "utils/MathUtil.h"
|
||||
|
||||
#include <atomic>
|
||||
|
@ -63,6 +64,8 @@ public:
|
|||
// Whether to rasterize the image even if a size has not been set yet.
|
||||
void setForceRasterization(bool setting) { mForceRasterization = setting; }
|
||||
|
||||
void setFormat(Renderer::Texture::Type format) { mFormat = format; }
|
||||
|
||||
// Has the image been loaded but not yet been rasterized as the size was not known?
|
||||
bool getPendingRasterization() { return mPendingRasterization; }
|
||||
|
||||
|
@ -77,6 +80,7 @@ private:
|
|||
std::string mPath;
|
||||
std::atomic<unsigned int> mTextureID;
|
||||
std::vector<unsigned char> mDataRGBA;
|
||||
Renderer::Texture::Type mFormat;
|
||||
std::atomic<int> mWidth;
|
||||
std::atomic<int> mHeight;
|
||||
std::atomic<float> mSourceWidth;
|
||||
|
|
|
@ -45,6 +45,8 @@ public:
|
|||
return (mTextureData != nullptr ? mTextureData->getPendingRasterization() : false);
|
||||
}
|
||||
|
||||
void setFormat(Renderer::Texture::Type format) { mTextureData->setFormat(format); }
|
||||
|
||||
std::string getTextureFilePath();
|
||||
|
||||
void rasterizeAt(float width, float height);
|
||||
|
|
33
resources/shaders/glsl/bgra_to_rgba.glsl
Normal file
33
resources/shaders/glsl/bgra_to_rgba.glsl
Normal file
|
@ -0,0 +1,33 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// EmulationStation Desktop Edition
|
||||
// bgra_to_rgba.glsl
|
||||
//
|
||||
// Convert from color model BGRA to RGBA.
|
||||
//
|
||||
|
||||
#if defined(VERTEX)
|
||||
// Vertex section of code:
|
||||
|
||||
uniform mat4 MVPMatrix;
|
||||
varying vec2 vTexCoord;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vTexCoord = gl_MultiTexCoord0.xy;
|
||||
gl_Position = MVPMatrix * gl_Vertex;
|
||||
}
|
||||
|
||||
#elif defined(FRAGMENT)
|
||||
// Fragment section of code:
|
||||
|
||||
uniform sampler2D myTexture;
|
||||
varying vec2 vTexCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture2D(myTexture, vTexCoord);
|
||||
gl_FragColor = vec4(color.bgra);
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue