summaryrefslogtreecommitdiffstats
path: root/src/glesrenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/glesrenderer.cpp')
-rw-r--r--src/glesrenderer.cpp776
1 files changed, 776 insertions, 0 deletions
diff --git a/src/glesrenderer.cpp b/src/glesrenderer.cpp
new file mode 100644
index 0000000..7d7339d
--- /dev/null
+++ b/src/glesrenderer.cpp
@@ -0,0 +1,776 @@
+/***************************************************************************
+ * Copyright (C) 2008, 2012 by Walter Roth *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program 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 General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "glesrenderer.h"
+
+#include <math.h>
+
+//#define DEBUG_GLESRENDERER
+
+//#ifdef DEBUG_GLESRENDERER
+#include "shaderdebugger.h"
+//#endif
+
+#ifdef Q_OS_ANDROID
+#ifndef GLES
+ #define GLES //Android uses GLES 2.0
+#endif
+#endif
+
+
+GLESRenderer::GLESRenderer(QObject *parent,
+ const QString & vShaderFilename,
+ const QString & fShaderFilename )
+ :QObject(parent)
+{
+ this->m_vShaderFileName = vShaderFilename;
+ this->m_fShaderFileName = fShaderFilename;
+
+ //flags
+ m_initialized = false;
+ m_bound = false;
+ m_lightingEnabled = false; // flag for lighting
+ m_colorArrayEnabled = false;
+ m_invertedMvpMatrixValid = false; //delay matrix inversion until it is really neccessary
+ m_textureEnabled = false;
+
+ m_lightDirection = QVector3D(1.0,1.0,1.0); //position of directional light
+ m_pointSize = 4.0;
+ m_shininess = 200.0;
+ m_ambientAndDiffuseColor = cl_White;
+ m_ambientLightBrightness = 0.2;
+ m_specularColor = cl_White;
+
+ m_vShader = NULL; //vertex shader, render thread
+ m_fShader = NULL; // fragment shader, render thread
+ m_renderProgram = NULL;// GUI-Thread
+
+ // Locations of shader variables
+ //attributes
+ m_location_aVertex = -1;
+ m_location_aColor = -1;
+ m_location_aNormal = -1;
+ m_location_aTexCoord = -1;
+ //uniforms
+ //flags
+ m_location_uColorArrayEnabled = -1;
+ m_location_uTextureEnabled = -1;
+ m_location_uLightingEnabled = -1;
+ //matrices
+ m_location_uNormalMatrix = -1;
+ m_location_uMvpMatrix = -1;
+ //lighting
+ m_location_uAmbientAndDiffuseColor = -1;
+ m_location_uAmbientLightBrightness = -1;
+ m_location_uSpecularColor = -1;
+ m_location_uLightDirection = -1;
+ m_location_uHalfPlaneVector = -1;
+ //texture
+ m_location_uTextureSampler = -1;
+
+ //viewport
+ m_viewportX = 0;
+ m_viewportY = 0;
+ m_viewportW = 100;
+ m_viewportH = 100;
+
+ //clippings
+ m_fovy = 45.0;
+ m_aspect = 1.0;
+ m_nearClip = 1.0;
+ m_farClip = 10.0;
+
+}
+/**
+ * @brief GLESRenderer::~GLESRenderer
+ * We need to delete the shaders here. They can not be added to the child list, because they live in render thread.
+ */
+GLESRenderer::~GLESRenderer()
+{
+ if(m_vShader)
+ delete m_vShader;
+ if(m_fShader)
+ delete m_fShader;
+}
+
+/**
+ * Set modelview matrix. Updates mvpMatrix and normalMatrix too.
+ * Call setPMatrix first.
+ */
+void GLESRenderer::setMvMatrix(const QMatrix4x4 newVal)
+{
+ m_mvMatrix = newVal;
+ m_normalMatrix = m_mvMatrix.normalMatrix(); //invert and transpose mvMatrix
+ m_invertedMvpMatrixValid = false; //delay matrix inversion until it is really neccessary
+
+ if(m_bound && (m_location_uNormalMatrix != -1))
+ m_renderProgram->setUniformValue(m_location_uNormalMatrix, m_normalMatrix);
+
+ m_mvpMatrix = m_pMatrix * m_mvMatrix;
+ if(m_bound && (m_location_uMvpMatrix != -1))
+ m_renderProgram->setUniformValue(m_location_uMvpMatrix, m_mvpMatrix);
+#ifdef DEBUG_GLESRENDERER
+ ShaderDebugger::debugMatrix4x4(m_mvMatrix, "GLESRenderer uses modelview matrix:");
+ ShaderDebugger::debugMatrix3x3(m_normalMatrix, "GLESRenderer uses normal matrix:");
+ ShaderDebugger::debugMatrix4x4(m_mvpMatrix, "GLESRenderer uses MVP matrix:");
+#endif
+}
+
+/**
+ * Sets mvMatrix to a lookAt transformation.
+ * Call setPMatrix or setPerspective first.
+ */
+void GLESRenderer::setLookAt(const QVector3D & eye,const QVector3D & center,const QVector3D & up )
+{
+ QMatrix4x4 m;
+ m.setToIdentity();
+ m.lookAt(eye, center, up);
+ setMvMatrix(m);
+}
+
+/**
+ * Set projection matrix. Call setMvMatrix after this.
+ */
+void GLESRenderer::setPMatrix(const QMatrix4x4 newVal)
+{
+ m_pMatrix = newVal;
+ m_mvpMatrix = m_pMatrix * m_mvMatrix;
+ if(m_bound && (m_location_uMvpMatrix != -1))
+ m_renderProgram->setUniformValue(m_location_uMvpMatrix, m_mvpMatrix);
+}
+
+/**
+ * Setup projection matrix. Call setMvMatrix after this.
+ */
+void GLESRenderer::setPerspective(GLfloat fovy, GLfloat aspect, GLfloat nearClip, GLfloat farClip)
+{
+ m_fovy = fovy;
+ m_aspect = aspect;
+ m_nearClip = nearClip;
+ m_farClip = farClip;
+ m_pMatrix.setToIdentity();
+ m_pMatrix.perspective(m_fovy, m_aspect, m_nearClip, m_farClip);
+ m_mvpMatrix = m_pMatrix * m_mvMatrix;
+ if(m_bound && (m_location_uMvpMatrix != -1))
+ m_renderProgram->setUniformValue(m_location_uMvpMatrix, m_mvpMatrix);
+#ifdef DEBUG_GLESRENDERER
+ ShaderDebugger::debugMatrix4x4(m_pMatrix, "GLESRenderer uses projection matrix:");
+#endif
+}
+
+void GLESRenderer::setOrtho(float left, float right, float bottom, float top, float nearPlane, float farPlane)
+{
+ m_fovy = 0.0;
+ m_aspect = (left - right) / (top - bottom);
+ m_nearClip = nearPlane;
+ m_farClip = farPlane;
+ m_pMatrix.setToIdentity();
+ m_pMatrix.ortho(left, right, bottom, top, nearPlane, farPlane);
+ m_mvpMatrix = m_pMatrix * m_mvMatrix;
+ if(m_bound && (m_location_uMvpMatrix != -1))
+ m_renderProgram->setUniformValue(m_location_uMvpMatrix, m_mvpMatrix);
+#ifdef DEBUG_GLESRENDERER
+ ShaderDebugger::debugMatrix4x4(m_pMatrix, "GLESRenderer uses projection matrix:");
+#endif
+}
+
+/**
+ * Set viewport
+ */
+void GLESRenderer::setViewport(int x, int y, int w, int h)
+{
+ m_viewportX = x;
+ m_viewportY = y;
+ m_viewportW = w;
+ m_viewportH = h;
+ //qDebug() << "GLESRenderer::setViewport x:" << x << " y: " << y << " w: " << w << " h: " << h;
+}
+
+/**
+ * Uses viewport and matrix settings to reverse the vertex transformation chain.
+ * WinX, winY, winZ are the coordinates in window coordinates. Lower left of viewport
+ * is winX = 0, winY = 0. Use winZ = 0.0 for a point on near clipping plane
+ * and winZ = 1.0 for a point on far clipping plane.
+ * This function assumes, that the vertex shader computes gl_positon as v * mvpMatrix.
+ * Use a custom shader reverse function, if this is not true.
+ * Returns coordinate in object space.
+ */
+QVector3D GLESRenderer::unProjectViewportPoint(const QVector3D & vWin)
+{
+ QVector3D vClip = viewportToClip(vWin);
+ if(!m_invertedMvpMatrixValid)
+ {
+ m_invertedMvpMatrix = m_mvpMatrix.inverted();
+ m_invertedMvpMatrixValid = true;
+ }
+ ShaderDebugger::debugMatrix4x4(m_mvpMatrix, "MVP Matrix:");
+ ShaderDebugger::debugMatrix4x4(m_invertedMvpMatrix, "Inverted MVP Matrix:");
+ QVector3D result = m_invertedMvpMatrix * vClip;
+ ShaderDebugger::debugVector3D(result, "Vector in model space:");
+ return result;
+}
+
+/**
+ * Performs inverse viewport transform.
+ */
+QVector3D GLESRenderer::viewportToClip(const QVector3D & vWin)
+{
+ //reverse viewport transformation, for original code see below
+ float xClip = (vWin.x() - (float)m_viewportX) / (float)m_viewportW * 2.0 - 1.0;
+ float yClip = (vWin.y() - (float)m_viewportY) / (float)m_viewportH * 2.0 - 1.0;
+ float zClip = 2.0 * vWin.z() - 1.0;
+
+ // original code from gluUnproject
+ //Transformation of normalized coordinates between -1 and 1
+ // in[0]=(winx-(float)viewport[0])/(float)viewport[2]*2.0-1.0;
+ // in[1]=(winy-(float)viewport[1])/(float)viewport[3]*2.0-1.0;
+ // in[2]=2.0*winz-1.0;
+ // in[3]=1.0;
+
+ QVector3D result = QVector3D(xClip, yClip, zClip);
+ ShaderDebugger::debugVector3D(result, "Vector in clip space:");
+ return result;
+}
+
+/**
+ * Returns the points on near and far clipping plane, that correspond to the
+ * mouseX and mouseY coordinates of a mouse click.
+ * mouseX and mouseY are coordinates as delivered by QMouseEvent or QDeclarativeMouseEvent.
+ */
+void GLESRenderer::calculateMousePoints(QVector3D * nearPoint, QVector3D * farPoint, const QPoint & mousePos)
+{
+ float winX = m_viewportX + mousePos.x();
+ float winY = m_viewportY + (m_viewportH - mousePos.y());
+ * nearPoint = unProjectViewportPoint(QVector3D(winX, winY, 0.0));
+ * farPoint = unProjectViewportPoint(QVector3D(winX, winY, 1.0));
+}
+
+/**
+ * Calculate the distance of the "mouse ray line" to point p in model space.
+ * mouseX, mouseY are the coordinates of the mouse click as delivered by QMouseEvent.
+ * Returns distance.
+ */
+float GLESRenderer::distanceToMouseClick(QVector3D p, const QPoint & mousePos)
+{
+ QVector3D nearPoint, farPoint;
+ calculateMousePoints(&nearPoint, &farPoint, mousePos);
+
+ QVector3D lineVector = nearPoint - farPoint;
+ float area = QVector3D::crossProduct(p - nearPoint, lineVector).length();
+ float distance = area / lineVector.length();
+
+ return distance;
+}
+
+/**
+ * Calculates intersection of "mouse ray line" with the plane defined by normal and d.
+ * mouseX, mouseY are the coordinates of the mouse click as delivered by QMouseEvent.
+ * Returns true, if intersection is in the visible frustum, else returns false.
+ * If return value is true, *intersection is the intersection of the mouse ray line with
+ * the plane normal*(x,y,z) + d = 0.
+ * If return value is false, *intersection is not modified.
+ */
+bool GLESRenderer::mouseIntersection(QVector3D * intersection, QVector3D normal, float d, const QPoint & mousePos)
+{
+ float m0, m15;
+ QVector3D pNear, pFar; //mouse intersections on near and far clipping plane
+ calculateMousePoints(&pNear, &pFar, mousePos);
+ QVector3D v = pFar - pNear; //vector from near to far clipping plane
+ m15 = d + QVector3D::dotProduct(normal, pNear);
+ m0 = QVector3D::dotProduct( normal, v);
+ if(fabs(m0) < fabs(m15)) //we have no intersection in frustum (lambda will be > 1.0)
+ {
+ return false;
+ }
+ float lambda = -m15 / m0;
+ * intersection = pNear + lambda * v;
+ return true;
+}
+
+/**
+ * Set the color for ambient and diffuse lighting (or no lighting).
+ * Alternatively use a color array and color attribute.
+ */
+void GLESRenderer::setAmbientAndDiffuseColor(const GLColorRgba newVal)
+{
+ m_ambientAndDiffuseColor = newVal;
+ if(m_bound && m_location_uAmbientAndDiffuseColor != -1)
+ m_renderProgram->setUniformValue(m_location_uAmbientAndDiffuseColor, m_ambientAndDiffuseColor);
+}
+
+/**
+ * Set the dimming factor for ambient light.
+ * Defaults to 0.2.
+ */
+void GLESRenderer::setAmbientLightBrightness(float newVal)
+{
+ m_ambientLightBrightness = newVal;
+ if(m_bound && m_location_uAmbientLightBrightness != -1)
+ m_renderProgram->setUniformValue(m_location_uAmbientLightBrightness, m_ambientLightBrightness);
+}
+
+/**
+ * Set the color for specular lighting.
+ */
+void GLESRenderer::setSpecularColor(const GLColorRgba newVal)
+{
+ m_specularColor = newVal;
+ if(m_bound && (m_location_uSpecularColor != -1))
+ m_renderProgram->setUniformValue(m_location_uSpecularColor,
+ m_specularColor.red(), m_specularColor.green(),
+ m_specularColor.blue(), m_specularColor.alpha());
+}
+
+/**
+ * Set the shininess for specular lighting.
+ */
+void GLESRenderer::setShininess(float newVal)
+{
+ m_shininess = newVal;
+ if(m_bound && (m_location_uShininess != -1))
+ m_renderProgram->setUniformValue(m_location_uShininess, m_shininess);
+}
+
+/**
+ * Enable / disable lighting.
+ */
+void GLESRenderer::setLightingEnabled(bool newVal)
+{
+ m_lightingEnabled = newVal;
+ if(m_bound && (m_location_uLightingEnabled != -1))
+ m_renderProgram->setUniformValue(m_location_uLightingEnabled, m_lightingEnabled);
+}
+
+/**
+ * Enable / disable color array.
+ */
+void GLESRenderer::setColorArrayEnabled(bool newVal)
+{
+ m_colorArrayEnabled = newVal;
+ if(m_bound && (m_location_uColorArrayEnabled != -1))
+ m_renderProgram->setUniformValue(m_location_uColorArrayEnabled, m_colorArrayEnabled);
+}
+
+/**
+ * Set the texture flag.
+ */
+void GLESRenderer::setTextureEnabled(bool newVal)
+{
+ m_textureEnabled = newVal;
+ if(m_bound && (m_location_uTextureEnabled != -1))
+ m_renderProgram->setUniformValue(m_location_uTextureEnabled, m_textureEnabled);
+}
+
+/**
+ * Set light direction.
+ */
+void GLESRenderer::setLightDirection(const QVector3D & newVal)
+{
+ m_lightDirection = newVal;
+#ifdef DEBUG_GLESRENDERER
+ ShaderDebugger::debugVector3D(m_lightDirection, "GLESRenderer uses lightDirection in object space:");
+#endif
+ QMatrix4x4 nMatrix = QMatrix4x4(m_normalMatrix);
+ m_lightDirection = (nMatrix * m_lightDirection).normalized();//transform to eye space
+ m_halfPlaneVector = (m_lightDirection + QVector3D(0.0,0.0,1.0)).normalized();//eye direction is 0,0,1 in eye space
+#ifdef DEBUG_GLESRENDERER
+ ShaderDebugger::debugVector3D(m_lightDirection, "GLESRenderer uses lightDirection in eye space:");
+ ShaderDebugger::debugVector3D(m_lightDirection, "GLESRenderer uses halfplane vector in eye space:");
+#endif
+ if(m_bound && (m_location_uLightDirection != -1))
+ m_renderProgram->setUniformValue(m_location_uLightDirection, m_lightDirection);
+ if(m_location_uHalfPlaneVector != -1)
+ m_renderProgram->setUniformValue(m_location_uHalfPlaneVector, m_halfPlaneVector);
+}
+
+/**
+ * Set size of points drawn with GL_POINTS.
+ */
+void GLESRenderer::setPointSize(int newVal)
+{
+ m_pointSize = newVal;
+ if(m_bound && (m_location_uPointSize != -1))
+ m_renderProgram->setUniformValue(m_location_uPointSize, m_pointSize);
+#ifndef GLES
+ glPointSize(m_pointSize); //set point size independent of vertex shader
+#endif
+}
+
+/**
+ * Pops mvMatrix from stack and updates normalMatrix and mvpMatrix.
+ */
+void GLESRenderer::popMvMatrix()
+{
+ setMvMatrix(m_mvMatrixStack.pop());
+}
+
+/**
+ * Translates mvMatrix by v
+ */
+void GLESRenderer::translate(const QVector3D & v)
+{
+ m_mvMatrix.translate(v);
+ setMvMatrix(m_mvMatrix); //update normalMatrix and mvpMatrix and copy to shader
+}
+
+/**
+ * Rotates mvMatrix by angle around axis
+ */
+void GLESRenderer::rotate(GLfloat angle, const QVector3D & axis)
+{
+ m_mvMatrix.rotate(angle, axis);
+ setMvMatrix(m_mvMatrix); //update normalMatrix and mvpMatrix and copy to shader
+}
+
+void GLESRenderer::addTransformation(const QMatrix4x4 additionalTransformation)
+{
+ setMvMatrix(m_mvMatrix * additionalTransformation); //update normalMatrix and mvpMatrix and copy to shader
+}
+
+/**
+ * Scales mvMatrix.
+ */
+void GLESRenderer::scale(const QVector3D & v )
+{
+ m_mvMatrix.scale(v);
+ setMvMatrix(m_mvMatrix);//update normalMatrix and mvpMatrix and copy to shader
+}
+
+void GLESRenderer::rotate( float angle, float x, float y, float z ) {
+ m_mvMatrix.rotate ( angle, x, y, z );
+ setMvMatrix( m_mvMatrix );
+} /* ----- end of method mvRotate ----- */
+
+void GLESRenderer::zoom( float zoomFactor ) {
+ // Es muss vor dem Zoom die Einheitsmatrix generiert werden. Ansonsten wird das vorherige Zoomen dazu addiert
+ m_pMatrix.setToIdentity();
+ m_pMatrix.perspective ( m_fovy * zoomFactor, m_aspect, m_nearClip, m_farClip );
+ // Auch hier muss die ProjectionModelView Matrix neu berechnet werden
+ m_mvpMatrix = m_pMatrix * m_mvMatrix;
+}
+
+
+void GLESRenderer::translate( float x, float y, float z ) {
+ m_mvMatrix.translate( x, y, z );
+ setMvMatrix( m_mvMatrix);
+} /* ----- end of method translate ----- */
+
+
+/**
+ * Compile shaders, get attribute and uniform locations.
+ * This function needs an active OpenGL context.
+ */
+bool GLESRenderer::initialize()
+{
+ if(m_initialized)
+ return true;
+ //Setup shaders and program
+ m_vShader = new QOpenGLShader(QOpenGLShader::Vertex,this); //vertex shader
+ m_vShader->compileSourceFile(m_vShaderFileName);
+ if(!m_vShader->isCompiled())
+ {
+ qDebug("GLESRenderer::initialize: Compiling vertex shader failed. Log follows:\n%s",
+ qPrintable(m_vShader->log()));
+ return false;
+ }
+ m_fShader = new QOpenGLShader(QOpenGLShader::Fragment,this); // fragment shader
+ m_fShader->compileSourceFile(m_fShaderFileName);
+ if(!m_fShader->isCompiled())
+ {
+ qDebug("GLESRenderer::initialize: Compiling fragment shader failed. Log follows:\n%s",
+ qPrintable(m_fShader->log()));
+ return false;
+ }
+
+ m_renderProgram = new QOpenGLShaderProgram(this);
+ m_renderProgram->addShader(m_vShader);
+ m_renderProgram->addShader(m_fShader);
+ m_renderProgram->link();
+ if(!m_renderProgram->isLinked())
+ {
+ qDebug("GLESRenderer::initialize: Linking program failed. Log follows:\n%s",
+ qPrintable(m_renderProgram->log()));
+ return false;
+ }
+
+ // Get all locations of shader variables
+ //Get locations of attributes and uniforms
+ //Non existing attributes and uniforms will return -1
+ //Attributes
+ m_location_aVertex = m_renderProgram->attributeLocation("a_Vertex");
+ m_location_aColor = m_renderProgram->attributeLocation("a_Color");
+ m_location_aNormal = m_renderProgram->attributeLocation("a_Normal");
+ m_location_aTexCoord = m_renderProgram->attributeLocation("a_TexCoord");
+ //Uniforms
+ //flags
+ m_location_uLightingEnabled = m_renderProgram->uniformLocation("u_LightingEnabled");
+ m_location_uColorArrayEnabled = m_renderProgram->uniformLocation("u_ColorArrayEnabled");
+ m_location_uTextureEnabled = m_renderProgram->uniformLocation("u_TextureEnabled");
+ //matrices
+ m_location_uNormalMatrix = m_renderProgram->uniformLocation("u_NormalMatrix");
+ m_location_uMvpMatrix = m_renderProgram->uniformLocation("u_MvpMatrix");
+ //lighting
+ m_location_uAmbientAndDiffuseColor = m_renderProgram->uniformLocation("u_AmbientAndDiffuseColor");
+ m_location_uAmbientLightBrightness = m_renderProgram->uniformLocation("u_AmbientLightBrightness");
+ m_location_uLightDirection = m_renderProgram->uniformLocation("u_LightDirection");
+ m_location_uSpecularColor = m_renderProgram->uniformLocation("u_SpecularColor");
+ m_location_uShininess = m_renderProgram->uniformLocation("u_Shininess");
+ m_location_uHalfPlaneVector = m_renderProgram->uniformLocation("u_HalfPlaneVector");
+ //texture
+ m_location_uTextureSampler = m_renderProgram->uniformLocation("s_Texture");
+ //point size
+ m_location_uPointSize = m_renderProgram->uniformLocation("u_PointSize");
+
+#ifdef DEBUG_GLESRENDERER
+ ShaderDebugger::setEnabled(true);
+ ShaderDebugger::debugUniforms(m_renderProgram->programId());
+ ShaderDebugger::setEnabled(false);
+#endif
+
+ //get present viewport settings
+ readGLViewportSettings();
+ m_initialized = true;
+ return true;
+}
+
+/**
+ * Bind program and transfer attribute and uniform data to the shaders.
+ * Calls initialize, if not already initialized.
+ */
+bool GLESRenderer::bind()
+{
+ bool ok = true;
+ if(!m_initialized)
+ ok = initialize();
+ if(!ok)
+ return false;
+ m_renderProgram->bind();
+ //Activate uniforms
+ //flags
+ if(m_location_uColorArrayEnabled != -1)
+ m_renderProgram->setUniformValue(m_location_uColorArrayEnabled, m_colorArrayEnabled);
+ if(m_location_uLightingEnabled != -1)
+ m_renderProgram->setUniformValue(m_location_uLightingEnabled, m_lightingEnabled);
+ if(m_location_uTextureEnabled != -1)
+ m_renderProgram->setUniformValue(m_location_uTextureEnabled, m_textureEnabled);
+ //matrices
+ if( m_location_uNormalMatrix != -1)
+ m_renderProgram->setUniformValue(m_location_uNormalMatrix, m_normalMatrix);
+ if(m_location_uMvpMatrix != -1)
+ m_renderProgram->setUniformValue(m_location_uMvpMatrix, m_mvpMatrix);
+ //lighting
+ if(m_location_uAmbientAndDiffuseColor != -1)
+ m_renderProgram->setUniformValue(m_location_uAmbientAndDiffuseColor,
+ m_ambientAndDiffuseColor.red(), m_ambientAndDiffuseColor.green(),
+ m_ambientAndDiffuseColor.blue(), m_ambientAndDiffuseColor.alpha());
+ if(m_location_uAmbientLightBrightness != -1)
+ m_renderProgram->setUniformValue(m_location_uAmbientLightBrightness, m_ambientLightBrightness);
+ if(m_location_uLightDirection != -1)
+ m_renderProgram->setUniformValue(m_location_uLightDirection, m_lightDirection);
+ if(m_location_uSpecularColor != -1)
+ m_renderProgram->setUniformValue(m_location_uSpecularColor,
+ m_specularColor.red(), m_specularColor.green(),
+ m_specularColor.blue(), m_specularColor.alpha());
+ if(m_location_uShininess != -1)
+ m_renderProgram->setUniformValue(m_location_uShininess, m_shininess);
+ if(m_location_uHalfPlaneVector != -1)
+ m_renderProgram->setUniformValue(m_location_uHalfPlaneVector, m_halfPlaneVector);
+ //texture
+ if(m_location_uTextureSampler != -1)
+ m_renderProgram->setUniformValue(m_location_uTextureSampler, 0); //set sampler to use texture unit 0
+ //point size
+ if(m_location_uPointSize != -1)
+ m_renderProgram->setUniformValue(m_location_uPointSize, m_pointSize);
+#ifndef GLES
+ glPointSize(m_pointSize); //set point size independent of vertex shader
+#endif
+
+ m_renderProgram->setUniformValue("u_viewPortCenter",
+ QVector2D(m_viewportW / 2, m_viewportH /2));
+ GLfloat diameterSquare = 200.0 * 200.0;
+ m_renderProgram->setUniformValue("u_diameterSquare", diameterSquare);
+
+
+ m_bound = true;
+ return m_bound;
+}
+
+/**
+ * Enables Vertex, normal, color or texCoord arrays and sets start adresses of arrays
+ * arrayLocation may be: VERTEX_LOCATION, NORMAL_LOCATION, COLOR_LOCATION, TEXCOORD_LOCATION
+ */
+bool GLESRenderer::activateAttributeArray (AttributeLocation arrayLocation, const QVector2D *values, int stride )
+{
+ return activateAttributeArray(arrayLocation, (float*)values, 2, stride);
+}
+/**
+ * Enables Vertex, normal, color or texCoord arrays and sets start adresses of arrays
+ * arrayLocation may be: VERTEX_LOCATION, NORMAL_LOCATION, COLOR_LOCATION, TEXCOORD_LOCATION
+ */
+bool GLESRenderer::activateAttributeArray (AttributeLocation arrayLocation, const QVector3D *values, int stride )
+{
+ return activateAttributeArray(arrayLocation, (float*)values, 3, stride);
+}
+/**
+ * Enables Vertex, normal, color or texCoord arrays and sets start adresses of arrays
+ * arrayLocation may be: VERTEX_LOCATION, NORMAL_LOCATION, COLOR_LOCATION, TEXCOORD_LOCATION
+ */
+bool GLESRenderer::activateAttributeArray (AttributeLocation arrayLocation, const QVector4D *values, int stride )
+{
+ return activateAttributeArray(arrayLocation, (float*)values, 4, stride);
+}
+
+/**
+ * Enables Vertex, normal, color or texCoord arrays and sets start adresses of arrays
+ * arrayLocation may be: VERTEX_LOCATION, NORMAL_LOCATION, COLOR_LOCATION, TEXCOORD_LOCATION
+ */
+bool GLESRenderer::activateAttributeArray (AttributeLocation arrayLocation, const float * values, int tupleSize, int stride )
+{
+ int location = -1;
+ switch(arrayLocation){
+ case VERTEX_LOCATION: location = m_location_aVertex; break;
+ case NORMAL_LOCATION: location = m_location_aNormal; break;
+ case COLOR_LOCATION : location = m_location_aColor; break;
+ case TEXCOORD_LOCATION : location = m_location_aTexCoord; break;
+ default: return false;
+ }
+
+ if(values && (location != -1))
+ {
+ m_renderProgram->enableAttributeArray(location);
+ m_renderProgram->setAttributeArray(location, values, tupleSize, stride);
+ m_activeAttributeLocations.append(location);
+ return true;
+ }
+ else return false;
+}
+
+///**
+// * Enables Vertex, normal, color or texCoord arrays and sets start adresses of arrays
+// * Type may be: VERTEX_LOCATION, COLOR_LOCATION
+// */
+//bool GLESRenderer::activateAttributeArray (AttributeLocation arrayLocation, const QVector4D * values, int stride )
+//{
+// if(!m_initialized)
+// return false;
+// int location = -1;
+// switch(arrayLocation){
+// case VERTEX_LOCATION: location = m_location_aVertex; break;
+// case COLOR_LOCATION : location = m_location_aColor; break;
+// default: return false;
+// }
+
+// if(values && (location != -1))
+// {
+// m_renderProgram->enableAttributeArray(location);
+// m_renderProgram->setAttributeArray(location, GL_FLOAT, values, 4, stride);
+// m_activeAttributeLocations.append(location);
+// return true;
+// }
+// else return false;
+//}
+
+bool GLESRenderer::activateAttributeBuffer(GLESRenderer::AttributeLocation bufferLocation, int bufferId, int stride)
+{
+ int location = -1;
+ int elements = 3;
+ int offset = 0;
+ switch(bufferLocation){
+ case VERTEX_LOCATION: location = m_location_aVertex; break;
+ case NORMAL_LOCATION: location = m_location_aNormal; break;
+ case COLOR_LOCATION : {
+ location = m_location_aColor;
+ elements = 4; //RGBA colors
+ }break;
+ case TEXCOORD_LOCATION : location = m_location_aTexCoord; break;
+ default: return false;
+ }
+ if( bufferId != 0 ) {
+ m_renderProgram->setAttributeBuffer(location, GL_FLOAT, offset, elements, stride);
+ m_renderProgram->enableAttributeArray( location );
+ return true;
+ }
+ else {
+ qDebug() << "GLESRenderer::activateAttributeBuffer: Error, invalid buffer id";
+ return false;
+ }
+}
+
+/**
+ * Disables all enabled attribute arrays.
+ */
+void GLESRenderer::disableAttributeArrays()
+{
+ for(int i = 0; i < m_activeAttributeLocations.size(); i++)
+ m_renderProgram->disableAttributeArray(m_activeAttributeLocations[i]);
+ m_activeAttributeLocations.clear();
+}
+
+/**
+ * Releases program. To be called, when all rendering is finished.
+ */
+void GLESRenderer::release()
+{
+ disableAttributeArrays();
+ if(m_renderProgram)
+ m_renderProgram->release();
+ else qDebug() << "GLESRenderer::release() called without valid render program.";
+ m_bound = false;
+}
+
+/**
+ * get the present settings from GL engine
+ */
+void GLESRenderer::readGLViewportSettings()
+{
+ GLint vp[4];
+ glGetIntegerv(GL_VIEWPORT, vp);
+ m_viewportX = vp[0];
+ m_viewportY = vp[1];
+ m_viewportW = vp[2];
+ m_viewportH = vp[3];
+}
+
+/**
+ * Multiplies current mvp matrix with v. Mainly for debugging.
+ */
+QVector3D GLESRenderer::modelToClip(const QVector3D & v)
+{
+ ShaderDebugger::debugVector3D(v, "Vector in model space:");
+ QVector3D result = m_mvpMatrix * v;
+ ShaderDebugger::debugVector3D(result, "Vector in clip space:");
+ return result;
+}
+
+/**
+ * Performs viewport transform. Mainly for debugging.
+ */
+QVector3D GLESRenderer::clipToViewport(const QVector3D & v)
+{
+ float ox = (m_viewportX + m_viewportW) / 2.0;
+ float oy = (m_viewportY + m_viewportH) / 2.0;
+ ShaderDebugger::debugVector3D(v, "Vector in clip space:");
+ float xw = (m_viewportW / 2.0) * v.x() + ox;
+ float yw = (m_viewportH / 2.0) * v.y() + oy;
+ float zw = ((m_farClip - m_nearClip) / 2.0) * v.z() + (m_nearClip + m_farClip) / 2.0;
+ QVector3D result = QVector3D(xw, yw, zw);
+ ShaderDebugger::debugVector3D(result, "Vector in viewport space:");
+ return result;
+}
+
+