summaryrefslogtreecommitdiff
path: root/src/graphics/StandardShader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphics/StandardShader.cpp')
-rw-r--r--src/graphics/StandardShader.cpp216
1 files changed, 216 insertions, 0 deletions
diff --git a/src/graphics/StandardShader.cpp b/src/graphics/StandardShader.cpp
new file mode 100644
index 0000000..3fcd93a
--- /dev/null
+++ b/src/graphics/StandardShader.cpp
@@ -0,0 +1,216 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "StandardShader.h"
+
+#include "GLContext.h"
+#include "ShaderRegistry.h"
+
+#include "../base/Logger.h"
+#include "../base/Exception.h"
+
+#include <iostream>
+
+using namespace std;
+
+#define STANDARD_SHADER "standard"
+#define MINIMAL_SHADER "minimal"
+
+namespace avg {
+
+StandardShaderPtr StandardShader::get()
+{
+ return GLContext::getMain()->getStandardShader();
+}
+
+StandardShader::StandardShader()
+{
+ avg::createShader(STANDARD_SHADER);
+ m_pShader = avg::getShader(STANDARD_SHADER);
+ m_pColorModelParam = m_pShader->getParam<int>("u_ColorModel");
+ m_pAlphaParam = m_pShader->getParam<float>("u_Alpha");
+ m_pColorCoeff0Param = m_pShader->getParam<glm::vec4>("u_ColorCoeff0");
+ m_pColorCoeff1Param = m_pShader->getParam<glm::vec4>("u_ColorCoeff1");
+ m_pColorCoeff2Param = m_pShader->getParam<glm::vec4>("u_ColorCoeff2");
+ m_pColorCoeff3Param = m_pShader->getParam<glm::vec4>("u_ColorCoeff3");
+ m_pGammaParam = m_pShader->getParam<glm::vec4>("u_Gamma");
+
+ m_pUseColorCoeffParam = m_pShader->getParam<int>("u_bUseColorCoeff");
+ m_pPremultipliedAlphaParam = m_pShader->getParam<int>("u_bPremultipliedAlpha");
+ m_pUseMaskParam = m_pShader->getParam<int>("u_bUseMask");
+ m_pMaskPosParam = m_pShader->getParam<glm::vec2>("u_MaskPos");
+ m_pMaskSizeParam = m_pShader->getParam<glm::vec2>("u_MaskSize");
+
+ m_pShader->activate();
+ m_pShader->getParam<int>("u_Texture")->set(0);
+ if (GLContext::getMain()->useGPUYUVConversion()) {
+ m_pShader->getParam<int>("u_CBTexture")->set(1);
+ m_pShader->getParam<int>("u_CRTexture")->set(2);
+ m_pShader->getParam<int>("u_ATexture")->set(3);
+ }
+ m_pShader->getParam<int>("u_MaskTexture")->set(4);
+
+ if (GLContext::getMain()->getShaderUsage() != GLConfig::FULL) {
+ avg::createShader(MINIMAL_SHADER);
+ m_pMinimalShader = avg::getShader(MINIMAL_SHADER);
+ m_pMinimalShader->activate();
+ m_pMinimalShader->getParam<int>("u_Texture")->set(0);
+ m_pMinimalAlphaParam = m_pMinimalShader->getParam<float>("u_Alpha");
+ }
+
+ generateWhiteTexture();
+}
+
+StandardShader::~StandardShader()
+{
+}
+
+void StandardShader::activate()
+{
+ if (useMinimalShader()) {
+ m_pMinimalShader->activate();
+ m_pMinimalShader->setTransform(m_Transform);
+ m_pMinimalAlphaParam->set(m_Alpha);
+ } else {
+ m_pShader->activate();
+ m_pShader->setTransform(m_Transform);
+ m_pColorModelParam->set(m_ColorModel);
+ m_pAlphaParam->set(m_Alpha);
+
+ m_pUseColorCoeffParam->set(m_bUseColorCoeff);
+ const glm::mat4& mat = m_ColorMatrix;
+ m_pColorCoeff0Param->set(glm::vec4(mat[0][0], mat[0][1], mat[0][2], 0));
+ m_pColorCoeff1Param->set(glm::vec4(mat[1][0], mat[1][1], mat[1][2], 0));
+ m_pColorCoeff2Param->set(glm::vec4(mat[2][0], mat[2][1], mat[2][2], 0));
+ m_pColorCoeff3Param->set(glm::vec4(mat[3][0], mat[3][1], mat[3][2], 1));
+ m_pGammaParam->set(m_Gamma);
+
+ m_pPremultipliedAlphaParam->set(m_bPremultipliedAlpha);
+
+ m_pUseMaskParam->set(m_bUseMask);
+ if (m_bUseMask) {
+ m_pMaskPosParam->set(m_MaskPos);
+ m_pMaskSizeParam->set(m_MaskSize);
+ }
+ }
+}
+
+void StandardShader::setTransform(const glm::mat4& transform)
+{
+ m_Transform = transform;
+}
+
+void StandardShader::setColorModel(int model)
+{
+ m_ColorModel = model;
+}
+
+void StandardShader::setAlpha(float alpha)
+{
+ m_Alpha = alpha;
+}
+
+void StandardShader::setUntextured()
+{
+ // Activate an internal 1x1 A8 texture.
+ m_ColorModel = 2;
+ m_pWhiteTex->activate(GL_TEXTURE0);
+ disableColorspaceMatrix();
+ setGamma(glm::vec4(1.f,1.f,1.f,1.f));
+ setPremultipliedAlpha(false);
+ setMask(false);
+}
+
+void StandardShader::setColorspaceMatrix(const glm::mat4& mat)
+{
+ m_bUseColorCoeff = true;
+ m_ColorMatrix = mat;
+}
+
+void StandardShader::disableColorspaceMatrix()
+{
+ m_bUseColorCoeff = false;
+}
+
+void StandardShader::setGamma(const glm::vec4& gamma)
+{
+ m_Gamma = gamma;
+}
+
+void StandardShader::setPremultipliedAlpha(bool bPremultipliedAlpha)
+{
+ m_bPremultipliedAlpha = bPremultipliedAlpha;
+}
+
+void StandardShader::setMask(bool bUseMask, const glm::vec2& maskPos,
+ const glm::vec2& maskSize)
+{
+ m_bUseMask = bUseMask;
+ m_MaskPos = maskPos;
+ m_MaskSize = maskSize;
+}
+
+const OGLShaderPtr& StandardShader::getShader() const
+{
+ if (useMinimalShader()) {
+ return m_pMinimalShader;
+ } else {
+ return m_pShader;
+ }
+}
+
+void StandardShader::dump() const
+{
+ cerr << "---------Standard shader--------" << endl;
+ cerr << " m_Transform: " << m_Transform << endl;
+ cerr << " m_ColorModel: " << m_ColorModel << endl;
+ cerr << " m_Alpha: " << m_Alpha << endl;
+ cerr << " m_bUseColorCoeff: " << m_bUseColorCoeff << endl;
+ cerr << " m_ColorMatrix: " << m_ColorMatrix << endl;
+ cerr << " m_Gamma: " << m_Gamma << endl;
+ cerr << " m_bPremultipliedAlpha: " << m_bPremultipliedAlpha << endl;
+ cerr << " m_bUseMask: " << m_bUseMask << endl;
+ cerr << " m_MaskPos: " << m_MaskPos << endl;
+ cerr << " m_MaskSize: " << m_MaskSize << endl;
+ cerr << endl;
+}
+
+void StandardShader::generateWhiteTexture()
+{
+ BitmapPtr pBmp(new Bitmap(glm::vec2(1,1), I8));
+ *(pBmp->getPixels()) = 255;
+ m_pWhiteTex = GLTexturePtr(new GLTexture(IntPoint(1,1), I8));
+ m_pWhiteTex->moveBmpToTexture(pBmp);
+}
+
+bool StandardShader::useMinimalShader() const
+{
+ bool bActivateMinimal = false;
+ if (GLContext::getMain()->getShaderUsage() != GLConfig::FULL) {
+ bool bGammaIsModified = (!almostEqual(m_Gamma, glm::vec4(1.0f,1.0f,1.0f,1.0f)));
+ if (m_ColorModel == 0 && !m_bUseColorCoeff && !bGammaIsModified && !m_bUseMask) {
+ bActivateMinimal = true;
+ }
+ }
+ return bActivateMinimal;
+}
+
+}