Added support for binding multiple texture units for use in the shaders

This commit is contained in:
Leon Styhre 2023-09-07 21:02:38 +02:00
parent 2f20f1d133
commit 848d19a80b
22 changed files with 115 additions and 87 deletions

View file

@ -572,7 +572,7 @@ void GIFAnimComponent::render(const glm::mat4& parentTrans)
} }
if (mTexture->getSize().x != 0.0f) { if (mTexture->getSize().x != 0.0f) {
mTexture->bind(); mTexture->bind(0);
Renderer::Vertex vertices[4]; Renderer::Vertex vertices[4];

View file

@ -420,14 +420,12 @@ void ImageComponent::render(const glm::mat4& parentTrans)
if (mTexture && mOpacity > 0.0f) { if (mTexture && mOpacity > 0.0f) {
if (Settings::getInstance()->getBool("DebugImage")) { if (Settings::getInstance()->getBool("DebugImage")) {
if (mTargetIsMax) { if (mTargetIsMax) {
const glm::vec2 targetSizePos { const glm::vec2 targetSizePos {(mTargetSize - mSize) * mOrigin * glm::vec2 {-1.0f}};
glm::round((mTargetSize - mSize) * mOrigin * glm::vec2 {-1.0f})};
mRenderer->drawRect(targetSizePos.x, targetSizePos.y, mTargetSize.x, mTargetSize.y, mRenderer->drawRect(targetSizePos.x, targetSizePos.y, mTargetSize.x, mTargetSize.y,
0xFF000033, 0xFF000033); 0xFF000033, 0xFF000033);
} }
if (mClipRegion == glm::vec4 {0.0f, 0.0f, 0.0f, 0.0f}) if (mClipRegion == glm::vec4 {0.0f, 0.0f, 0.0f, 0.0f})
mRenderer->drawRect(0.0f, 0.0f, std::round(mSize.x), std::round(mSize.y), mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0xFF000033, 0xFF000033);
0xFF000033, 0xFF000033);
else else
mRenderer->drawRect(mClipRegion.x, mClipRegion.y, mClipRegion.z - mClipRegion.x, mRenderer->drawRect(mClipRegion.x, mClipRegion.y, mClipRegion.z - mClipRegion.x,
mClipRegion.w - mClipRegion.y, 0xFF000033, 0xFF000033); mClipRegion.w - mClipRegion.y, 0xFF000033, 0xFF000033);
@ -441,9 +439,9 @@ void ImageComponent::render(const glm::mat4& parentTrans)
// getting invalidated, in which case we want to make sure to not get a partially // getting invalidated, in which case we want to make sure to not get a partially
// faded texture rendered onto the new background. // faded texture rendered onto the new background.
if (mWindow->isInvalidatingCachedBackground()) if (mWindow->isInvalidatingCachedBackground())
mTexture->bind(); mTexture->bind(0);
else else
fadeIn(mTexture->bind()); fadeIn(mTexture->bind(0));
mVertices->brightness = mBrightness; mVertices->brightness = mBrightness;
mVertices->opacity = mThemeOpacity; mVertices->opacity = mThemeOpacity;
@ -878,16 +876,16 @@ void ImageComponent::updateVertices()
// We round the vertices already here in this component as we may otherwise end up with edge // We round the vertices already here in this component as we may otherwise end up with edge
// cases at sizes near 0.5. // cases at sizes near 0.5.
for (int i = 0; i < 4; ++i) for (int i {0}; i < 4; ++i)
mVertices[i].position = glm::round(mVertices[i].position); mVertices[i].position = glm::round(mVertices[i].position);
if (mFlipX) { if (mFlipX) {
for (int i = 0; i < 4; ++i) for (int i {0}; i < 4; ++i)
mVertices[i].texcoord[0] = px - mVertices[i].texcoord[0]; mVertices[i].texcoord[0] = px - mVertices[i].texcoord[0];
} }
if (mFlipY) { if (mFlipY) {
for (int i = 0; i < 4; ++i) for (int i {0}; i < 4; ++i)
mVertices[i].texcoord[1] = py - mVertices[i].texcoord[1]; mVertices[i].texcoord[1] = py - mVertices[i].texcoord[1];
} }

View file

@ -563,7 +563,7 @@ void LottieAnimComponent::render(const glm::mat4& parentTrans)
} }
if (mTexture->getSize().x != 0.0f) { if (mTexture->getSize().x != 0.0f) {
mTexture->bind(); mTexture->bind(0);
Renderer::Vertex vertices[4]; Renderer::Vertex vertices[4];

View file

@ -35,7 +35,7 @@ void NinePatchComponent::render(const glm::mat4& parentTrans)
mRenderer->setMatrix(trans); mRenderer->setMatrix(trans);
(*mVertices)[0].opacity = mOpacity; (*mVertices)[0].opacity = mOpacity;
(*mVertices)[0].shaderFlags = Renderer::ShaderFlags::PREMULTIPLIED; (*mVertices)[0].shaderFlags = Renderer::ShaderFlags::PREMULTIPLIED;
mTexture->bind(); mTexture->bind(0);
mRenderer->drawTriangleStrips(&mVertices->at(0), 6 * 9); mRenderer->drawTriangleStrips(&mVertices->at(0), 6 * 9);
} }

View file

@ -257,7 +257,7 @@ void VideoFFmpegComponent::render(const glm::mat4& parentTrans)
} }
if (mTexture != nullptr) if (mTexture != nullptr)
mTexture->bind(); mTexture->bind(0);
// Render scanlines if this option is enabled. However, if this is the media viewer // Render scanlines if this option is enabled. However, if this is the media viewer
// or the video screensaver, then skip this as the scanline rendering is then handled // or the video screensaver, then skip this as the scanline rendering is then handled

View file

@ -487,12 +487,12 @@ void Renderer::drawRect(const float x,
// clang-format on // clang-format on
// Round vertices. // Round vertices.
for (int i = 0; i < 4; ++i) for (int i {0}; i < 4; ++i)
vertices[i].position = glm::round(vertices[i].position); vertices[i].position = glm::round(vertices[i].position);
vertices->opacity = opacity; vertices->opacity = opacity;
vertices->dimming = dimming; vertices->dimming = dimming;
bindTexture(0); bindTexture(0, 0);
drawTriangleStrips(vertices, 4, srcBlendFactor, dstBlendFactor); drawTriangleStrips(vertices, 4, srcBlendFactor, dstBlendFactor);
} }

