Added support for clipping to the core GLSL shader.

This commit is contained in:
Leon Styhre 2022-08-30 19:42:37 +02:00
parent 6126016289
commit 496b60fa7d
7 changed files with 78 additions and 6 deletions

View file

@ -50,6 +50,7 @@ ImageComponent::ImageComponent(bool forceLoad, bool dynamic)
, mLinearInterpolation {false}
, mTopLeftCrop {0.0f, 0.0f}
, mBottomRightCrop {1.0f, 1.0f}
, mClipRegion {0.0f, 0.0f, 0.0f, 0.0f}
{
updateColors();
}
@ -367,6 +368,34 @@ void ImageComponent::setDimming(float dimming)
mDimming = dimming;
}
void ImageComponent::setClipRegion(const glm::vec4& clipRegion)
{
if (mVertices[0].clipregion == clipRegion)
return;
mClipRegion = clipRegion;
if (mClipRegion == glm::vec4 {0.0f, 0.0f, 0.0f, 0.0f}) {
if (mVertices[0].shaderFlags & Renderer::ShaderFlags::CLIPPING) {
mVertices[0].shaderFlags ^= Renderer::ShaderFlags::CLIPPING;
mVertices[1].shaderFlags ^= Renderer::ShaderFlags::CLIPPING;
mVertices[2].shaderFlags ^= Renderer::ShaderFlags::CLIPPING;
mVertices[3].shaderFlags ^= Renderer::ShaderFlags::CLIPPING;
}
}
else {
mVertices[0].shaderFlags |= Renderer::ShaderFlags::CLIPPING;
mVertices[1].shaderFlags |= Renderer::ShaderFlags::CLIPPING;
mVertices[2].shaderFlags |= Renderer::ShaderFlags::CLIPPING;
mVertices[3].shaderFlags |= Renderer::ShaderFlags::CLIPPING;
}
mVertices[0].clipregion = clipRegion;
mVertices[1].clipregion = clipRegion;
mVertices[2].clipregion = clipRegion;
mVertices[3].clipregion = clipRegion;
}
void ImageComponent::updateVertices()
{
if (!mTexture)
@ -401,6 +430,8 @@ void ImageComponent::updateVertices()
for (int i = 0; i < 4; ++i)
mVertices[i].texcoord[1] = py - mVertices[i].texcoord[1];
}
setClipRegion(mClipRegion);
}
void ImageComponent::updateColors()
@ -436,7 +467,11 @@ void ImageComponent::render(const glm::mat4& parentTrans)
glm::vec2 targetSizePos {(mTargetSize - mSize) * mOrigin * glm::vec2 {-1.0f}};
mRenderer->drawRect(targetSizePos.x, targetSizePos.y, mTargetSize.x, mTargetSize.y,
0xFF000033, 0xFF000033);
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0xFF000033, 0xFF000033);
if (mClipRegion == glm::vec4 {0.0f, 0.0f, 0.0f, 0.0f})
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0xFF000033, 0xFF000033);
else
mRenderer->drawRect(mClipRegion.x, mClipRegion.y, mClipRegion.z - mClipRegion.x,
mClipRegion.w - mClipRegion.y, 0xFF000033, 0xFF000033);
}
// An image with zero size would normally indicate a corrupt image file.
if (mTexture->getSize() != glm::ivec2 {}) {

View file

@ -82,6 +82,7 @@ public:
void setOpacity(float opacity) override;
void setSaturation(float saturation) override;
void setDimming(float dimming) override;
void setClipRegion(const glm::vec4& clipRegion);
void setReflectionsFalloff(float falloff) override { mReflectionsFalloff = falloff; }
void setFlipX(bool flip) override; // Mirror on the X axis.
@ -154,6 +155,7 @@ private:
glm::vec2 mTopLeftCrop;
glm::vec2 mBottomRightCrop;
glm::vec4 mClipRegion;
};
#endif // ES_CORE_COMPONENTS_IMAGE_COMPONENT_H

View file

@ -51,7 +51,8 @@ public:
enum ShaderFlags {
BGRA_TO_RGBA = 0x00000001,
FONT_TEXTURE = 0x00000002,
POST_PROCESSING = 0x00000004
POST_PROCESSING = 0x00000004,
CLIPPING = 0x00000008
};
// clang-format on
@ -59,6 +60,7 @@ public:
glm::vec2 position;
glm::vec2 texcoord;
unsigned int color;
glm::vec4 clipregion;
float opacity;
float saturation;
float dimming;
@ -76,10 +78,14 @@ public:
{
}
Vertex(const glm::vec2& position, const glm::vec2& textureCoord, const unsigned int color)
Vertex(const glm::vec2& position,
const glm::vec2& textureCoord,
const unsigned int color,
const glm::vec4& clipRegion = glm::vec4 {0.0f, 0.0f, 0.0f, 0.0f})
: position(position)
, texcoord(textureCoord)
, color(color)
, clipregion(clipRegion)
, opacity {1.0f}
, saturation {1.0f}
, dimming {1.0f}

