Unified the OpenGL and OpenGL ES renderers and removed the fixed function pipeline.

Also made some other rendering optimizations and cleaned up some code.
This commit is contained in:
Leon Styhre 2022-03-13 23:52:32 +01:00
parent adb162e0d1
commit a7db474a64
19 changed files with 300 additions and 363 deletions

View file

@ -86,7 +86,6 @@ void MediaViewer::render(const glm::mat4& /*parentTrans*/)
if (mVideo && !mDisplayingImage) {
mVideo->render(trans);
#if defined(USE_OPENGL_21)
Renderer::postProcessingParams videoParameters;
unsigned int shaders {0};
if (Settings::getInstance()->getBool("MediaViewerVideoScanlines"))
@ -111,20 +110,19 @@ void MediaViewer::render(const glm::mat4& /*parentTrans*/)
videoParameters.blurPasses = 2; // 1080
// clang-format on
}
Renderer::shaderPostprocessing(shaders, videoParameters);
#endif
if (shaders != 0)
Renderer::shaderPostprocessing(shaders, videoParameters);
}
else if (mImage && mImage->hasImage() && mImage->getSize() != glm::vec2 {}) {
mImage->render(trans);
#if defined(USE_OPENGL_21)
if (mCurrentImageIndex == mScreenshotIndex &&
Settings::getInstance()->getBool("MediaViewerScreenshotScanlines"))
Renderer::shaderPostprocessing(Renderer::SHADER_SCANLINES);
else if (mCurrentImageIndex == mTitleScreenIndex &&
Settings::getInstance()->getBool("MediaViewerScreenshotScanlines"))
Renderer::shaderPostprocessing(Renderer::SHADER_SCANLINES);
#endif
// This is necessary so that the video loops if viewing an image when
// the video ends.

View file

@ -267,10 +267,8 @@ void Screensaver::renderScreensaver()
if (isScreensaverActive()) {
if (Settings::getInstance()->getString("ScreensaverType") == "slideshow") {
if (mHasMediaFiles) {
#if defined(USE_OPENGL_21)
if (Settings::getInstance()->getBool("ScreensaverSlideshowScanlines"))
Renderer::shaderPostprocessing(Renderer::SHADER_SCANLINES);
#endif
if (Settings::getInstance()->getBool("ScreensaverSlideshowGameInfo") &&
mGameOverlay) {
if (mGameOverlayRectangleCoords.size() == 4) {
@ -295,7 +293,6 @@ void Screensaver::renderScreensaver()
}
else if (Settings::getInstance()->getString("ScreensaverType") == "video") {
if (mHasMediaFiles) {
#if defined(USE_OPENGL_21)
Renderer::postProcessingParams videoParameters;
unsigned int shaders {0};
if (Settings::getInstance()->getBool("ScreensaverVideoScanlines"))
@ -320,8 +317,10 @@ void Screensaver::renderScreensaver()
videoParameters.blurPasses = 2; // 1080
// clang-format on
}
Renderer::shaderPostprocessing(shaders, videoParameters);
#endif
if (shaders != 0)
Renderer::shaderPostprocessing(shaders, videoParameters);
if (Settings::getInstance()->getBool("ScreensaverVideoGameInfo") && mGameOverlay) {
if (mGameOverlayRectangleCoords.size() == 4) {
Renderer::drawRect(
@ -345,7 +344,6 @@ void Screensaver::renderScreensaver()
}
if (mFallbackScreensaver ||
Settings::getInstance()->getString("ScreensaverType") == "dim") {
#if defined(USE_OPENGL_21)
Renderer::postProcessingParams dimParameters;
dimParameters.dimming = mDimValue;
dimParameters.saturation = mSaturationAmount;
@ -354,22 +352,13 @@ void Screensaver::renderScreensaver()
mDimValue = glm::clamp(mDimValue - 0.015f, 0.68f, 1.0f);
if (mSaturationAmount > 0.0)
mSaturationAmount = glm::clamp(mSaturationAmount - 0.035f, 0.0f, 1.0f);
#else
Renderer::drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
0x000000A0, 0x000000A0);
#endif
}
else if (Settings::getInstance()->getString("ScreensaverType") == "black") {
#if defined(USE_OPENGL_21)
Renderer::postProcessingParams blackParameters;
blackParameters.dimming = mDimValue;
Renderer::shaderPostprocessing(Renderer::SHADER_CORE, blackParameters);
if (mDimValue > 0.0)
mDimValue = glm::clamp(mDimValue - 0.045f, 0.0f, 1.0f);
#else
Renderer::drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
0x000000FF, 0x000000FF);
#endif
}
}
}

View file

@ -41,7 +41,6 @@ GuiMediaViewerOptions::GuiMediaViewerOptions(const std::string& title)
}
});
#if defined(USE_OPENGL_21)
// Render scanlines for videos using a shader.
auto video_scanlines = std::make_shared<SwitchComponent>();
video_scanlines->setState(Settings::getInstance()->getBool("MediaViewerVideoScanlines"));
@ -79,5 +78,4 @@ GuiMediaViewerOptions::GuiMediaViewerOptions(const std::string& title)
setNeedsSaving();
}
});
#endif
}

View file