View file

@ -93,13 +93,11 @@ public:
Vertex(const glm::vec2& positionArg, Vertex(const glm::vec2& positionArg,
const glm::vec2& texcoordArg, const glm::vec2& texcoordArg,
const unsigned int colorArg, const unsigned int colorArg)
const glm::vec4& clipRegionArg = glm::vec4 {0.0f, 0.0f, 0.0f, 0.0f},
const glm::vec2& shadowOffsetArg = glm::vec2 {0.0f, 0.0f})
: position {positionArg} : position {positionArg}
, texcoord {texcoordArg} , texcoord {texcoordArg}
, color {colorArg} , color {colorArg}
, clipRegion {clipRegionArg} , clipRegion {0.0f, 0.0f, 0.0f, 0.0f}
, brightness {0.0f} , brightness {0.0f}
, opacity {1.0f} , opacity {1.0f}
, saturation {1.0f} , saturation {1.0f}
@ -195,15 +193,11 @@ public:
static constexpr glm::mat4 getIdentity() { return glm::mat4 {1.0f}; } static constexpr glm::mat4 getIdentity() { return glm::mat4 {1.0f}; }
glm::mat4 mTrans {getIdentity()}; glm::mat4 mTrans {getIdentity()};
virtual void shaderPostprocessing(
const unsigned int shaders,
const Renderer::postProcessingParams& parameters = postProcessingParams(),
unsigned char* textureRGBA = nullptr) = 0;
virtual void setup() = 0; virtual void setup() = 0;
virtual bool createContext() = 0; virtual bool createContext() = 0;
virtual void destroyContext() = 0; virtual void destroyContext() = 0;
virtual unsigned int createTexture(const TextureType type, virtual unsigned int createTexture(const unsigned int texUnit,
const TextureType type,
const bool linearMinify, const bool linearMinify,
const bool linearMagnify, const bool linearMagnify,
const bool mipmapping, const bool mipmapping,
@ -213,18 +207,23 @@ public:
void* data) = 0; void* data) = 0;
virtual void destroyTexture(const unsigned int texture) = 0; virtual void destroyTexture(const unsigned int texture) = 0;
virtual void updateTexture(const unsigned int texture, virtual void updateTexture(const unsigned int texture,
const unsigned int texUnit,
const TextureType type, const TextureType type,
const unsigned int x, const unsigned int x,
const unsigned int y, const unsigned int y,
const unsigned int width, const unsigned int width,
const unsigned int height, const unsigned int height,
void* data) = 0; void* data) = 0;
virtual void bindTexture(const unsigned int texture) = 0; virtual void bindTexture(const unsigned int texture, const unsigned int texUnit) = 0;
virtual void drawTriangleStrips( virtual void drawTriangleStrips(
const Vertex* vertices, const Vertex* vertices,
const unsigned int numVertices, const unsigned int numVertices,
const BlendFactor srcBlendFactor = BlendFactor::ONE, const BlendFactor srcBlendFactor = BlendFactor::ONE,
const BlendFactor dstBlendFactor = BlendFactor::ONE_MINUS_SRC_ALPHA) = 0; const BlendFactor dstBlendFactor = BlendFactor::ONE_MINUS_SRC_ALPHA) = 0;
virtual void shaderPostprocessing(
const unsigned int shaders,
const Renderer::postProcessingParams& parameters = postProcessingParams(),
unsigned char* textureRGBA = nullptr) = 0;
virtual void setMatrix(const glm::mat4& matrix) = 0; virtual void setMatrix(const glm::mat4& matrix) = 0;
virtual void setViewport(const Rect& viewport) = 0; virtual void setViewport(const Rect& viewport) = 0;
virtual void setScissor(const Rect& scissor) = 0; virtual void setScissor(const Rect& scissor) = 0;