View file

@ -420,6 +420,7 @@ void RendererOpenGL::drawTriangleStrips(const Vertex* vertices,
mCoreShader->setAttribPointers();
GL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * numVertices, vertices,
GL_DYNAMIC_DRAW));
mCoreShader->setClipRegion(vertices->clipregion);
mCoreShader->setOpacity(vertices->opacity);
mCoreShader->setSaturation(vertices->saturation);
mCoreShader->setDimming(vertices->dimming);

View file

@ -121,6 +121,7 @@ void ShaderOpenGL::getVariableLocations(GLuint programID)
mShaderTextureCoord = glGetAttribLocation(mProgramID, "texCoordVertex");
mShaderColor = glGetAttribLocation(mProgramID, "colorVertex");
mShaderTextureSize = glGetUniformLocation(mProgramID, "textureSize");
mShaderClipRegion = glGetUniformLocation(mProgramID, "clipRegion");
mShaderOpacity = glGetUniformLocation(mProgramID, "opacity");
mShaderSaturation = glGetUniformLocation(mProgramID, "saturation");
mShaderDimming = glGetUniformLocation(mProgramID, "dimming");
@ -158,6 +159,13 @@ void ShaderOpenGL::setTextureSize(std::array<GLfloat, 2> shaderVec2)
GL_CHECK_ERROR(glUniform2f(mShaderTextureSize, shaderVec2[0], shaderVec2[1]));
}
void ShaderOpenGL::setClipRegion(glm::vec4 clipRegion)
{
if (mShaderClipRegion != -1)
GL_CHECK_ERROR(glUniform4f(mShaderClipRegion, clipRegion[0], clipRegion[1], clipRegion[2],
clipRegion[3]));
}
void ShaderOpenGL::setOpacity(GLfloat opacity)
{
if (mShaderOpacity != -1)

View file

@ -68,6 +68,7 @@ public:
void setAttribPointers();
void setTextureSize(std::array<GLfloat, 2> shaderVec2);
void setClipRegion(glm::vec4 clipRegion);
void setOpacity(GLfloat opacity);
void setSaturation(GLfloat saturation);
void setDimming(GLfloat dimming);
@ -92,6 +93,7 @@ private:
GLint mShaderPosition;
GLint mShaderTextureCoord;
GLint mShaderColor;
GLint mShaderClipRegion;
GLint mShaderTextureSize;
GLint mShaderOpacity;
GLint mShaderSaturation;

View file

@ -4,7 +4,7 @@
// core.glsl
//
// Core shader functionality:
// opacity, saturation, dimming and BGRA to RGBA conversion.
// clipping, opacity, saturation, dimming and BGRA to RGBA conversion.
//
// Vertex section of code:
@ -15,12 +15,14 @@ in vec2 positionVertex;
in vec2 texCoordVertex;
in vec4 colorVertex;
out vec4 color;
out vec2 position;
out vec2 texCoord;
out vec4 color;
void main(void)
{
gl_Position = MVPMatrix * vec4(positionVertex.xy, 0.0, 1.0);
position = positionVertex;
texCoord = texCoordVertex;
color.rgba = colorVertex.abgr;
}
@ -32,8 +34,11 @@ void main(void)
precision mediump float;
#endif
in vec4 color;
in vec2 position;
in vec2 texCoord;
in vec4 color;
uniform vec4 clipRegion;
uniform float opacity;
uniform float saturation;
uniform float dimming;
@ -47,9 +52,22 @@ out vec4 FragColor;
// 0x00000001 - BGRA to RGBA conversion
// 0x00000002 - Font texture
// 0x00000004 - Post processing
// 0x00000008 - Clipping
void main()
{
// Discard any pixels outside the clipping region.
if (0u != (shaderFlags & 8u)) {
if (position.x < clipRegion.x)
discard;
else if (position.y < clipRegion.y)
discard;
else if (position.x > clipRegion.z)
discard;
else if (position.y > clipRegion.w)
discard;
}
vec4 sampledColor = texture(textureSampler, texCoord);
// For fonts the alpha information is stored in the red channel.