@ -493,7 +493,6 @@ void GuiMenu::openUIOptions()
screensaver_row.makeAcceptInputHandler(std::bind(&GuiMenu::openScreensaverOptions, this));
s->addRow(screensaver_row);
#if defined(USE_OPENGL_21)
// Blur background when the menu is open.
auto menu_blur_background = std::make_shared<SwitchComponent>();
menu_blur_background->setState(Settings::getInstance()->getBool("MenuBlurBackground"));
@ -507,7 +506,6 @@ void GuiMenu::openUIOptions()
s->setInvalidateCachedBackground();
}
});
#endif
// Display pillarboxes (and letterboxes) for videos in the gamelists.
auto gamelistVideoPillarbox = std::make_shared<SwitchComponent>();
@ -522,7 +520,6 @@ void GuiMenu::openUIOptions()
}
});
#if defined(USE_OPENGL_21)
// Render scanlines for videos in the gamelists.
auto gamelistVideoScanlines = std::make_shared<SwitchComponent>();
gamelistVideoScanlines->setState(Settings::getInstance()->getBool("GamelistVideoScanlines"));
@ -535,7 +532,6 @@ void GuiMenu::openUIOptions()
s->setNeedsSaving();
}
});
#endif
// Sort folders on top of the gamelists.
auto folders_on_top = std::make_shared<SwitchComponent>();
@ -751,13 +747,11 @@ void GuiMenu::openUIOptions()
->setOpacity(DISABLED_OPACITY);
// Scanlines are theme-controlled for newer themes.
#if defined(USE_OPENGL_21)
gamelistVideoScanlines->setEnabled(false);
gamelistVideoScanlines->setOpacity(DISABLED_OPACITY);
gamelistVideoScanlines->getParent()
->getChild(gamelistVideoScanlines->getChildIndex() - 1)
->setOpacity(DISABLED_OPACITY);
#endif
}
else {
gamelist_view_style->setEnabled(true);
@ -778,13 +772,11 @@ void GuiMenu::openUIOptions()
->getChild(gamelistVideoPillarbox->getChildIndex() - 1)
->setOpacity(1.0f);
#if defined(USE_OPENGL_21)
gamelistVideoScanlines->setEnabled(true);
gamelistVideoScanlines->setOpacity(1.0f);
gamelistVideoScanlines->getParent()
->getChild(gamelistVideoScanlines->getChildIndex() - 1)
->setOpacity(1.0f);
#endif
}
};

View file

@ -149,7 +149,6 @@ void GuiScreensaverOptions::openSlideshowScreensaverOptions()
}
});
#if defined(USE_OPENGL_21)
// Render scanlines using a shader.
auto screensaver_slideshow_scanlines = std::make_shared<SwitchComponent>();
screensaver_slideshow_scanlines->setState(
@ -163,7 +162,6 @@ void GuiScreensaverOptions::openSlideshowScreensaverOptions()
s->setNeedsSaving();
}
});
#endif
// Whether to use custom images.
auto screensaver_slideshow_custom_images = std::make_shared<SwitchComponent>();
@ -262,7 +260,6 @@ void GuiScreensaverOptions::openVideoScreensaverOptions()
}
});
#if defined(USE_OPENGL_21)
// Render scanlines using a shader.
auto screensaver_video_scanlines = std::make_shared<SwitchComponent>();
screensaver_video_scanlines->setState(
@ -289,7 +286,6 @@ void GuiScreensaverOptions::openVideoScreensaverOptions()
s->setNeedsSaving();
}
});
#endif
s->setSize(mSize);
mWindow->pushGui(s);

View file