View file

@ -280,7 +280,7 @@ bool RendererOpenGL::createContext()
GL_CHECK_ERROR(glBindVertexArray(mVertexBuffer2)); GL_CHECK_ERROR(glBindVertexArray(mVertexBuffer2));
uint8_t data[4] {255, 255, 255, 255}; uint8_t data[4] {255, 255, 255, 255};
mWhiteTexture = createTexture(TextureType::BGRA, false, false, false, true, 1, 1, data); mWhiteTexture = createTexture(0, TextureType::BGRA, false, false, false, true, 1, 1, data);
unsigned int textureWidth {0}; unsigned int textureWidth {0};
unsigned int textureHeight {0}; unsigned int textureHeight {0};
@ -294,9 +294,9 @@ bool RendererOpenGL::createContext()
textureHeight = static_cast<unsigned int>(getScreenWidth()); textureHeight = static_cast<unsigned int>(getScreenWidth());
} }
mPostProcTexture1 = createTexture(TextureType::BGRA, false, true, false, false, textureWidth, mPostProcTexture1 = createTexture(0, TextureType::BGRA, false, true, false, false, textureWidth,
textureHeight, nullptr); textureHeight, nullptr);
mPostProcTexture2 = createTexture(TextureType::BGRA, false, true, false, false, textureWidth, mPostProcTexture2 = createTexture(0, TextureType::BGRA, false, true, false, false, textureWidth,
textureHeight, nullptr); textureHeight, nullptr);
// Attach textures to the shader framebuffers. // Attach textures to the shader framebuffers.
@ -400,7 +400,8 @@ void RendererOpenGL::swapBuffers()
GL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); GL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
} }
unsigned int RendererOpenGL::createTexture(const TextureType type, unsigned int RendererOpenGL::createTexture(const unsigned int texUnit,
const TextureType type,
const bool linearMinify, const bool linearMinify,
const bool linearMagnify, const bool linearMagnify,
const bool mipmapping, const bool mipmapping,
@ -409,9 +410,12 @@ unsigned int RendererOpenGL::createTexture(const TextureType type,
const unsigned int height, const unsigned int height,
void* data) void* data)
{ {
assert(texUnit < 32);
const GLenum textureType {convertTextureType(type)}; const GLenum textureType {convertTextureType(type)};
unsigned int texture; unsigned int texture;
GL_CHECK_ERROR(glActiveTexture(GL_TEXTURE0 + texUnit));
GL_CHECK_ERROR(glGenTextures(1, &texture)); GL_CHECK_ERROR(glGenTextures(1, &texture));
GL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture)); GL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
@ -454,6 +458,7 @@ void RendererOpenGL::destroyTexture(const unsigned int texture)
} }
void RendererOpenGL::updateTexture(const unsigned int texture, void RendererOpenGL::updateTexture(const unsigned int texture,
const unsigned int texUnit,
const TextureType type, const TextureType type,
const unsigned int x, const unsigned int x,
const unsigned int y, const unsigned int y,
@ -461,8 +466,10 @@ void RendererOpenGL::updateTexture(const unsigned int texture,
const unsigned int height, const unsigned int height,
void* data) void* data)
{ {
const GLenum textureType {convertTextureType(type)}; assert(texUnit < 32);
const GLenum textureType {convertTextureType(type)};
GL_CHECK_ERROR(glActiveTexture(GL_TEXTURE0 + texUnit));
GL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture)); GL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
GL_CHECK_ERROR(glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, textureType, GL_CHECK_ERROR(glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, textureType,
GL_UNSIGNED_BYTE, data)); GL_UNSIGNED_BYTE, data));
@ -470,8 +477,12 @@ void RendererOpenGL::updateTexture(const unsigned int texture,
GL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, mWhiteTexture)); GL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, mWhiteTexture));
} }
void RendererOpenGL::bindTexture(const unsigned int texture) void RendererOpenGL::bindTexture(const unsigned int texture, const unsigned int texUnit)
{ {
assert(texUnit < 32);
GL_CHECK_ERROR(glActiveTexture(GL_TEXTURE0 + texUnit));
if (texture == 0) if (texture == 0)
GL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, mWhiteTexture)); GL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, mWhiteTexture));
else else
@ -500,6 +511,8 @@ void RendererOpenGL::drawTriangleStrips(const Vertex* vertices,
mCoreShader->setAttribPointers(); mCoreShader->setAttribPointers();
GL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * numVertices, vertices, GL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * numVertices, vertices,
GL_DYNAMIC_DRAW)); GL_DYNAMIC_DRAW));
mCoreShader->setTextureSamplers();
mCoreShader->setTextureSize({width, height});
mCoreShader->setClipRegion(vertices->clipRegion); mCoreShader->setClipRegion(vertices->clipRegion);
mCoreShader->setBrightness(vertices->brightness); mCoreShader->setBrightness(vertices->brightness);
mCoreShader->setOpacity(vertices->opacity); mCoreShader->setOpacity(vertices->opacity);
@ -644,7 +657,7 @@ void RendererOpenGL::shaderPostprocessing(unsigned int shaders,
shaderList.push_back(Shader::SCANLINES); shaderList.push_back(Shader::SCANLINES);
setMatrix(getIdentity()); setMatrix(getIdentity());
bindTexture(mPostProcTexture1); bindTexture(mPostProcTexture1, 0);
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mShaderFBO1)); GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mShaderFBO1));
@ -732,14 +745,14 @@ void RendererOpenGL::shaderPostprocessing(unsigned int shaders,
break; break;
if (firstFBO) { if (firstFBO) {
bindTexture(mPostProcTexture2); bindTexture(mPostProcTexture2, 0);
GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, mShaderFBO2)); GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, mShaderFBO2));
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mShaderFBO1)); GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mShaderFBO1));
GL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT)); GL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT));
firstFBO = false; firstFBO = false;
} }
else { else {
bindTexture(mPostProcTexture1); bindTexture(mPostProcTexture1, 0);
GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, mShaderFBO1)); GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, mShaderFBO1));
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mShaderFBO2)); GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mShaderFBO2));
GL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT)); GL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT));

View file

@ -43,7 +43,8 @@ public:
void setSwapInterval() override; void setSwapInterval() override;
void swapBuffers() override; void swapBuffers() override;
unsigned int createTexture(const TextureType type, unsigned int createTexture(const unsigned int texUnit,
const TextureType type,
const bool linearMinify, const bool linearMinify,
const bool linearMagnify, const bool linearMagnify,
const bool mipmapping, const bool mipmapping,
@ -53,20 +54,19 @@ public:
void* data) override; void* data) override;
void destroyTexture(const unsigned int texture) override; void destroyTexture(const unsigned int texture) override;
void updateTexture(const unsigned int texture, void updateTexture(const unsigned int texture,
const unsigned int texUnit,
const TextureType type, const TextureType type,
const unsigned int x, const unsigned int x,
const unsigned int y, const unsigned int y,
const unsigned int width, const unsigned int width,
const unsigned int height, const unsigned int height,
void* data) override; void* data) override;
void bindTexture(const unsigned int texture) override; void bindTexture(const unsigned int texture, const unsigned int texUnit) override;
void drawTriangleStrips( void drawTriangleStrips(
const Vertex* vertices, const Vertex* vertices,
const unsigned int numVertices, const unsigned int numVertices,
const BlendFactor srcBlendFactor = BlendFactor::ONE, const BlendFactor srcBlendFactor = BlendFactor::ONE,
const BlendFactor dstBlendFactor = BlendFactor::ONE_MINUS_SRC_ALPHA) override; const BlendFactor dstBlendFactor = BlendFactor::ONE_MINUS_SRC_ALPHA) override;
void shaderPostprocessing( void shaderPostprocessing(
const unsigned int shaders, const unsigned int shaders,
const Renderer::postProcessingParams& parameters = postProcessingParams(), const Renderer::postProcessingParams& parameters = postProcessingParams(),

View file

@ -18,7 +18,10 @@ ShaderOpenGL::ShaderOpenGL()
, mShaderPosition {0} , mShaderPosition {0}
, mShaderTextureCoord {0} , mShaderTextureCoord {0}
, mShaderColor {0} , mShaderColor {0}
, mTextureSampler0 {0}
, mTextureSampler1 {0}
, mShaderTextureSize {0} , mShaderTextureSize {0}
, mShaderClipRegion {0}
, mShaderBrightness {0} , mShaderBrightness {0}
, mShaderOpacity {0} , mShaderOpacity {0}
, mShaderSaturation {0} , mShaderSaturation {0}
@ -123,6 +126,8 @@ void ShaderOpenGL::getVariableLocations(GLuint programID)
mShaderPosition = glGetAttribLocation(mProgramID, "positionVertex"); mShaderPosition = glGetAttribLocation(mProgramID, "positionVertex");
mShaderTextureCoord = glGetAttribLocation(mProgramID, "texCoordVertex"); mShaderTextureCoord = glGetAttribLocation(mProgramID, "texCoordVertex");
mShaderColor = glGetAttribLocation(mProgramID, "colorVertex"); mShaderColor = glGetAttribLocation(mProgramID, "colorVertex");
mTextureSampler0 = glGetUniformLocation(mProgramID, "textureSampler0");
mTextureSampler1 = glGetUniformLocation(mProgramID, "textureSampler1");
mShaderTextureSize = glGetUniformLocation(mProgramID, "texSize"); mShaderTextureSize = glGetUniformLocation(mProgramID, "texSize");
mShaderClipRegion = glGetUniformLocation(mProgramID, "clipRegion"); mShaderClipRegion = glGetUniformLocation(mProgramID, "clipRegion");
mShaderBrightness = glGetUniformLocation(mProgramID, "brightness"); mShaderBrightness = glGetUniformLocation(mProgramID, "brightness");
@ -159,6 +164,14 @@ void ShaderOpenGL::setAttribPointers()
reinterpret_cast<const void*>(offsetof(Renderer::Vertex, color)))); reinterpret_cast<const void*>(offsetof(Renderer::Vertex, color))));
} }
void ShaderOpenGL::setTextureSamplers()
{
if (mTextureSampler0 != -1)
GL_CHECK_ERROR(glUniform1i(mTextureSampler0, 0));
if (mTextureSampler1 != -1)
GL_CHECK_ERROR(glUniform1i(mTextureSampler1, 1));
}
void ShaderOpenGL::setTextureSize(std::array<GLfloat, 2> shaderVec2) void ShaderOpenGL::setTextureSize(std::array<GLfloat, 2> shaderVec2)
{ {
if (mShaderTextureSize != -1) if (mShaderTextureSize != -1)

View file

@ -67,6 +67,7 @@ public:
void setModelViewProjectionMatrix(glm::mat4 mvpMatrix); void setModelViewProjectionMatrix(glm::mat4 mvpMatrix);
void setAttribPointers(); void setAttribPointers();
void setTextureSamplers();
void setTextureSize(std::array<GLfloat, 2> shaderVec2); void setTextureSize(std::array<GLfloat, 2> shaderVec2);
void setClipRegion(glm::vec4 clipRegion); void setClipRegion(glm::vec4 clipRegion);
void setBrightness(GLfloat brightness); void setBrightness(GLfloat brightness);
@ -96,6 +97,8 @@ private:
GLint mShaderPosition; GLint mShaderPosition;
GLint mShaderTextureCoord; GLint mShaderTextureCoord;
GLint mShaderColor; GLint mShaderColor;
GLint mTextureSampler0;
GLint mTextureSampler1;
GLint mShaderTextureSize; GLint mShaderTextureSize;
GLint mShaderClipRegion; GLint mShaderClipRegion;
GLint mShaderBrightness; GLint mShaderBrightness;

View file

@ -255,7 +255,7 @@ void Font::renderTextCache(TextCache* cache)
it->verts[0].clipRegion = cache->clipRegion; it->verts[0].clipRegion = cache->clipRegion;
} }
mRenderer->bindTexture(*it->textureIdPtr); mRenderer->bindTexture(*it->textureIdPtr, 0);
mRenderer->drawTriangleStrips( mRenderer->drawTriangleStrips(
&it->verts[0], static_cast<const unsigned int>(it->verts.size()), &it->verts[0], static_cast<const unsigned int>(it->verts.size()),
Renderer::BlendFactor::SRC_ALPHA, Renderer::BlendFactor::ONE_MINUS_SRC_ALPHA); Renderer::BlendFactor::SRC_ALPHA, Renderer::BlendFactor::ONE_MINUS_SRC_ALPHA);
@ -590,7 +590,7 @@ void Font::FontTexture::initTexture()
// glyphs will not be visible. That would otherwise lead to edge artifacts as these pixels // glyphs will not be visible. That would otherwise lead to edge artifacts as these pixels
// would get sampled during scaling. // would get sampled during scaling.
std::vector<uint8_t> texture(textureSize.x * textureSize.y * 4, 0); std::vector<uint8_t> texture(textureSize.x * textureSize.y * 4, 0);
textureId = Renderer::getInstance()->createTexture(Renderer::TextureType::RED, true, textureId = Renderer::getInstance()->createTexture(0, Renderer::TextureType::RED, true,
linearMagnify, false, false, textureSize.x, linearMagnify, false, false, textureSize.x,
textureSize.y, &texture[0]); textureSize.y, &texture[0]);
} }
@ -657,7 +657,7 @@ void Font::rebuildTextures()
static_cast<int>(it->second.texSize.y * tex->textureSize.y)}; static_cast<int>(it->second.texSize.y * tex->textureSize.y)};
// Upload to texture. // Upload to texture.
mRenderer->updateTexture(tex->textureId, Renderer::TextureType::RED, cursor.x, cursor.y, mRenderer->updateTexture(tex->textureId, 0, Renderer::TextureType::RED, cursor.x, cursor.y,
glyphSize.x, glyphSize.y, glyphSlot->bitmap.buffer); glyphSize.x, glyphSize.y, glyphSlot->bitmap.buffer);
} }
} }
@ -781,7 +781,7 @@ Font::Glyph* Font::getGlyph(const unsigned int id)
glyph.rows = glyphSlot->bitmap.rows; glyph.rows = glyphSlot->bitmap.rows;
// Upload glyph bitmap to texture. // Upload glyph bitmap to texture.
mRenderer->updateTexture(tex->textureId, Renderer::TextureType::RED, cursor.x, cursor.y, mRenderer->updateTexture(tex->textureId, 0, Renderer::TextureType::RED, cursor.x, cursor.y,
glyphSize.x, glyphSize.y, glyphSlot->bitmap.buffer); glyphSize.x, glyphSize.y, glyphSlot->bitmap.buffer);
return &glyph; return &glyph;