@ -150,8 +150,6 @@ set(CORE_SOURCES
# Renderer
${CMAKE_CURRENT_SOURCE_DIR}/src/renderers/Renderer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/renderers/Renderer_GL21.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/renderers/Renderer_GLES10.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/renderers/Renderer_GLES20.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/renderers/Shader_GL21.cpp
# Resources

View file

@ -20,9 +20,7 @@
#include <algorithm>
#include <iomanip>
#if defined(USE_OPENGL_21)
#define CLOCK_BACKGROUND_CREATION false
#endif
Window::Window() noexcept
: mScreensaver {nullptr}
@ -124,12 +122,10 @@ bool Window::init()
mDefaultFonts.push_back(Font::get(FONT_SIZE_LARGE));
}
mBackgroundOverlay->setImage(":/graphics/screen_gradient.png");
mBackgroundOverlay->setImage(":/graphics/frame.png");
mBackgroundOverlay->setResize(Renderer::getScreenWidth(), Renderer::getScreenHeight());
#if defined(USE_OPENGL_21)
mPostprocessedBackground = TextureResource::get("");
#endif
mListScrollFont = Font::get(FONT_SIZE_LARGE);
@ -146,9 +142,7 @@ void Window::deinit()
for (auto it = mGuiStack.cbegin(); it != mGuiStack.cend(); ++it)
(*it)->onHide();
#if defined(USE_OPENGL_21)
mPostprocessedBackground.reset();
#endif
InputManager::getInstance().deinit();
ResourceManager::getInstance().unloadAll();
@ -445,7 +439,6 @@ void Window::render()
bottom->render(trans);
if (bottom != top || mRenderLaunchScreen) {
#if defined(USE_OPENGL_21)
if (!mCachedBackground && mInvalidateCacheTimer == 0) {
// Generate a cache texture of the shaded background when opening the menu, which
// will remain valid until the menu is closed. This is way faster than having to
@ -483,7 +476,8 @@ void Window::render()
// Also dim the background slightly.
backgroundParameters.dimming = 0.60f;
Renderer::shaderPostprocessing(Renderer::SHADER_BLUR_HORIZONTAL |
Renderer::shaderPostprocessing(Renderer::SHADER_CORE |
Renderer::SHADER_BLUR_HORIZONTAL |
Renderer::SHADER_BLUR_VERTICAL,
backgroundParameters, &processedTexture[0]);
}
@ -527,7 +521,6 @@ void Window::render()
mBackgroundOverlayOpacity =
glm::clamp(mBackgroundOverlayOpacity + 0.118f, 0.0f, 1.0f);
}
#endif // USE_OPENGL_21
mBackgroundOverlay->render(trans);

View file

@ -172,10 +172,7 @@ private:
GuiInfoPopup* mInfoPopup;
std::queue<std::pair<std::string, int>> mInfoPopupQueue;
#if defined(USE_OPENGL_21)
std::shared_ptr<TextureResource> mPostprocessedBackground;
#endif
std::string mListScrollText;
std::shared_ptr<Font> mListScrollFont;

View file

@ -44,11 +44,6 @@ GIFAnimComponent::GIFAnimComponent()
{
// Get an empty texture for rendering the animation.
mTexture = TextureResource::get("");
#if defined(USE_OPENGLES_10) || defined(USE_OPENGLES_20)
// This is not really supported by the OpenGL ES standard so hopefully it works
// with all drivers and on all operating systems.
mTexture->setFormat(Renderer::Texture::BGRA);
#endif
mAnimIO.read_proc = readProc;
mAnimIO.write_proc = writeProc;

View file

@ -39,11 +39,6 @@ LottieAnimComponent::LottieAnimComponent()
{
// Get an empty texture for rendering the animation.
mTexture = TextureResource::get("");
#if defined(USE_OPENGLES_10) || defined(USE_OPENGLES_20)
// This is not really supported by the OpenGL ES standard so hopefully it works
// with all drivers and on all operating systems.
mTexture->setFormat(Renderer::Texture::BGRA);
#endif
// Keep per-file cache size within 0 to 1024 MiB.
mMaxCacheSize = static_cast<size_t>(

View file

@ -47,11 +47,15 @@ namespace Renderer
};
static std::vector<Shader*> sShaderProgramVector;
static GLuint shaderFBO1;
static GLuint shaderFBO2;
// This is simply to get rid of a GCC false positive -Wunused-variable compiler warning.
static GLuint shaderFBO1 {0};
static GLuint shaderFBO2 {0};
static GLuint vertexBuffer1 {0};
static GLuint vertexBuffer2 {0};
// This is simply to get rid of some GCC false positive -Wunused-variable compiler warnings.
static GLuint shaderFBODummy1 {shaderFBO1};
static GLuint shaderFBODummy2 {shaderFBO2};
static GLuint vertexBufferDummy1 {vertexBuffer1};
static GLuint vertexBufferDummy2 {vertexBuffer2};
static constexpr glm::mat4 getIdentity() { return glm::mat4 {1.0f}; }
static inline glm::mat4 mTrans {getIdentity()};
@ -64,11 +68,11 @@ namespace Renderer
const GLenum errorCode = glGetError();
if (errorCode != GL_NO_ERROR) {
#if defined(USE_OPENGL_21)
LOG(LogError) << "OpenGL error: " << _funcName << " failed with error code: 0x"
#if defined(USE_OPENGLES)
LOG(LogError) << "OpenGL ES error: " << _funcName << " failed with error code: 0x"
<< std::hex << errorCode;
#else
LOG(LogError) << "OpenGL ES error: " << _funcName << " failed with error code: 0x"
LOG(LogError) << "OpenGL error: " << _funcName << " failed with error code: 0x"
<< std::hex << errorCode;
#endif
}
@ -98,7 +102,7 @@ namespace Renderer
enum Type {
RGBA, // Replace with AllowShortEnumsOnASingleLine: false (clang-format >=11.0).
BGRA,
ALPHA
RED
};
}
@ -124,6 +128,7 @@ namespace Renderer
float saturation;
float dimming;
bool convertBGRAToRGBA;
bool font;
bool postProcessing;
unsigned int shaders;
@ -132,6 +137,7 @@ namespace Renderer
, saturation {1.0f}
, dimming {1.0f}
, convertBGRAToRGBA {false}
, font {false}
, postProcessing {false}
, shaders {0}
{
@ -144,6 +150,7 @@ namespace Renderer
, saturation {1.0f}
, dimming {1.0f}
, convertBGRAToRGBA {false}
, font {false}
, postProcessing {false}
, shaders {0}
{

View file

@ -3,11 +3,9 @@
// EmulationStation Desktop Edition
// Renderer_GL21.cpp
//
// OpenGL 2.1 rendering functions.
// OpenGL / OpenGL ES renderer.
//
#if defined(USE_OPENGL_21)
#include "Settings.h"
#include "Shader_GL21.h"
#include "renderers/Renderer.h"
@ -47,8 +45,12 @@ namespace Renderer
// clang-format off
switch (type) {
case Texture::RGBA: { return GL_RGBA; } break;
#if defined(USE_OPENGLES)
case Texture::BGRA: { return GL_BGRA_EXT; } break;
#else
case Texture::BGRA: { return GL_BGRA; } break;
case Texture::ALPHA: { return GL_LUMINANCE_ALPHA; } break;
#endif
case Texture::RED: { return GL_RED; } break;
default: { return GL_ZERO; }
}
// clang-format on
@ -56,15 +58,16 @@ namespace Renderer
void setupWindow()
{
#if defined(__APPLE__)
// This is required on macOS, as the operating system will otherwise insist on using
// a newer OpenGL version which completely breaks the application.
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
#if defined(USE_OPENGLES)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#else
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
#endif
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
@ -75,7 +78,6 @@ namespace Renderer
bool createContext()
{
bool missingExtension = false;
sdlContext = SDL_GL_CreateContext(getSDLWindow());
if (!sdlContext) {
@ -103,46 +105,37 @@ namespace Renderer
LOG(LogInfo) << "GL renderer: " << renderer;
LOG(LogInfo) << "GL version: " << version;
#if defined(_WIN64)
LOG(LogInfo) << "EmulationStation renderer: OpenGL 2.1 with GLEW";
LOG(LogInfo) << "EmulationStation renderer: OpenGL 3.3 with GLEW";
#else
LOG(LogInfo) << "EmulationStation renderer: OpenGL 2.1";
#if defined(USE_OPENGLES)
LOG(LogInfo) << "EmulationStation renderer: OpenGL ES 3.0";
#else
LOG(LogInfo) << "EmulationStation renderer: OpenGL 3.3";
#endif
LOG(LogInfo) << "Checking available OpenGL extensions...";
std::string glExts = glGetString(GL_EXTENSIONS) ?
reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)) :
"";
if (extensions.find("GL_ARB_texture_non_power_of_two") == std::string::npos) {
LOG(LogError) << "GL_ARB_texture_non_power_of_two: MISSING";
missingExtension = true;
}
else {
LOG(LogInfo) << "GL_ARB_texture_non_power_of_two: OK";
}
if (extensions.find("GL_ARB_vertex_shader") == std::string::npos) {
LOG(LogError) << "GL_ARB_vertex_shader: MISSING";
missingExtension = true;
}
else {
LOG(LogInfo) << "GL_ARB_vertex_shader: OK";
}
if (extensions.find("GL_ARB_fragment_shader") == std::string::npos) {
LOG(LogError) << "GL_ARB_fragment_shader: MISSING";
missingExtension = true;
}
else {
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) {
LOG(LogError) << "Required OpenGL extensions missing.";
return false;
}
#endif
#if !defined(USE_OPENGLES)
// TODO: Fix the issue that causes the first glClearColor function call to fail.
GL_CHECK_ERROR(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
#endif
GL_CHECK_ERROR(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
GL_CHECK_ERROR(glActiveTexture(GL_TEXTURE0));
GL_CHECK_ERROR(glEnable(GL_BLEND));
GL_CHECK_ERROR(glPixelStorei(GL_PACK_ALIGNMENT, 1));
GL_CHECK_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
// These are used for the shader post processing.
GL_CHECK_ERROR(glGenFramebuffers(1, &shaderFBO1));
GL_CHECK_ERROR(glGenFramebuffers(1, &shaderFBO2));
GL_CHECK_ERROR(glGenBuffers(1, &vertexBuffer1));
GL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer1));
GL_CHECK_ERROR(glGenVertexArrays(1, &vertexBuffer2));
GL_CHECK_ERROR(glBindVertexArray(vertexBuffer2));
uint8_t data[4] = {255, 255, 255, 255};
whiteTexture = createTexture(Texture::RGBA, false, false, true, 1, 1, data);
postProcTexture1 = createTexture(Texture::RGBA, false, false, false,
static_cast<unsigned int>(getScreenWidth()),
@ -152,21 +145,16 @@ namespace Renderer
static_cast<unsigned int>(getScreenWidth()),
static_cast<unsigned int>(getScreenHeight()), nullptr);
uint8_t data[4] = {255, 255, 255, 255};
whiteTexture = createTexture(Texture::RGBA, false, false, true, 1, 1, data);
// Attach textures to the shader framebuffers.
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, shaderFBO1));
GL_CHECK_ERROR(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
postProcTexture1, 0));
GL_CHECK_ERROR(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
GL_CHECK_ERROR(glEnable(GL_TEXTURE_2D));
GL_CHECK_ERROR(glEnable(GL_BLEND));
GL_CHECK_ERROR(glPixelStorei(GL_PACK_ALIGNMENT, 1));
GL_CHECK_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
GL_CHECK_ERROR(glEnableClientState(GL_VERTEX_ARRAY));
GL_CHECK_ERROR(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
GL_CHECK_ERROR(glEnableClientState(GL_COLOR_ARRAY));
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, shaderFBO2));
GL_CHECK_ERROR(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
postProcTexture2, 0));
// These framebuffers are used for the shader post processing.
GL_CHECK_ERROR(glGenFramebuffers(1, &shaderFBO1));
GL_CHECK_ERROR(glGenFramebuffers(1, &shaderFBO2));
GL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0));
return true;
}
@ -209,24 +197,8 @@ namespace Renderer
linearMagnify ? static_cast<GLfloat>(GL_LINEAR) :
static_cast<GLfloat>(GL_NEAREST)));
if (textureType == GL_LUMINANCE_ALPHA) {
uint8_t* a_data {reinterpret_cast<uint8_t*>(data)};
uint8_t* la_data {new uint8_t[width * height * 2]};
for (uint32_t i = 0; i < (width * height); ++i) {
la_data[(i * 2) + 0] = 255;
la_data[(i * 2) + 1] = a_data ? a_data[i] : 255;
}
GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, textureType, width, height, 0,
textureType, GL_UNSIGNED_BYTE, la_data));
delete[] la_data;
}
else {
GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, textureType, width, height, 0,
textureType, GL_UNSIGNED_BYTE, data));
}
GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, textureType, width, height, 0, textureType,
GL_UNSIGNED_BYTE, data));
return texture;
}
@ -246,26 +218,8 @@ namespace Renderer
const GLenum textureType = convertTextureType(type);
GL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
// Regular GL_ALPHA textures are black + alpha when used in shaders, so create a
// GL_LUMINANCE_ALPHA texture instead so it's white + alpha.
if (textureType == GL_LUMINANCE_ALPHA) {
uint8_t* a_data {reinterpret_cast<uint8_t*>(data)};
uint8_t* la_data {new uint8_t[width * height * 2]};
for (uint32_t i = 0; i < (width * height); ++i) {
la_data[(i * 2) + 0] = 255;
la_data[(i * 2) + 1] = a_data ? a_data[i] : 255;
}
GL_CHECK_ERROR(glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, textureType,
GL_UNSIGNED_BYTE, la_data));
delete[] la_data;
}
else {
GL_CHECK_ERROR(glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, textureType,
GL_UNSIGNED_BYTE, data));
}
GL_CHECK_ERROR(glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, textureType,
GL_UNSIGNED_BYTE, data));
GL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, whiteTexture));
}
@ -286,51 +240,57 @@ namespace Renderer
const float width {vertices[3].position[0]};
const float height {vertices[3].position[1]};
GL_CHECK_ERROR(glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &vertices[0].position));
GL_CHECK_ERROR(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &vertices[0].texture));
GL_CHECK_ERROR(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &vertices[0].color));
GL_CHECK_ERROR(
glBlendFunc(convertBlendFactor(srcBlendFactor), convertBlendFactor(dstBlendFactor)));
if (vertices->shaders == 0 || vertices->shaders & SHADER_CORE) {
Shader* runShader = getShaderProgram(SHADER_CORE);
if (runShader) {
runShader->activateShaders();
runShader->setModelViewProjectionMatrix(mTrans);
runShader->setOpacity(vertices->opacity);
runShader->setSaturation(vertices->saturation);
runShader->setDimming(vertices->dimming);
runShader->setBGRAToRGBA(vertices->convertBGRAToRGBA);
runShader->setPostProcessing(vertices->postProcessing);
Shader* shader {getShaderProgram(SHADER_CORE)};
if (shader) {
shader->activateShaders();
shader->setModelViewProjectionMatrix(mTrans);
shader->setAttribPointers();
GL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * numVertices, vertices,
GL_DYNAMIC_DRAW));
shader->setOpacity(vertices->opacity);
shader->setSaturation(vertices->saturation);
shader->setDimming(vertices->dimming);
shader->setBGRAToRGBA(vertices->convertBGRAToRGBA);
shader->setFont(vertices->font);
shader->setPostProcessing(vertices->postProcessing);
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, numVertices));
runShader->deactivateShaders();
shader->deactivateShaders();
}
}
else if (vertices->shaders & SHADER_BLUR_HORIZONTAL) {
Shader* runShader = getShaderProgram(SHADER_BLUR_HORIZONTAL);
if (runShader) {
runShader->activateShaders();
runShader->setModelViewProjectionMatrix(mTrans);
runShader->setTextureSize({width, height});
Shader* shader {getShaderProgram(SHADER_BLUR_HORIZONTAL)};
if (shader) {
shader->activateShaders();
shader->setModelViewProjectionMatrix(mTrans);
shader->setAttribPointers();
GL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * numVertices, vertices,
GL_DYNAMIC_DRAW));
shader->setTextureSize({width, height});
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, numVertices));
runShader->deactivateShaders();
shader->deactivateShaders();
}
return;
}
else if (vertices->shaders & SHADER_BLUR_VERTICAL) {
Shader* runShader = getShaderProgram(SHADER_BLUR_VERTICAL);
if (runShader) {
runShader->activateShaders();
runShader->setModelViewProjectionMatrix(mTrans);
runShader->setTextureSize({width, height});
Shader* shader {getShaderProgram(SHADER_BLUR_VERTICAL)};
if (shader) {
shader->activateShaders();
shader->setModelViewProjectionMatrix(mTrans);
shader->setAttribPointers();
GL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * numVertices, vertices,
GL_DYNAMIC_DRAW));
shader->setTextureSize({width, height});
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, numVertices));
runShader->deactivateShaders();
shader->deactivateShaders();
}
return;
}
else if (vertices->shaders & SHADER_SCANLINES) {
Shader* runShader {getShaderProgram(SHADER_SCANLINES)};
Shader* shader {getShaderProgram(SHADER_SCANLINES)};
float shaderWidth {width * 1.2f};
// Scale the scanlines relative to screen resolution.
float screenHeightModifier {getScreenHeightModifier()};
@ -350,13 +310,16 @@ namespace Renderer
float modifier {1.41f + relativeAdjustment / 7.0f - (0.14f * screenHeightModifier)};
shaderHeight = height * modifier;
}
if (runShader) {
runShader->activateShaders();
runShader->setModelViewProjectionMatrix(mTrans);
runShader->setOpacity(vertices->opacity);
runShader->setTextureSize({shaderWidth, shaderHeight});
if (shader) {
shader->activateShaders();
shader->setModelViewProjectionMatrix(mTrans);
shader->setAttribPointers();
GL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * numVertices, vertices,
GL_DYNAMIC_DRAW));
shader->setOpacity(vertices->opacity);
shader->setTextureSize({shaderWidth, shaderHeight});
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, numVertices));
runShader->deactivateShaders();
shader->deactivateShaders();
}
}
}
@ -446,8 +409,8 @@ namespace Renderer
vertices->dimming = parameters.dimming;
vertices->postProcessing = true;
shaderList.emplace_back(Renderer::SHADER_CORE);
if (shaders & Renderer::SHADER_CORE)
shaderList.push_back(Renderer::SHADER_CORE);
if (shaders & Renderer::SHADER_BLUR_HORIZONTAL)
shaderList.push_back(Renderer::SHADER_BLUR_HORIZONTAL);
if (shaders & Renderer::SHADER_BLUR_VERTICAL)
@ -458,16 +421,8 @@ namespace Renderer
setMatrix(getIdentity());
bindTexture(postProcTexture1);
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, shaderFBO2));
GL_CHECK_ERROR(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
postProcTexture2, 0));
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, shaderFBO1));
// Attach texture to the shader framebuffer.
GL_CHECK_ERROR(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
postProcTexture1, 0));
// Blit the screen contents to postProcTexture.
GL_CHECK_ERROR(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
GL_COLOR_BUFFER_BIT, GL_NEAREST));
@ -545,5 +500,3 @@ namespace Renderer
}
} // namespace Renderer
#endif // USE_OPENGL_21