View file

@ -206,12 +206,12 @@ bool TextureData::isLoaded()
return false; return false;
} }
bool TextureData::uploadAndBind() bool TextureData::uploadAndBind(const unsigned int texUnit)
{ {
// Check if it has already been uploaded. // Check if it has already been uploaded.
std::unique_lock<std::mutex> lock {mMutex}; std::unique_lock<std::mutex> lock {mMutex};
if (mTextureID != 0) { if (mTextureID != 0) {
mRenderer->bindTexture(mTextureID); mRenderer->bindTexture(mTextureID, texUnit);
} }
else { else {
// Make sure we're ready to upload. // Make sure we're ready to upload.
@ -220,8 +220,8 @@ bool TextureData::uploadAndBind()
// Upload texture. // Upload texture.
mTextureID = mTextureID =
mRenderer->createTexture(Renderer::TextureType::BGRA, true, mLinearMagnify, mMipmapping, mRenderer->createTexture(texUnit, Renderer::TextureType::BGRA, true, mLinearMagnify,
mTile, static_cast<const unsigned int>(mWidth), mMipmapping, mTile, static_cast<const unsigned int>(mWidth),
static_cast<const unsigned int>(mHeight), mDataRGBA.data()); static_cast<const unsigned int>(mHeight), mDataRGBA.data());
} }
return true; return true;

View file

@ -41,7 +41,7 @@ public:
// Upload the texture to VRAM if necessary and bind. // Upload the texture to VRAM if necessary and bind.
// Returns true if bound correctly. // Returns true if bound correctly.
bool uploadAndBind(); bool uploadAndBind(const unsigned int texUnit);
// Release the texture from VRAM. // Release the texture from VRAM.
void releaseVRAM(); void releaseVRAM();

View file

@ -66,14 +66,14 @@ std::shared_ptr<TextureData> TextureDataManager::get(const TextureResource* key)
return tex; return tex;
} }
bool TextureDataManager::bind(const TextureResource* key) bool TextureDataManager::bind(const TextureResource* key, const unsigned int texUnit)
{ {
std::shared_ptr<TextureData> tex {get(key)}; std::shared_ptr<TextureData> tex {get(key)};
bool bound {false}; bool bound {false};
if (tex != nullptr) if (tex != nullptr)
bound = tex->uploadAndBind(); bound = tex->uploadAndBind(texUnit);
if (!bound) if (!bound)
mBlank->uploadAndBind(); mBlank->uploadAndBind(texUnit);
return bound; return bound;
} }