View file

@ -6,8 +6,6 @@
// OpenGL 2.1 GLSL shader functions.
//
#if defined(USE_OPENGL_21)
#include "Shader_GL21.h"
#include "Log.h"
@ -19,11 +17,16 @@ namespace Renderer
Renderer::Shader::Shader()
: mProgramID {0}
, shaderMVPMatrix {0}
, shaderTextureSize {0}
, shaderPosition {0}
, shaderTextureCoord {0}
, shaderColor {0}
, shaderTextureSize {0}
, shaderOpacity {0}
, shaderSaturation {0}
, shaderDimming {0}
, shaderBGRAToRGBA {0}
, shaderFont {0}
, shaderPostProcessing {0}
{
}
@ -42,9 +45,12 @@ namespace Renderer
const ResourceData& shaderData {ResourceManager::getInstance().getFileData(path)};
shaderCode.assign(reinterpret_cast<const char*>(shaderData.ptr.get()), shaderData.length);
// Define the GLSL version (version 120 = OpenGL 2.1).
preprocessorDefines = "#version 120\n";
// Define the GLSL version.
#if defined(USE_OPENGLES)
preprocessorDefines = "#version 300 es\n";
#else
preprocessorDefines = "#version 330\n";
#endif
// Define the preprocessor constants that will let the shader compiler know whether
// the VERTEX or FRAGMENT portion of the code should be used.
if (shaderType == GL_VERTEX_SHADER)
@ -76,9 +82,12 @@ namespace Renderer
if (shaderCompiled != GL_TRUE) {
LOG(LogError) << "OpenGL error: Unable to compile shader " << currentShader << " ("
<< std::get<0>(*it) << ").";
printShaderInfoLog(currentShader, std::get<2>(*it));
printShaderInfoLog(currentShader, std::get<2>(*it), true);
return false;
}
else {
printShaderInfoLog(currentShader, std::get<2>(*it), false);
}
GL_CHECK_ERROR(glAttachShader(mProgramID, currentShader));
}
@ -93,6 +102,16 @@ namespace Renderer
}
getVariableLocations(mProgramID);
if (shaderPosition != -1)
GL_CHECK_ERROR(glEnableVertexAttribArray(shaderPosition));
if (shaderTextureCoord != -1)
GL_CHECK_ERROR(glEnableVertexAttribArray(shaderTextureCoord));
if (shaderColor != -1)
GL_CHECK_ERROR(glEnableVertexAttribArray(shaderColor));
return true;
}
@ -105,12 +124,15 @@ namespace Renderer
{
// Some of the variable names are chosen to be compatible with the RetroArch GLSL shaders.
shaderMVPMatrix = glGetUniformLocation(mProgramID, "MVPMatrix");
shaderTextureSize = glGetUniformLocation(mProgramID, "TextureSize");
shaderPosition = glGetAttribLocation(mProgramID, "positionAttrib");
shaderTextureCoord = glGetAttribLocation(mProgramID, "TexCoord");
shaderColor = glGetAttribLocation(mProgramID, "colorAttrib");
shaderTextureSize = glGetUniformLocation(mProgramID, "TextureSize");
shaderOpacity = glGetUniformLocation(mProgramID, "opacity");
shaderSaturation = glGetUniformLocation(mProgramID, "saturation");
shaderDimming = glGetUniformLocation(mProgramID, "dimming");
shaderBGRAToRGBA = glGetUniformLocation(mProgramID, "BGRAToRGBA");
shaderFont = glGetUniformLocation(mProgramID, "font");
shaderPostProcessing = glGetUniformLocation(mProgramID, "postProcessing");
}
@ -121,48 +143,62 @@ namespace Renderer
reinterpret_cast<GLfloat*>(&mvpMatrix)));
}
void Renderer::Shader::setTextureSize(std::array<GLfloat, 2> shaderVec2)
void Renderer::Shader::setAttribPointers()
{
if (shaderTextureSize != GL_INVALID_VALUE && shaderTextureSize != GL_INVALID_OPERATION)
GL_CHECK_ERROR(glUniform2f(shaderTextureSize, shaderVec2[0], shaderVec2[1]));
if (shaderPosition != -1)
GL_CHECK_ERROR(
glVertexAttribPointer(shaderPosition, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<const void*>(offsetof(Vertex, position))));
if (shaderTextureCoord != -1)
GL_CHECK_ERROR(
glVertexAttribPointer(shaderTextureCoord, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<const void*>(offsetof(Vertex, texture))));
if (shaderColor != -1)
GL_CHECK_ERROR(
glVertexAttribPointer(shaderColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex),
reinterpret_cast<const void*>(offsetof(Vertex, color))));
}
void Renderer::Shader::setTextureCoordinates(std::array<GLfloat, 4> shaderVec4)
void Renderer::Shader::setTextureSize(std::array<GLfloat, 2> shaderVec2)
{
if (shaderTextureCoord != GL_INVALID_OPERATION) {
glVertexAttrib4f(shaderTextureCoord, shaderVec4[0], shaderVec4[1], shaderVec4[2],
shaderVec4[3]);
}
if (shaderTextureSize != -1)
GL_CHECK_ERROR(glUniform2f(shaderTextureSize, shaderVec2[0], shaderVec2[1]));
}
void Renderer::Shader::setOpacity(GLfloat opacity)
{
if (shaderOpacity != GL_INVALID_VALUE && shaderOpacity != GL_INVALID_OPERATION)
if (shaderOpacity != -1)
GL_CHECK_ERROR(glUniform1f(shaderOpacity, opacity));
}
void Renderer::Shader::setSaturation(GLfloat saturation)
{
if (shaderSaturation != GL_INVALID_VALUE && shaderSaturation != GL_INVALID_OPERATION)
if (shaderSaturation != -1)
GL_CHECK_ERROR(glUniform1f(shaderSaturation, saturation));
}
void Renderer::Shader::setDimming(GLfloat dimming)
{
if (shaderDimming != GL_INVALID_VALUE && shaderDimming != GL_INVALID_OPERATION)
if (shaderDimming != -1)
GL_CHECK_ERROR(glUniform1f(shaderDimming, dimming));
}
void Renderer::Shader::setBGRAToRGBA(GLboolean BGRAToRGBA)
{
if (shaderBGRAToRGBA != GL_INVALID_VALUE && shaderBGRAToRGBA != GL_INVALID_OPERATION)
if (shaderBGRAToRGBA != -1)
GL_CHECK_ERROR(glUniform1i(shaderBGRAToRGBA, BGRAToRGBA ? 1 : 0));
}
void Renderer::Shader::setFont(GLboolean font)
{
if (shaderFont != -1)
GL_CHECK_ERROR(glUniform1i(shaderFont, font ? 1 : 0));
}
void Renderer::Shader::setPostProcessing(GLboolean postProcessing)
{
if (shaderPostProcessing != GL_INVALID_VALUE &&
shaderPostProcessing != GL_INVALID_OPERATION)
if (shaderPostProcessing != -1)
GL_CHECK_ERROR(glUniform1i(shaderPostProcessing, postProcessing ? 1 : 0));
}
@ -199,7 +235,7 @@ namespace Renderer
}
}
void Renderer::Shader::printShaderInfoLog(GLuint shaderID, GLenum shaderType)
void Renderer::Shader::printShaderInfoLog(GLuint shaderID, GLenum shaderType, bool error)
{
if (glIsShader(shaderID)) {
int logLength;
@ -208,10 +244,14 @@ namespace Renderer
glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<char> infoLog(maxLength);
if (infoLog.size() == 0)
return;
glGetShaderInfoLog(shaderID, maxLength, &logLength, &infoLog.front());
if (logLength > 0) {
LOG(LogDebug) << "Shader_GL21::printShaderInfoLog(): Error in "
LOG(LogDebug) << "Shader_GL21::printShaderInfoLog(): "
<< (error ? "Error" : "Warning") << " in "
<< (shaderType == GL_VERTEX_SHADER ? "VERTEX section:\n" :
"FRAGMENT section:\n")
<< std::string(infoLog.begin(), infoLog.end());
@ -223,5 +263,3 @@ namespace Renderer
}
} // namespace Renderer
#endif // USE_OPENGL_21

View file

@ -18,11 +18,11 @@
#endif
#include <SDL2/SDL.h>
// Hack until shader support has been added for OpenGL ES.
#if defined(USE_OPENGL_21)
#include <SDL2/SDL_opengl.h>
#else
#if defined(USE_OPENGLES)
#include <GLES3/gl3.h>
#include <SDL2/SDL_opengles.h>
#else
#include <SDL2/SDL_opengl.h>
#endif
#include <array>
#include <string>
@ -47,12 +47,13 @@ namespace Renderer
// One-way communication with the compiled shaders.
void setModelViewProjectionMatrix(glm::mat4 mvpMatrix);
void setAttribPointers();
void setTextureSize(std::array<GLfloat, 2> shaderVec2);
void setTextureCoordinates(std::array<GLfloat, 4> shaderVec4);
void setOpacity(GLfloat opacity);
void setSaturation(GLfloat saturation);
void setDimming(GLfloat dimming);
void setBGRAToRGBA(GLboolean BGRAToRGBA);
void setFont(GLboolean font);
void setPostProcessing(GLboolean postProcessing);
// Sets the shader program to use the loaded shaders.
void activateShaders();
@ -62,7 +63,7 @@ namespace Renderer
GLuint getProgramID() { return mProgramID; }
// Only used for error logging if the shaders fail to compile or link.
void printProgramInfoLog(GLuint programID);
void printShaderInfoLog(GLuint shaderID, GLenum shaderType);
void printShaderInfoLog(GLuint shaderID, GLenum shaderType, bool error);
private:
GLuint mProgramID;
@ -70,12 +71,15 @@ namespace Renderer
// Variables used for communication with the compiled shaders.
GLint shaderMVPMatrix;
GLint shaderTextureSize;
GLint shaderPosition;
GLint shaderTextureCoord;
GLint shaderColor;
GLint shaderTextureSize;
GLint shaderOpacity;
GLint shaderSaturation;
GLint shaderDimming;
GLint shaderBGRAToRGBA;
GLint shaderFont;
GLint shaderPostProcessing;
};

View file

@ -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::RED, false, false, false, textureSize.x,
textureSize.y, nullptr);
}
void Font::FontTexture::deinitTexture()
@ -346,8 +346,8 @@ Font::Glyph* Font::getGlyph(unsigned int id)
static_cast<float>(g->metrics.horiBearingY) / 64.0f};
// Upload glyph bitmap to texture.
Renderer::updateTexture(tex->textureId, Renderer::Texture::ALPHA, cursor.x, cursor.y,
glyphSize.x, glyphSize.y, g->bitmap.buffer);
Renderer::updateTexture(tex->textureId, Renderer::Texture::RED, cursor.x, cursor.y, glyphSize.x,
glyphSize.y, g->bitmap.buffer);
// Update max glyph height.
if (glyphSize.y > mMaxGlyphHeight)
@ -380,7 +380,7 @@ void Font::rebuildTextures()
static_cast<int>(it->second.texSize.y * tex->textureSize.y)};
// Upload to texture.
Renderer::updateTexture(tex->textureId, Renderer::Texture::ALPHA, cursor.x, cursor.y,
Renderer::updateTexture(tex->textureId, Renderer::Texture::RED, cursor.x, cursor.y,
glyphSize.x, glyphSize.y, glyphSlot->bitmap.buffer);
}
}
@ -392,10 +392,11 @@ void Font::renderTextCache(TextCache* cache)
return;
}
for (auto it = cache->vertexLists.cbegin(); it != cache->vertexLists.cend(); ++it) {
for (auto it = cache->vertexLists.begin(); it != cache->vertexLists.end(); ++it) {
assert(*it->textureIdPtr != 0);
auto vertexList = *it;
it->verts[0].font = true;
Renderer::bindTexture(*it->textureIdPtr);
Renderer::drawTriangleStrips(&it->verts[0],

View file

@ -18,7 +18,6 @@
#else
#define COMPAT_VARYING varying
#define COMPAT_ATTRIBUTE attribute
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
@ -27,39 +26,19 @@
#define COMPAT_PRECISION
#endif
COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 COLOR;
COMPAT_ATTRIBUTE vec2 positionAttrib;
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 = MVPMatrix * gl_Vertex;
COL0 = COLOR;
TEX0.xy = gl_MultiTexCoord0.xy;
gl_Position = MVPMatrix * vec4(positionAttrib.xy, 0.0, 1.0);
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;
@ -71,20 +50,25 @@ precision mediump float;
#define COMPAT_PRECISION
#endif
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out COMPAT_PRECISION vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
COMPAT_VARYING vec4 TEX0;
COMPAT_VARYING COMPAT_PRECISION 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()
{
@ -129,8 +113,9 @@ void main()
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};
float sampleOffsets[5] = float[5](0.0, 1.4347826, 3.3478260, 5.2608695, 7.1739130);
float sampleWeights[5] =
float[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++) {

View file

@ -18,7 +18,6 @@
#else
#define COMPAT_VARYING varying
#define COMPAT_ATTRIBUTE attribute
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
@ -27,39 +26,19 @@
#define COMPAT_PRECISION
#endif
COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 COLOR;
COMPAT_ATTRIBUTE vec2 positionAttrib;
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 = MVPMatrix * gl_Vertex;
COL0 = COLOR;
TEX0.xy = gl_MultiTexCoord0.xy;
gl_Position = MVPMatrix * vec4(positionAttrib.xy, 0.0, 1.0);
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;
@ -71,20 +50,25 @@ precision mediump float;
#define COMPAT_PRECISION
#endif
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out COMPAT_PRECISION vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
COMPAT_VARYING vec4 TEX0;
COMPAT_VARYING COMPAT_PRECISION 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()
{
@ -129,8 +113,9 @@ void main()
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};
float sampleOffsets[5] = float[5](0.0, 1.4347826, 3.3478260, 5.2608695, 7.1739130);
float sampleWeights[5] =
float[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++) {

View file

@ -12,71 +12,98 @@
#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_ATTRIBUTE in
#else
#define COMPAT_VARYING varying
#define COMPAT_ATTRIBUTE attribute
#endif
#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
uniform mat4 MVPMatrix;
COMPAT_ATTRIBUTE vec2 positionAttrib;
COMPAT_ATTRIBUTE vec2 TexCoord;
COMPAT_ATTRIBUTE vec4 colorAttrib;
COMPAT_VARYING vec4 color;
COMPAT_VARYING vec2 texCoord;
void main(void)
{
texCoord = gl_MultiTexCoord0.xy;
color.rgba = gl_Color.abgr;
gl_Position = MVPMatrix * gl_Vertex;
color.rgba = colorAttrib.abgr;
texCoord = TexCoord;
gl_Position = MVPMatrix * vec4(positionAttrib.xy, 0.0, 1.0);
}
#elif defined(FRAGMENT)
// Fragment section of code:
#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out COMPAT_PRECISION vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define COMPAT_TEXTURE texture2D
#define FragColor gl_FragColor
#endif
COMPAT_VARYING vec4 color;
COMPAT_VARYING vec2 texCoord;
uniform float opacity = 1.0f;
uniform float saturation = 1.0f;
uniform float dimming = 1.0f;
uniform int BGRAToRGBA = 0;
uniform int postProcessing = 0;
COMPAT_VARYING COMPAT_PRECISION vec4 color;
COMPAT_VARYING COMPAT_PRECISION vec4 color2;
COMPAT_VARYING COMPAT_PRECISION vec2 texCoord;
uniform COMPAT_PRECISION float opacity;
uniform COMPAT_PRECISION float saturation;
uniform COMPAT_PRECISION float dimming;
uniform int BGRAToRGBA;
uniform int font;
uniform int postProcessing;
uniform sampler2D myTexture;
void main()
{
vec4 color = COMPAT_TEXTURE(myTexture, texCoord) * color;
COMPAT_PRECISION vec4 sampledColor = COMPAT_TEXTURE(myTexture, texCoord);
// For fonts the alpha information is stored in the red channel.
if (font == 1)
sampledColor = vec4(1.0f, 1.0f, 1.0f, sampledColor.r);
sampledColor *= color;
// When post-processing we drop the alpha channel to avoid strange issues
// with some graphics drivers.
if (postProcessing == 1)
color.a = 1.0f;
sampledColor.a = 1.0f;
// Opacity.
if (opacity != 1.0f)
color.a = color.a * opacity;
sampledColor.a = sampledColor.a * opacity;
// Saturation.
if (saturation != 1.0f) {
vec3 grayscale = vec3(dot(color.rgb, vec3(0.34f, 0.55f, 0.11f)));
vec3 blendedColor = mix(grayscale, color.rgb, saturation);
color = vec4(blendedColor, color.a);
COMPAT_PRECISION vec3 grayscale = vec3(dot(sampledColor.rgb, vec3(0.34f, 0.55f, 0.11f)));
COMPAT_PRECISION vec3 blendedColor = mix(grayscale, sampledColor.rgb, saturation);
sampledColor = vec4(blendedColor, sampledColor.a);
}
// Dimming
if (dimming != 1.0f) {
vec4 dimColor = vec4(dimming, dimming, dimming, 1.0f);
color *= dimColor;
COMPAT_PRECISION vec4 dimColor = vec4(dimming, dimming, dimming, 1.0f);
sampledColor *= dimColor;
}
// BGRA to RGBA conversion.
if (BGRAToRGBA == 1)
color = vec4(color.bgr, color.a);
sampledColor = vec4(sampledColor.bgr, sampledColor.a);
gl_FragColor = color;
FragColor = sampledColor;
}
#endif

View file

@ -29,7 +29,6 @@
#else
#define COMPAT_VARYING varying
#define COMPAT_ATTRIBUTE attribute
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
@ -38,45 +37,27 @@
#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;
COMPAT_ATTRIBUTE vec2 positionAttrib;
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 = MVPMatrix * gl_Vertex;
COL0 = COLOR;
TEX0.xy = gl_MultiTexCoord0.xy;
gl_Position = MVPMatrix * vec4(positionAttrib.xy, 0.0, 1.0);
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;
@ -88,12 +69,18 @@ precision mediump float;
#define COMPAT_PRECISION
#endif
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out COMPAT_PRECISION vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform COMPAT_PRECISION float opacity = 1.0;
uniform COMPAT_PRECISION float opacity;
uniform sampler2D Texture;
COMPAT_VARYING vec4 TEX0;
COMPAT_VARYING vec2 onex;
@ -104,7 +91,6 @@ COMPAT_VARYING vec2 oney;
#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.