View file

@ -72,7 +72,7 @@ public:
void remove(const TextureResource* key); void remove(const TextureResource* key);
std::shared_ptr<TextureData> get(const TextureResource* key); std::shared_ptr<TextureData> get(const TextureResource* key);
bool bind(const TextureResource* key); bool bind(const TextureResource* key, const unsigned int texUnit);
// Get the total size of all textures managed by this object, loaded and unloaded in bytes. // Get the total size of all textures managed by this object, loaded and unloaded in bytes.
size_t getTotalSize(); size_t getTotalSize();

View file

@ -146,14 +146,14 @@ bool TextureResource::isTiled() const
return data->getTiled(); return data->getTiled();
} }
bool TextureResource::bind() bool TextureResource::bind(const unsigned int texUnit)
{ {
if (mTextureData != nullptr) { if (mTextureData != nullptr) {
mTextureData->uploadAndBind(); mTextureData->uploadAndBind(texUnit);
return true; return true;
} }
else { else {
return sTextureDataManager.bind(this); return sTextureDataManager.bind(this, texUnit);
} }
} }

View file

@ -73,7 +73,7 @@ public:
} }
const glm::ivec2 getSize() const { return mSize; } const glm::ivec2 getSize() const { return mSize; }
bool bind(); bool bind(const unsigned int texUnit);
// Returns an approximation of total VRAM used by textures (in bytes). // Returns an approximation of total VRAM used by textures (in bytes).
static size_t getTotalMemUsage(); static size_t getTotalMemUsage();

View file

@ -28,7 +28,7 @@ precision mediump float;
#endif #endif
uniform uint shaderFlags; uniform uint shaderFlags;
uniform sampler2D textureSampler; uniform sampler2D textureSampler0;
uniform float blurStrength; uniform float blurStrength;
in vec2 texCoord; in vec2 texCoord;
out vec4 FragColor; out vec4 FragColor;
@ -58,31 +58,31 @@ void main()
} }
// 9-tap filter. // 9-tap filter.
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x - 4.0 * blurStrength * hstep, tc.y - 4.0 * blurStrength * vstep)) * vec2(tc.x - 4.0 * blurStrength * hstep, tc.y - 4.0 * blurStrength * vstep)) *
0.0162162162; 0.0162162162;
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x - 3.0 * blurStrength * hstep, tc.y - 3.0 * blurStrength * vstep)) * vec2(tc.x - 3.0 * blurStrength * hstep, tc.y - 3.0 * blurStrength * vstep)) *
0.0540540541; 0.0540540541;
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x - 2.0 * blurStrength * hstep, tc.y - 2.0 * blurStrength * vstep)) * vec2(tc.x - 2.0 * blurStrength * hstep, tc.y - 2.0 * blurStrength * vstep)) *
0.1216216216; 0.1216216216;
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x - 1.0 * blurStrength * hstep, tc.y - 1.0 * blurStrength * vstep)) * vec2(tc.x - 1.0 * blurStrength * hstep, tc.y - 1.0 * blurStrength * vstep)) *
0.1945945946; 0.1945945946;
color += texture(textureSampler, vec2(tc.x, tc.y)) * 0.2270270270; color += texture(textureSampler0, vec2(tc.x, tc.y)) * 0.2270270270;
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x + 1.0 * blurStrength * hstep, tc.y + 1.0 * blurStrength * vstep)) * vec2(tc.x + 1.0 * blurStrength * hstep, tc.y + 1.0 * blurStrength * vstep)) *
0.1945945946; 0.1945945946;
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x + 2.0 * blurStrength * hstep, tc.y + 2.0 * blurStrength * vstep)) * vec2(tc.x + 2.0 * blurStrength * hstep, tc.y + 2.0 * blurStrength * vstep)) *
0.1216216216; 0.1216216216;
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x + 3.0 * blurStrength * hstep, tc.y + 3.0 * blurStrength * vstep)) * vec2(tc.x + 3.0 * blurStrength * hstep, tc.y + 3.0 * blurStrength * vstep)) *
0.0540540541; 0.0540540541;
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x + 4.0 * blurStrength * hstep, tc.y + 4.0 * blurStrength * vstep)) * vec2(tc.x + 4.0 * blurStrength * hstep, tc.y + 4.0 * blurStrength * vstep)) *
0.0162162162; 0.0162162162;

View file

@ -28,7 +28,7 @@ precision mediump float;
#endif #endif
uniform uint shaderFlags; uniform uint shaderFlags;
uniform sampler2D textureSampler; uniform sampler2D textureSampler0;
uniform float blurStrength; uniform float blurStrength;
in vec2 texCoord; in vec2 texCoord;
out vec4 FragColor; out vec4 FragColor;
@ -58,31 +58,31 @@ void main()
} }
// 9-tap filter. // 9-tap filter.
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x - 4.0 * blurStrength * hstep, tc.y - 4.0 * blurStrength * vstep)) * vec2(tc.x - 4.0 * blurStrength * hstep, tc.y - 4.0 * blurStrength * vstep)) *
0.0162162162; 0.0162162162;
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x - 3.0 * blurStrength * hstep, tc.y - 3.0 * blurStrength * vstep)) * vec2(tc.x - 3.0 * blurStrength * hstep, tc.y - 3.0 * blurStrength * vstep)) *
0.0540540541; 0.0540540541;
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x - 2.0 * blurStrength * hstep, tc.y - 2.0 * blurStrength * vstep)) * vec2(tc.x - 2.0 * blurStrength * hstep, tc.y - 2.0 * blurStrength * vstep)) *
0.1216216216; 0.1216216216;
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x - 1.0 * blurStrength * hstep, tc.y - 1.0 * blurStrength * vstep)) * vec2(tc.x - 1.0 * blurStrength * hstep, tc.y - 1.0 * blurStrength * vstep)) *
0.1945945946; 0.1945945946;
color += texture(textureSampler, vec2(tc.x, tc.y)) * 0.2270270270; color += texture(textureSampler0, vec2(tc.x, tc.y)) * 0.2270270270;
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x + 1.0 * blurStrength * hstep, tc.y + 1.0 * blurStrength * vstep)) * vec2(tc.x + 1.0 * blurStrength * hstep, tc.y + 1.0 * blurStrength * vstep)) *
0.1945945946; 0.1945945946;
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x + 2.0 * blurStrength * hstep, tc.y + 2.0 * blurStrength * vstep)) * vec2(tc.x + 2.0 * blurStrength * hstep, tc.y + 2.0 * blurStrength * vstep)) *
0.1216216216; 0.1216216216;
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x + 3.0 * blurStrength * hstep, tc.y + 3.0 * blurStrength * vstep)) * vec2(tc.x + 3.0 * blurStrength * hstep, tc.y + 3.0 * blurStrength * vstep)) *
0.0540540541; 0.0540540541;
color += texture(textureSampler, color += texture(textureSampler0,
vec2(tc.x + 4.0 * blurStrength * hstep, tc.y + 4.0 * blurStrength * vstep)) * vec2(tc.x + 4.0 * blurStrength * hstep, tc.y + 4.0 * blurStrength * vstep)) *
0.0162162162; 0.0162162162;

View file

@ -47,7 +47,8 @@ uniform float cornerRadius;
uniform float reflectionsFalloff; uniform float reflectionsFalloff;
uniform uint shaderFlags; uniform uint shaderFlags;
uniform sampler2D textureSampler; uniform sampler2D textureSampler0;
uniform sampler2D textureSampler1;
out vec4 FragColor; out vec4 FragColor;
// shaderFlags: // shaderFlags:
@ -73,19 +74,20 @@ void main()
discard; discard;
} }
vec4 sampledColor = texture(textureSampler, texCoord); vec4 sampledColor = texture(textureSampler0, texCoord);
// Rounded corners. // Rounded corners.
if (0x0u != (shaderFlags & 0x20u) || 0x0u != (shaderFlags & 0x40u)) { if (0x0u != (shaderFlags & 0x20u) || 0x0u != (shaderFlags & 0x40u)) {
float radius = cornerRadius; float cornerRadiusClamped = cornerRadius;
// Don't go beyond half the width and height. // Don't go beyond half the width and height.
if (radius > texSize.x / 2.0) if (cornerRadiusClamped > texSize.x / 2.0)
radius = texSize.x / 2.0; cornerRadiusClamped = texSize.x / 2.0;
if (radius > texSize.y / 2.0) if (cornerRadiusClamped > texSize.y / 2.0)
radius = texSize.y / 2.0; cornerRadiusClamped = texSize.y / 2.0;
vec2 q = abs(position - texSize / 2.0) - (vec2(texSize.x / 2.0, texSize.y / 2.0) - radius); vec2 center = position - texSize / 2.0;
float pixelDistance = length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - radius; vec2 q = abs(center) - (vec2(texSize.x / 2.0, texSize.y / 2.0) - cornerRadiusClamped);
float pixelDistance = length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - cornerRadiusClamped;
if (pixelDistance > 0.0) { if (pixelDistance > 0.0) {
discard; discard;

View file

@ -61,7 +61,7 @@ uniform float opacity;
uniform float brightness; uniform float brightness;
uniform float saturation; uniform float saturation;
uniform uint shaderFlags; uniform uint shaderFlags;
uniform sampler2D textureSampler; uniform sampler2D textureSampler0;
in vec2 texCoord; in vec2 texCoord;
in vec2 onex; in vec2 onex;
in vec2 oney; in vec2 oney;
@ -85,7 +85,7 @@ uniform float OutputGamma;
#define GAMMA_IN(color) pow(color, vec4(InputGamma)) #define GAMMA_IN(color) pow(color, vec4(InputGamma))
#define GAMMA_OUT(color) pow(color, vec4(1.0 / OutputGamma)) #define GAMMA_OUT(color) pow(color, vec4(1.0 / OutputGamma))
#define TEX2D(coords) GAMMA_IN(texture(textureSampler, coords)) #define TEX2D(coords) GAMMA_IN(texture(textureSampler0, coords))
// Macro for weights computing. // Macro for weights computing.
#define WEIGHT(w) \ #define WEIGHT(w) \