summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/surfacechart/main.cpp24
-rw-r--r--src/datavis3d/engine/drawer.cpp34
-rw-r--r--src/datavis3d/engine/drawer_p.h7
-rw-r--r--src/datavis3d/engine/engine.qrc6
-rw-r--r--src/datavis3d/engine/shaders/surface.frag38
-rw-r--r--src/datavis3d/engine/shaders/surface.vert29
-rw-r--r--src/datavis3d/engine/shaders/surfaceFlat.frag38
-rw-r--r--src/datavis3d/engine/shaders/surfaceFlat.vert29
-rw-r--r--src/datavis3d/engine/shaders/surfaceGrid.frag18
-rw-r--r--src/datavis3d/engine/shaders/surfaceGrid.vert28
-rw-r--r--src/datavis3d/engine/surface3dcontroller.cpp1
-rw-r--r--src/datavis3d/engine/surface3drenderer.cpp139
-rw-r--r--src/datavis3d/engine/surface3drenderer_p.h10
-rw-r--r--src/datavis3d/utils/abstractobjecthelper.cpp101
-rw-r--r--src/datavis3d/utils/abstractobjecthelper_p.h85
-rw-r--r--src/datavis3d/utils/objecthelper.cpp47
-rw-r--r--src/datavis3d/utils/objecthelper_p.h22
-rw-r--r--src/datavis3d/utils/surfaceobject.cpp352
-rw-r--r--src/datavis3d/utils/surfaceobject_p.h88
-rw-r--r--src/datavis3d/utils/utils.pri8
20 files changed, 1023 insertions, 81 deletions
diff --git a/examples/surfacechart/main.cpp b/examples/surfacechart/main.cpp
index 330f83dd..b984f7f1 100644
--- a/examples/surfacechart/main.cpp
+++ b/examples/surfacechart/main.cpp
@@ -52,15 +52,21 @@ int main(int argc, char *argv[])
Q3DSurface surfaceChart;
QList<qreal> lowList;
- lowList << 15.0 << 65.0 << 105.0 << 65.0 << 15.0;
- lowList << 35.0 << 105.0 << 170.0 << 105.0 << 35;
- lowList << 55.0 << 135.0 << 215.0 << 135.0 << 55;
- lowList << 75.0 << 155.0 << 240.0 << 155.0 << 75;
- lowList << 80.0 << 190.0 << 245.0 << 190.0 << 80;
- lowList << 75.0 << 155.0 << 240.0 << 155.0 << 75.0;
- lowList << 55.0 << 135.0 << 215.0 << 135.0 << 55;
- lowList << 35.0 << 105.0 << 170.0 << 105.0 << 35.0;
- lowList << 15.0 << 65.0 << 105.0 << 65.0 << 16.1;
+ lowList << 15.0 << 35.0 << 55.0 << 75.0 << 80.0 << 75.0 << 55.0 << 35.0 << 15.0;
+ lowList << 65.0 << 105.0 << 135.0 << 155.0 << 190.0 << 155.0 << 135.0 << 105.0 << 65.0;
+ lowList << 105.0 << 170.0 << 215.0 << 240.0 << 245.0 << 240.0 << 215.0 << 170.0 << 105.0;
+ lowList << 65.0 << 105.0 << 135.0 << 155.0 << 190.0 << 155.0 << 135.0 << 105.0 << 65.0;
+ lowList << 15.0 << 35.0 << 55.0 << 75.0 << 80.0 << 75.0 << 55.0 << 35.0 << 16.1;
+
+// lowList << 15.0 << 65.0 << 105.0 << 65.0 << 15.0;
+// lowList << 35.0 << 105.0 << 170.0 << 105.0 << 35;
+// lowList << 55.0 << 135.0 << 215.0 << 135.0 << 55;
+// lowList << 75.0 << 155.0 << 240.0 << 155.0 << 75;
+// lowList << 80.0 << 190.0 << 245.0 << 190.0 << 80;
+// lowList << 75.0 << 155.0 << 240.0 << 155.0 << 75.0;
+// lowList << 55.0 << 135.0 << 215.0 << 135.0 << 55;
+// lowList << 35.0 << 105.0 << 170.0 << 105.0 << 35.0;
+// lowList << 15.0 << 65.0 << 105.0 << 65.0 << 16.1;
surfaceChart.appendSeries(lowList);
diff --git a/src/datavis3d/engine/drawer.cpp b/src/datavis3d/engine/drawer.cpp
index 675848b0..464ad518 100644
--- a/src/datavis3d/engine/drawer.cpp
+++ b/src/datavis3d/engine/drawer.cpp
@@ -43,6 +43,8 @@
#include "drawer_p.h"
#include "shaderhelper_p.h"
#include "objecthelper_p.h"
+#include "abstractobjecthelper_p.h"
+#include "surfaceobject_p.h"
#include "camerahelper_p.h"
#include "utils_p.h"
#include "texturehelper_p.h"
@@ -100,7 +102,7 @@ void Drawer::setTransparency(LabelTransparency transparency)
emit drawerChanged();
}
-void Drawer::drawObject(ShaderHelper *shader, ObjectHelper *object, GLuint textureId,
+void Drawer::drawObject(ShaderHelper *shader, AbstractObjectHelper *object, GLuint textureId,
GLuint depthTextureId)
{
// Store the GL state before changing
@@ -161,6 +163,36 @@ void Drawer::drawObject(ShaderHelper *shader, ObjectHelper *object, GLuint textu
glBindTexture(GL_TEXTURE_2D, *oldTexId);
}
+void Drawer::drawSurfaceGrid(ShaderHelper *shader, SurfaceObject *object)
+{
+ // Store the GL state before changing
+ GLint oldActiveTex[1];
+ glGetIntegerv(GL_ACTIVE_TEXTURE, oldActiveTex);
+ GLint oldTexId[1];
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, oldTexId);
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(shader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, object->vertexBuf());
+ glVertexAttribPointer(shader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object->gridElementBuf());
+
+ // Draw the lines
+ glDrawElements(GL_LINES, object->gridIndexCount(), GL_UNSIGNED_SHORT, (void*)0);
+
+ // Free buffers
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ glDisableVertexAttribArray(shader->posAtt());
+
+ // Restore the GL state
+ glActiveTexture(*oldActiveTex);
+ glBindTexture(GL_TEXTURE_2D, *oldTexId);
+}
+
void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelItem,
const QMatrix4x4 &viewmatrix, const QMatrix4x4 &projectionmatrix,
const QVector3D &positionComp, const QVector3D &rotation,
diff --git a/src/datavis3d/engine/drawer_p.h b/src/datavis3d/engine/drawer_p.h
index 27f1e871..659599d0 100644
--- a/src/datavis3d/engine/drawer_p.h
+++ b/src/datavis3d/engine/drawer_p.h
@@ -63,6 +63,8 @@ QT_DATAVIS3D_BEGIN_NAMESPACE
class ShaderHelper;
class ObjectHelper;
+class AbstractObjectHelper;
+class SurfaceObject;
class TextureHelper;
class CameraHelper;
@@ -80,9 +82,10 @@ public:
void setFont(const QFont &font);
void setTransparency(LabelTransparency transparency);
- void drawObject(ShaderHelper *shader, ObjectHelper *object, GLuint textureId = 0,
+ void drawObject(ShaderHelper *shader, AbstractObjectHelper *object, GLuint textureId = 0,
GLuint depthTextureId = 0);
- void drawLabel(const AbstractRenderItem &item, const LabelItem &label,
+ void drawSurfaceGrid(ShaderHelper *shader, SurfaceObject *object);
+ void drawLabel(const AbstractRenderItem &item, const LabelItem &labelItem,
const QMatrix4x4 &viewmatrix, const QMatrix4x4 &projectionmatrix,
const QVector3D &positionComp, const QVector3D &rotation, GLfloat itemHeight,
SelectionMode mode, ShaderHelper *shader, ObjectHelper *object,
diff --git a/src/datavis3d/engine/engine.qrc b/src/datavis3d/engine/engine.qrc
index 2588197a..5c9df92a 100644
--- a/src/datavis3d/engine/engine.qrc
+++ b/src/datavis3d/engine/engine.qrc
@@ -48,6 +48,12 @@
<file alias="fragmentES2">shaders/default_ES2.frag</file>
<file alias="vertexES2">shaders/default_ES2.vert</file>
<file alias="fragmentTextureES2">shaders/texture_ES2.frag</file>
+ <file alias="fragmentSurface">shaders/surface.frag</file>
+ <file alias="vertexSurface">shaders/surface.vert</file>
+ <file alias="fragmentSurfaceGrid">shaders/surfaceGrid.frag</file>
+ <file alias="vertexSurfaceGrid">shaders/surfaceGrid.vert</file>
+ <file alias="vertexSurfaceFlat">shaders/surfaceFlat.vert</file>
+ <file alias="fragmentSurfaceFlat">shaders/surfaceFlat.frag</file>
</qresource>
<qresource prefix="/textures"/>
</RCC>
diff --git a/src/datavis3d/engine/shaders/surface.frag b/src/datavis3d/engine/shaders/surface.frag
new file mode 100644
index 00000000..af75cbb9
--- /dev/null
+++ b/src/datavis3d/engine/shaders/surface.frag
@@ -0,0 +1,38 @@
+#version 150
+
+varying highp vec2 UV;
+varying highp vec3 coords_mdl;
+varying highp vec3 position_wrld;
+varying highp vec3 normal_cmr;
+varying highp vec3 eyeDirection_cmr;
+varying highp vec3 lightDirection_cmr;
+
+uniform highp vec3 lightPosition_wrld;
+uniform highp vec3 color_mdl;
+uniform highp float lightStrength;
+uniform highp float ambientStrength;
+
+void main() {
+ highp vec3 materialDiffuseColor = vec3(position_wrld.y, 1.0 - position_wrld.y, 0.0);
+ highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor;
+ highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0);
+
+ highp float distance = length(lightPosition_wrld - position_wrld);
+
+ highp vec3 n = normalize(normal_cmr);
+ highp vec3 l = normalize(lightDirection_cmr);
+ highp float cosTheta = clamp(dot(n, l), 0.0, 1.0);
+
+ highp vec3 E = normalize(eyeDirection_cmr);
+ highp vec3 R = reflect(-l, n);
+ highp float cosAlpha = clamp(dot(E, R), 0.0, 1.0);
+
+// gl_FragColor.rgb = n;
+ gl_FragColor.rgb =
+ materialAmbientColor +
+ materialDiffuseColor * lightStrength * pow(cosTheta, 2) / distance +
+ materialSpecularColor * lightStrength * pow(cosAlpha, 10) / distance;
+ gl_FragColor.a = 1.0;
+// gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+
diff --git a/src/datavis3d/engine/shaders/surface.vert b/src/datavis3d/engine/shaders/surface.vert
new file mode 100644
index 00000000..20aad190
--- /dev/null
+++ b/src/datavis3d/engine/shaders/surface.vert
@@ -0,0 +1,29 @@
+#version 150
+
+attribute highp vec3 vertexPosition_mdl;
+attribute highp vec2 vertexUV;
+attribute highp vec3 vertexNormal_mdl;
+
+uniform highp mat4 MVP;
+uniform highp mat4 V;
+uniform highp mat4 M;
+uniform highp mat4 itM;
+uniform highp vec3 lightPosition_wrld;
+
+varying highp vec3 position_wrld;
+varying highp vec3 normal_cmr;
+varying highp vec3 eyeDirection_cmr;
+varying highp vec3 lightDirection_cmr;
+varying highp vec3 coords_mdl;
+
+void main() {
+ gl_Position = MVP * vec4(vertexPosition_mdl, 1.0);
+ coords_mdl = vertexPosition_mdl;
+ position_wrld = (M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ vec3 vertexPosition_cmr = (V * M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ eyeDirection_cmr = vec3(0.0, 0.0, 0.0) - vertexPosition_cmr;
+ vec3 lightPosition_cmr = (V * vec4(lightPosition_wrld, 1.0)).xyz;
+ lightDirection_cmr = lightPosition_cmr + eyeDirection_cmr;
+ normal_cmr = (V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
+ //normal_cmr = vertexNormal_mdl;
+}
diff --git a/src/datavis3d/engine/shaders/surfaceFlat.frag b/src/datavis3d/engine/shaders/surfaceFlat.frag
new file mode 100644
index 00000000..b07acbad
--- /dev/null
+++ b/src/datavis3d/engine/shaders/surfaceFlat.frag
@@ -0,0 +1,38 @@
+#version 150
+
+varying highp vec2 UV;
+varying highp vec3 coords_mdl;
+varying highp vec3 position_wrld;
+flat in highp vec3 normal_cmr;
+varying highp vec3 eyeDirection_cmr;
+varying highp vec3 lightDirection_cmr;
+
+uniform highp vec3 lightPosition_wrld;
+uniform highp vec3 color_mdl;
+uniform highp float lightStrength;
+uniform highp float ambientStrength;
+
+void main() {
+ highp vec3 materialDiffuseColor = vec3(position_wrld.y, 1.0 - position_wrld.y, 0.0);
+ highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor;
+ highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0);
+
+ highp float distance = length(lightPosition_wrld - position_wrld);
+
+ highp vec3 n = normalize(normal_cmr);
+ highp vec3 l = normalize(lightDirection_cmr);
+ highp float cosTheta = clamp(dot(n, l), 0.0, 1.0);
+
+ highp vec3 E = normalize(eyeDirection_cmr);
+ highp vec3 R = reflect(-l, n);
+ highp float cosAlpha = clamp(dot(E, R), 0.0, 1.0);
+
+// gl_FragColor.rgb = n;
+ gl_FragColor.rgb =
+ materialAmbientColor +
+ materialDiffuseColor * lightStrength * pow(cosTheta, 2) / distance +
+ materialSpecularColor * lightStrength * pow(cosAlpha, 10) / distance;
+ gl_FragColor.a = 1.0;
+// gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+
diff --git a/src/datavis3d/engine/shaders/surfaceFlat.vert b/src/datavis3d/engine/shaders/surfaceFlat.vert
new file mode 100644
index 00000000..4adc511e
--- /dev/null
+++ b/src/datavis3d/engine/shaders/surfaceFlat.vert
@@ -0,0 +1,29 @@
+#version 150
+
+attribute highp vec3 vertexPosition_mdl;
+attribute highp vec2 vertexUV;
+attribute highp vec3 vertexNormal_mdl;
+
+uniform highp mat4 MVP;
+uniform highp mat4 V;
+uniform highp mat4 M;
+uniform highp mat4 itM;
+uniform highp vec3 lightPosition_wrld;
+
+varying highp vec3 position_wrld;
+flat out highp vec3 normal_cmr;
+varying highp vec3 eyeDirection_cmr;
+varying highp vec3 lightDirection_cmr;
+varying highp vec3 coords_mdl;
+
+void main() {
+ gl_Position = MVP * vec4(vertexPosition_mdl, 1.0);
+ coords_mdl = vertexPosition_mdl;
+ position_wrld = (M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ vec3 vertexPosition_cmr = (V * M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ eyeDirection_cmr = vec3(0.0, 0.0, 0.0) - vertexPosition_cmr;
+ vec3 lightPosition_cmr = (V * vec4(lightPosition_wrld, 1.0)).xyz;
+ lightDirection_cmr = lightPosition_cmr + eyeDirection_cmr;
+ normal_cmr = (V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
+ //normal_cmr = vertexNormal_mdl;
+}
diff --git a/src/datavis3d/engine/shaders/surfaceGrid.frag b/src/datavis3d/engine/shaders/surfaceGrid.frag
new file mode 100644
index 00000000..1fe5c68a
--- /dev/null
+++ b/src/datavis3d/engine/shaders/surfaceGrid.frag
@@ -0,0 +1,18 @@
+#version 150
+
+varying highp vec2 UV;
+varying highp vec2 coords_mdl;
+varying highp vec3 position_wrld;
+varying highp vec3 normal_cmr;
+varying highp vec3 eyeDirection_cmr;
+varying highp vec3 lightDirection_cmr;
+
+uniform highp vec3 lightPosition_wrld;
+uniform highp vec3 color_mdl;
+uniform highp float lightStrength;
+uniform highp float ambientStrength;
+
+void main() {
+ gl_FragColor.rgb = color_mdl;
+}
+
diff --git a/src/datavis3d/engine/shaders/surfaceGrid.vert b/src/datavis3d/engine/shaders/surfaceGrid.vert
new file mode 100644
index 00000000..73262c4a
--- /dev/null
+++ b/src/datavis3d/engine/shaders/surfaceGrid.vert
@@ -0,0 +1,28 @@
+#version 150
+
+attribute highp vec3 vertexPosition_mdl;
+attribute highp vec2 vertexUV;
+attribute highp vec3 vertexNormal_mdl;
+
+uniform highp mat4 MVP;
+uniform highp mat4 V;
+uniform highp mat4 M;
+uniform highp mat4 itM;
+uniform highp vec3 lightPosition_wrld;
+
+varying highp vec3 position_wrld;
+varying highp vec3 normal_cmr;
+varying highp vec3 eyeDirection_cmr;
+varying highp vec3 lightDirection_cmr;
+varying highp vec2 coords_mdl;
+
+void main() {
+ gl_Position = MVP * vec4(vertexPosition_mdl, 1.0);
+ coords_mdl = vertexPosition_mdl.xy;
+ position_wrld = (M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ vec3 vertexPosition_cmr = (V * M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ eyeDirection_cmr = vec3(0.0, 0.0, 0.0) - vertexPosition_cmr;
+ vec3 lightPosition_cmr = (V * vec4(lightPosition_wrld, 1.0)).xyz;
+ lightDirection_cmr = lightPosition_cmr + eyeDirection_cmr;
+ normal_cmr = (V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
+}
diff --git a/src/datavis3d/engine/surface3dcontroller.cpp b/src/datavis3d/engine/surface3dcontroller.cpp
index de4befa1..cc37918f 100644
--- a/src/datavis3d/engine/surface3dcontroller.cpp
+++ b/src/datavis3d/engine/surface3dcontroller.cpp
@@ -167,6 +167,7 @@ void Surface3dController::setData(QList<qreal> series, int width, int depth)
m_renderer->setYRangeStuff(5, 50.0f, 0.0f);
m_renderer->setXZStuff(width, depth);
+ m_renderer->setSeries(series);
}
QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/surface3drenderer.cpp b/src/datavis3d/engine/surface3drenderer.cpp
index c1372b2d..93d6f0f4 100644
--- a/src/datavis3d/engine/surface3drenderer.cpp
+++ b/src/datavis3d/engine/surface3drenderer.cpp
@@ -44,6 +44,7 @@
#include "camerahelper_p.h"
#include "shaderhelper_p.h"
#include "objecthelper_p.h"
+#include "surfaceobject_p.h"
#include "texturehelper_p.h"
#include "theme_p.h"
#include "utils_p.h"
@@ -74,6 +75,8 @@ Surface3dRenderer::Surface3dRenderer(Surface3dController *controller)
m_tickXCount(0),
m_tickZCount(0),
m_backgroundShader(0),
+ m_surfaceShader(0),
+ m_surfaceGridShader(0),
m_isInitialized(false),
m_yRange(0.0f), // m_heightNormalizer
m_yAdjustment(0.0f),
@@ -86,9 +89,12 @@ Surface3dRenderer::Surface3dRenderer(Surface3dController *controller)
m_maxSceneSize(40.0),
m_backgroundObj(0),
m_gridLineObj(0),
+ m_surfaceObj(0),
m_depthTexture(0),
m_depthFrameBuffer(0),
+ m_surfaceGridTexture(0),
m_shadowQualityToShader(33.3f),
+ m_smoothSurface(true),
m_drawer(new Drawer(*m_theme, m_font, m_labelTransparency))
{
initializeOpenGL();
@@ -96,6 +102,7 @@ Surface3dRenderer::Surface3dRenderer(Surface3dController *controller)
Surface3dRenderer::~Surface3dRenderer()
{
+ qDebug() << "Surface3dRenderer::~Surface3dRenderer()";
m_textureHelper->glDeleteFramebuffers(1, &m_depthFrameBuffer);
if (m_backgroundShader)
@@ -105,6 +112,7 @@ Surface3dRenderer::~Surface3dRenderer()
m_textureHelper->deleteTexture(&m_depthTexture);
delete m_backgroundObj;
+ delete m_surfaceObj;
delete m_textureHelper;
delete m_drawer;
}
@@ -134,6 +142,8 @@ void Surface3dRenderer::initializeOpenGL()
QStringLiteral(":/shaders/fragmentES2"));
#endif
+ initSurfaceShaders();
+
// Init selection shader
//initSelectionShader();
@@ -168,6 +178,8 @@ void Surface3dRenderer::initializeOpenGL()
// Load background mesh (we need to be initialized first)
loadBackgroundMesh();
+
+ loadSurfaceObj();
}
void Surface3dRenderer::render(CameraHelper *camera, const GLuint defaultFboHandle)
@@ -246,6 +258,78 @@ void Surface3dRenderer::drawScene(CameraHelper *camera, const GLuint defaultFboH
// Enable texturing
glEnable(GL_TEXTURE_2D);
+ m_surfaceShader->bind();
+
+ // For surface we can see climpses from underneath
+ glDisable(GL_CULL_FACE);
+
+ if (1) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(0.0f, 1.0f - m_yAdjustment, zComp);
+ modelMatrix.scale(QVector3D( m_xLength / m_scaleFactor,
+ 1.0f,
+ m_zLength / m_scaleFactor));
+ itModelMatrix.scale(QVector3D( m_xLength / m_scaleFactor,
+ 1.0f,
+ m_zLength / m_scaleFactor));
+
+#ifdef SHOW_DEPTH_TEXTURE_SCENE
+ MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+#else
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+#endif
+ // TODO Check the usage?
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ QVector3D baseColor = Utils::vectorFromColor(QColor(Qt::red)/*m_theme->m_baseColor*/);
+
+ // Set shader bindings
+ m_surfaceShader->setUniformValue(m_surfaceShader->lightP(), lightPos);
+ m_surfaceShader->setUniformValue(m_surfaceShader->view(), viewMatrix);
+ m_surfaceShader->setUniformValue(m_surfaceShader->model(), modelMatrix);
+ m_surfaceShader->setUniformValue(m_surfaceShader->nModel(), itModelMatrix.inverted().transposed());
+ m_surfaceShader->setUniformValue(m_surfaceShader->MVP(), MVPMatrix);
+ m_surfaceShader->setUniformValue(m_surfaceShader->color(), baseColor);
+ m_surfaceShader->setUniformValue(m_surfaceShader->ambientS(), m_theme->m_ambientStrength);
+
+ //IF QT_OPENGL_ES_2 TODO
+ // Shadow quality etc.
+ //m_backgroundShader->setUniformValue(m_backgroundShader->shadowQ(), m_shadowQualityToShader);
+ //m_backgroundShader->setUniformValue(m_backgroundShader->depth(), depthMVPMatrix);
+ m_surfaceShader->setUniformValue(m_surfaceShader->lightS(),
+ m_theme->m_lightStrength * 2.0f);
+
+ m_drawer->drawObject(m_surfaceShader, m_surfaceObj, 0, m_depthTexture);
+ m_surfaceShader->release();
+
+ // Draw the grid over the surface
+ glPolygonOffset(1.0f, 1.0f);
+ glEnable(GL_POLYGON_OFFSET_FILL);
+
+ m_surfaceGridShader->bind();
+
+ QVector3D gridColor = Utils::vectorFromColor(QColor(Qt::white));
+ // Set shader bindings
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->view(), viewMatrix);
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->model(), modelMatrix);
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->nModel(), itModelMatrix.inverted().transposed());
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->MVP(), MVPMatrix);
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->color(), gridColor);
+ //m_surfaceGridShader->setUniformValue(m_surfaceGridShader->ambientS(), m_theme->m_ambientStrength);
+ m_drawer->drawSurfaceGrid(m_surfaceGridShader, m_surfaceObj);
+
+ m_surfaceGridShader->release();
+
+ glPolygonOffset(0.0f, 0.0f);
+ glDisable(GL_POLYGON_OFFSET_FILL);
+ }
+
+ //m_surfaceShader->release();
+
// Bind background shader
m_backgroundShader->bind();
@@ -262,13 +346,13 @@ void Surface3dRenderer::drawScene(CameraHelper *camera, const GLuint defaultFboH
QMatrix4x4 itModelMatrix;
modelMatrix.translate(0.0f, 1.0f - m_yAdjustment, zComp);
- modelMatrix.scale(QVector3D( 9.6f / 4.057f /*m_xLength / m_scaleFactor*/,
+ modelMatrix.scale(QVector3D( m_xLength / m_scaleFactor,
1.0f,
- 7.2f / 4.057f /*m_zLength / m_scaleFactor*/));
+ m_zLength / m_scaleFactor));
modelMatrix.rotate(backgroundRotation, 0.0f, 1.0f, 0.0f);
- itModelMatrix.scale(QVector3D( 9.6f / 4.057f /*m_xLength / m_scaleFactor*/,
+ itModelMatrix.scale(QVector3D( m_xLength / m_scaleFactor,
1.0f,
- 7.2f / 4.057f /*m_zLength / m_scaleFactor*/));
+ m_zLength / m_scaleFactor));
#ifdef SHOW_DEPTH_TEXTURE_SCENE
MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
@@ -350,6 +434,22 @@ void Surface3dRenderer::setXZStuff(GLint tickXCount, GLint tickZCount)
calculateSceneScalingFactors();
}
+void Surface3dRenderer::setSeries(QList<qreal> series)
+{
+// QList<qreal> temp;
+// temp.append(10);temp.append(150);temp.append(50);
+// temp.append(10);temp.append(150);temp.append(50);
+// temp.append(10);temp.append(150);temp.append(50);
+// if (m_smoothSurface)
+// m_surfaceObj->setUpSmoothData(temp, 3, 3, m_yRange);
+// else
+// m_surfaceObj->setUpData(temp, 3, 3, m_yRange);
+ if (m_smoothSurface)
+ m_surfaceObj->setUpSmoothData(series, m_tickXCount, m_tickZCount, m_yRange);
+ else
+ m_surfaceObj->setUpData(series, m_tickXCount, m_tickZCount, m_yRange);
+}
+
void Surface3dRenderer::calculateSceneScalingFactors()
{
// Calculate scene scaling and translation factors
@@ -388,6 +488,17 @@ void Surface3dRenderer::loadBackgroundMesh()
m_backgroundObj->load();
}
+void Surface3dRenderer::loadSurfaceObj()
+{
+ if (!m_isInitialized)
+ return;
+
+ if (m_surfaceObj)
+ delete m_surfaceObj;
+ m_surfaceObj = new SurfaceObject();
+ //m_surfaceObj->setUpData();
+}
+
void Surface3dRenderer::loadGridLineMesh()
{
if (m_gridLineObj)
@@ -550,4 +661,24 @@ void Surface3dRenderer::initBackgroundShaders(const QString &vertexShader,
m_backgroundShader->initialize();
}
+void Surface3dRenderer::initSurfaceShaders()
+{
+ if (m_surfaceShader)
+ delete m_surfaceShader;
+ if (m_smoothSurface) {
+ m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurface"),
+ QStringLiteral(":/shaders/fragmentSurface"));
+ } else {
+ m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceFlat"),
+ QStringLiteral(":/shaders/fragmentSurfaceFlat"));
+ }
+ m_surfaceShader->initialize();
+
+ if (m_surfaceGridShader)
+ delete m_surfaceGridShader;
+ m_surfaceGridShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceGrid"),
+ QStringLiteral(":/shaders/fragmentSurfaceGrid"));
+ m_surfaceGridShader->initialize();
+}
+
QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/surface3drenderer_p.h b/src/datavis3d/engine/surface3drenderer_p.h
index d2912c41..07116987 100644
--- a/src/datavis3d/engine/surface3drenderer_p.h
+++ b/src/datavis3d/engine/surface3drenderer_p.h
@@ -67,6 +67,7 @@ QT_DATAVIS3D_BEGIN_NAMESPACE
class ShaderHelper;
class ObjectHelper;
+class SurfaceObject;
class TextureHelper;
class Theme;
class Drawer;
@@ -114,6 +115,8 @@ private:
QRect m_mainViewPort;
QRect m_sliceViewPort;
ShaderHelper *m_backgroundShader;
+ ShaderHelper *m_surfaceShader;
+ ShaderHelper *m_surfaceGridShader;
TextureHelper *m_textureHelper;
bool m_isInitialized;
GLfloat m_yRange; // m_heightNormalizer
@@ -127,9 +130,12 @@ private:
GLfloat m_maxSceneSize;
ObjectHelper *m_backgroundObj;
ObjectHelper *m_gridLineObj;
+ SurfaceObject *m_surfaceObj;
GLuint m_depthTexture;
GLuint m_depthFrameBuffer;
+ GLuint m_surfaceGridTexture;
GLfloat m_shadowQualityToShader;
+ bool m_smoothSurface;
Drawer *m_drawer;
@@ -166,21 +172,23 @@ public:
void wheelEvent(QWheelEvent *event);
void handleResize();
-
#if !defined(QT_OPENGL_ES_2)
void updateDepthBuffer();
#endif
void loadBackgroundMesh();
void loadGridLineMesh();
+ void loadSurfaceObj();
// TODO: temp
void setYRangeStuff(GLint tickCount, GLfloat step, GLfloat minimum);
void setXZStuff(GLint tickXCount, GLint tickZCount);
+ void setSeries(QList<qreal> series);
private:
void drawScene(CameraHelper *camera, const GLuint defaultFboHandle);
void calculateSceneScalingFactors();
void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader);
+ void initSurfaceShaders();
Q_DISABLE_COPY(Surface3dRenderer)
};
diff --git a/src/datavis3d/utils/abstractobjecthelper.cpp b/src/datavis3d/utils/abstractobjecthelper.cpp
new file mode 100644
index 00000000..d80e416b
--- /dev/null
+++ b/src/datavis3d/utils/abstractobjecthelper.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtDataVis3D module.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractobjecthelper_p.h"
+
+#include <QDebug>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+AbstractObjectHelper::AbstractObjectHelper()
+ : m_vertexbuffer(0),
+ m_normalbuffer(0),
+ m_uvbuffer(0),
+ m_elementbuffer(0),
+ m_indexCount(0),
+ m_meshDataLoaded(false)
+{
+ qDebug() << "AbstractObjectHelper::AbstractObjectHelper";
+}
+
+AbstractObjectHelper::~AbstractObjectHelper()
+{
+ qDebug() << "AbstractObjectHelper::~AbstractObjectHelper";
+ glDeleteBuffers(1, &m_vertexbuffer);
+ glDeleteBuffers(1, &m_uvbuffer);
+ glDeleteBuffers(1, &m_normalbuffer);
+ glDeleteBuffers(1, &m_elementbuffer);
+}
+
+GLuint AbstractObjectHelper::vertexBuf()
+{
+ if (!m_meshDataLoaded)
+ qFatal("No loaded object");
+ return m_vertexbuffer;
+}
+
+GLuint AbstractObjectHelper::normalBuf()
+{
+ if (!m_meshDataLoaded)
+ qFatal("No loaded object");
+ return m_normalbuffer;
+}
+
+GLuint AbstractObjectHelper::uvBuf()
+{
+ if (!m_meshDataLoaded)
+ qFatal("No loaded object");
+ return m_uvbuffer;
+}
+
+GLuint AbstractObjectHelper::elementBuf()
+{
+ if (!m_meshDataLoaded)
+ qFatal("No loaded object");
+ return m_elementbuffer;
+}
+
+GLuint AbstractObjectHelper::indexCount()
+{
+ return m_indexCount;
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/utils/abstractobjecthelper_p.h b/src/datavis3d/utils/abstractobjecthelper_p.h
new file mode 100644
index 00000000..4fa9d0ec
--- /dev/null
+++ b/src/datavis3d/utils/abstractobjecthelper_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtDataVis3D module.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef ABSTRACTOBJECTHELPER_H
+#define ABSTRACTOBJECTHELPER_H
+
+#include "datavis3dglobal_p.h"
+#include <QOpenGLFunctions>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class AbstractObjectHelper: protected QOpenGLFunctions
+{
+protected:
+ AbstractObjectHelper();
+public:
+ ~AbstractObjectHelper();
+
+ GLuint vertexBuf();
+ GLuint normalBuf();
+ GLuint uvBuf();
+ GLuint elementBuf();
+ GLuint indexCount();
+
+public:
+ GLuint m_vertexbuffer;
+ GLuint m_normalbuffer;
+ GLuint m_uvbuffer;
+ GLuint m_elementbuffer;
+
+ GLuint m_indexCount;
+ GLboolean m_meshDataLoaded;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // ABSTRACTOBJECTHELPER_H
diff --git a/src/datavis3d/utils/objecthelper.cpp b/src/datavis3d/utils/objecthelper.cpp
index b29ec8d6..df77d395 100644
--- a/src/datavis3d/utils/objecthelper.cpp
+++ b/src/datavis3d/utils/objecthelper.cpp
@@ -42,28 +42,20 @@
#include "meshloader_p.h"
#include "vertexindexer_p.h"
#include "objecthelper_p.h"
+#include "abstractobjecthelper_p.h"
#include <QDebug>
QT_DATAVIS3D_BEGIN_NAMESPACE
ObjectHelper::ObjectHelper(const QString &objectFile)
- : m_objectFile(objectFile),
- m_vertexbuffer(0),
- m_normalbuffer(0),
- m_uvbuffer(0),
- m_elementbuffer(0),
- m_indexCount(0),
- m_meshDataLoaded(false)
+ : m_objectFile(objectFile)
{
}
ObjectHelper::~ObjectHelper()
{
- glDeleteBuffers(1, &m_vertexbuffer);
- glDeleteBuffers(1, &m_uvbuffer);
- glDeleteBuffers(1, &m_normalbuffer);
- glDeleteBuffers(1, &m_elementbuffer);
+ qDebug() << "ObjectHelper::~ObjectHelper()";
}
void ObjectHelper::setObjectFile(const QString &objectFile)
@@ -129,37 +121,4 @@ void ObjectHelper::load()
m_meshDataLoaded = true;
}
-GLuint ObjectHelper::vertexBuf()
-{
- if (!m_meshDataLoaded)
- qFatal("No loaded object");
- return m_vertexbuffer;
-}
-
-GLuint ObjectHelper::normalBuf()
-{
- if (!m_meshDataLoaded)
- qFatal("No loaded object");
- return m_normalbuffer;
-}
-
-GLuint ObjectHelper::uvBuf()
-{
- if (!m_meshDataLoaded)
- qFatal("No loaded object");
- return m_uvbuffer;
-}
-
-GLuint ObjectHelper::elementBuf()
-{
- if (!m_meshDataLoaded)
- qFatal("No loaded object");
- return m_elementbuffer;
-}
-
-GLuint ObjectHelper::indexCount()
-{
- return m_indexCount;
-}
-
QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/utils/objecthelper_p.h b/src/datavis3d/utils/objecthelper_p.h
index bfe152bd..d52f5b90 100644
--- a/src/datavis3d/utils/objecthelper_p.h
+++ b/src/datavis3d/utils/objecthelper_p.h
@@ -53,13 +53,14 @@
#define OBJECTHELPER_P_H
#include "datavis3dglobal_p.h"
+#include "abstractobjecthelper_p.h"
#include <QOpenGLFunctions>
QT_DATAVIS3D_BEGIN_NAMESPACE
-class ObjectHelper: protected QOpenGLFunctions
+class ObjectHelper : public AbstractObjectHelper
{
- public:
+public:
ObjectHelper(const QString &objectFile = QString());
~ObjectHelper();
@@ -67,23 +68,8 @@ class ObjectHelper: protected QOpenGLFunctions
void load();
- GLuint vertexBuf();
- GLuint normalBuf();
- GLuint uvBuf();
- GLuint elementBuf();
- GLuint indexCount();
-
- private:
+private:
QString m_objectFile;
-
- GLuint m_vertexbuffer;
- GLuint m_normalbuffer;
- GLuint m_uvbuffer;
- GLuint m_elementbuffer;
-
- GLuint m_indexCount;
-
- GLboolean m_meshDataLoaded;
};
QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/utils/surfaceobject.cpp b/src/datavis3d/utils/surfaceobject.cpp
new file mode 100644
index 00000000..7a34349e
--- /dev/null
+++ b/src/datavis3d/utils/surfaceobject.cpp
@@ -0,0 +1,352 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtDataVis3D module.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "surfaceobject_p.h"
+#include "abstractobjecthelper_p.h"
+
+#include <QVector3D>
+#include <QVector2D>
+
+#include <QDebug>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+SurfaceObject::SurfaceObject()
+{
+}
+
+SurfaceObject::~SurfaceObject()
+{
+}
+
+void SurfaceObject::setUpSmoothData(QList<qreal> series, int columns, int rows, GLfloat yRange)
+{
+ GLfloat width = (GLfloat(columns) - 1.0f) / 2.0f;
+ GLfloat depth = (GLfloat(rows) - 1.0f) / -2.0f;
+ GLfloat height = yRange / 2.0f;
+
+ // Create vertice table
+ QVector<QVector3D> vertices;
+ QVector<QVector2D> uvs;
+ for (int i = 0, row = 0; i < rows; i++, row += columns) {
+ for (int j = 0; j < columns; j++) {
+ vertices.append(QVector3D(float(j) / width - 1.0f,
+ series.at(row + j) / height - 1.0f,
+ float(i) / depth + 1.0f));
+ uvs.append(QVector2D(1.0f / float(j), 1.0f / float(i)));
+ }
+ }
+
+ qDebug() << "vertices.count() = " << vertices.count();
+
+ // Create normals
+ QVector<QVector3D> normals;
+ for (int i = 0, row = 0; i < rows - 1; i++, row += columns) {
+ for (int j = 0; j < columns - 1; j++) {
+ normals.append(normal(vertices.at(row + j),
+ vertices.at(row + j + 1),
+ vertices.at(row + columns + j)));
+ }
+ int p = row + columns - 1;
+ normals.append(normal(vertices.at(p),
+ vertices.at(p + columns),
+ vertices.at(p - 1)));
+ }
+ for (int j = (rows - 1) * columns ; j < rows * columns - 1; j++) {
+ normals.append(normal(vertices.at(j),
+ vertices.at(j - columns),
+ vertices.at(j + 1)));
+ }
+ int p = rows * columns - 1;
+ normals.append(normal(vertices.at(p),
+ vertices.at(p - 1),
+ vertices.at(p - columns - 1)));
+
+ // Create indice table
+ m_indexCount = 6 * (columns - 1) * (rows - 1);
+ GLushort *indices = new GLushort[m_indexCount];
+ p = 0;
+ for (int i = 0, row = 0; i < rows - 1; i++, row += columns) {
+ for (int j = 0; j < columns - 1; j++) {
+ // Left triangle
+ indices[p++] = row + j + 1;
+ indices[p++] = row + columns + j;
+ indices[p++] = row + j;
+
+ // Right triangle
+ indices[p++] = row + columns + j + 1;
+ indices[p++] = row + columns + j;
+ indices[p++] = row + j + 1;
+ }
+ }
+
+ // Create line element indices
+ m_gridIndexCount = 2 * columns * (rows - 1) + 2 * rows * (columns - 1);
+ GLushort *gridIndices = new GLushort[m_gridIndexCount];
+ p = 0;
+ for (int i = 0, row = 0; i < rows; i++, row += columns) {
+ for (int j = 0; j < columns - 1; j++) {
+ gridIndices[p++] = row + j;
+ gridIndices[p++] = row + j + 1;
+ }
+ }
+ for (int i = 0, row = 0; i < rows - 1; i++, row += columns) {
+ for (int j = 0; j < columns; j++) {
+ gridIndices[p++] = row + j;
+ gridIndices[p++] = row + j + columns;
+ }
+ }
+// for (int i = columns - 1; i < (rows - 1) * columns; i += columns) {
+// gridIndices[p++] = i;
+// gridIndices[p++] = i + doubleColumns;
+// }
+
+ createBuffers(vertices, uvs, normals, indices, gridIndices);
+
+ delete indices;
+ delete gridIndices;
+}
+
+
+void SurfaceObject::setUpData(QList<qreal> series, int columns, int rows, GLfloat yRange)
+{
+ GLfloat width = (GLfloat(columns) - 1.0f) / 2.0f;
+ GLfloat depth = (GLfloat(rows) - 1.0f) / -2.0f;
+ GLfloat height = yRange / 2.0f;
+
+ // Create vertice table
+ QVector<QVector3D> vertices;
+ QVector<QVector2D> uvs;
+ for (int i = 0, row = 0; i < rows; i++, row += columns) {
+ for (int j = 0; j < columns; j++) {
+ vertices.append(QVector3D(float(j) / width - 1.0f,
+ series.at(row + j) / height - 1.0f,
+ float(i) / depth + 1.0f));
+ uvs.append(QVector2D(1.0f / float(j), 1.0f / float(i)));
+ if (j > 0 && j < columns - 1) {
+ vertices.append(vertices.last());
+ uvs.append(QVector2D(1.0f / float(j), 1.0f / float(i)));
+ }
+ }
+ }
+
+ // Create normals
+ QVector<QVector3D> normals;
+ int doubleColumns = columns * 2 - 2;
+ for (int i = 0, row = 0; i < rows - 1; i++, row += doubleColumns) {
+ for (int j = 0; j < columns * 2 - 2; j += 2) {
+ normals.append(normal(vertices.at(row + j),
+ vertices.at(row + j + 1),
+ vertices.at(row + doubleColumns + j)));
+ normals.append(normal(vertices.at(row + j + 1),
+ vertices.at(row + doubleColumns + j + 1),
+ vertices.at(row + doubleColumns + j)));
+ }
+ }
+ for (int j = (rows - 2) * doubleColumns ; j < (rows - 1) * doubleColumns; j++)
+ normals.append(normals.at(j));
+
+ // Create indice table
+ m_indexCount = 6 * (columns - 1) * (rows - 1);
+ GLushort *indices = new GLushort[6 * (columns - 1) * (rows - 1)];
+ int indWidth = columns - 1;
+ for (int i = 0, row = 0; i < rows - 1; i++, row += doubleColumns) {
+ for (int j = 0, jj = 0; j < columns - 1; j++, jj += 2) {
+ int p = (i * indWidth + j) * 2 * 3;
+ // Left triangle
+ indices[p + 0] = row + jj + 1;
+ indices[p + 1] = (i + 1) * doubleColumns + jj;
+ indices[p + 2] = row + jj;
+
+ // Right triangle
+ indices[p + 3] = (i + 1) * doubleColumns + (jj + 1);
+ indices[p + 4] = (i + 1) * doubleColumns + jj;
+ indices[p + 5] = row + jj + 1;
+ }
+ }
+
+ // Create line element indices
+ m_gridIndexCount = 2 * columns * (rows - 1) + 2 * rows * (columns - 1);
+ GLushort *gridIndices = new GLushort[m_gridIndexCount];
+ int p = 0;
+ for (int i = 0, row = 0; i < rows; i++, row += doubleColumns) {
+ for (int j = 0, jj = 0; j < columns - 1; j++, jj += 2) {
+ gridIndices[p++] = row + jj;
+ gridIndices[p++] = row + jj + 1;
+ }
+ }
+ for (int i = 0, row = 0; i < rows - 1; i++, row += doubleColumns) {
+ for (int j = 0, jj = 0; j < columns - 1; j++, jj += 2) {
+ gridIndices[p++] = row + jj;
+ gridIndices[p++] = row + jj + doubleColumns;
+ }
+ }
+ for (int i = doubleColumns - 1; i < (rows - 1) * doubleColumns; i += doubleColumns) {
+ gridIndices[p++] = i;
+ gridIndices[p++] = i + doubleColumns;
+ }
+
+ createBuffers(vertices, uvs, normals, indices, gridIndices);
+
+ delete indices;
+ delete gridIndices;
+}
+
+
+void SurfaceObject::createBuffers(const QVector<QVector3D> &vertices, const QVector<QVector2D> &uvs,
+ const QVector<QVector3D> &normals, const GLushort *indices,
+ const GLushort *gridIndices)
+{
+ initializeOpenGLFunctions();
+ if (m_meshDataLoaded) {
+ // Delete old data
+ glDeleteBuffers(1, &m_vertexbuffer);
+ glDeleteBuffers(1, &m_uvbuffer);
+ glDeleteBuffers(1, &m_normalbuffer);
+ glDeleteBuffers(1, &m_elementbuffer);
+ }
+
+ // Move to buffers
+ glGenBuffers(1, &m_vertexbuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer);
+ glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(QVector3D),
+ &vertices.at(0), GL_STATIC_DRAW);
+
+ glGenBuffers(1, &m_normalbuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, m_normalbuffer);
+ glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(QVector3D),
+ &normals.at(0), GL_STATIC_DRAW);
+
+ glGenBuffers(1, &m_uvbuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer);
+ glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(QVector2D),
+ &uvs.at(0), GL_STATIC_DRAW);
+
+ glGenBuffers(1, &m_elementbuffer);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbuffer);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indexCount * sizeof(GLushort),
+ indices, GL_STATIC_DRAW);
+
+ glGenBuffers(1, &m_gridElementbuffer);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_gridElementbuffer);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_gridIndexCount * sizeof(GLushort),
+ gridIndices, GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ // We're done. Set the flag ON
+ m_meshDataLoaded = true;
+}
+
+GLuint SurfaceObject::gridElementBuf()
+{
+ if (!m_meshDataLoaded)
+ qFatal("No loaded object");
+ return m_gridElementbuffer;
+}
+
+GLuint SurfaceObject::gridIndexCount()
+{
+ return m_gridIndexCount;
+}
+
+QVector3D SurfaceObject::normal(const QVector3D &a, const QVector3D &b, const QVector3D &c)
+{
+ QVector3D v1 = b - a;
+ QVector3D v2 = c - a;
+ return QVector3D::crossProduct(v1, v2);
+}
+
+QT_DATAVIS3D_END_NAMESPACE
+
+
+
+// For rainy days
+
+// QVector3D vertices[] = {
+// QVector3D(-0.5f, 0.0f, 0.1f),
+// QVector3D(0.5f, 0.0f, 0.1f),
+// QVector3D(0.0f, 1.0f, -0.5f)
+// };
+
+// QVector3D normals[] = {
+// QVector3D(0.5, 0.0, 1.0),
+// QVector3D(0.5, 0.0, 1.0),
+// QVector3D(0.5, 0.0, 1.0)
+// };
+
+// vertices.append(QVector3D(-1.0f, 0.0f, 0.1f));
+// vertices.append(QVector3D(0.0f, 0.0f, 0.1f));
+// vertices.append(QVector3D(0.0f, 0.5f, -0.5f));
+
+// normals.append(QVector3D(0.5, 0.0, 1.0));
+// normals.append(QVector3D(0.5, 0.0, 1.0));
+// normals.append(QVector3D(0.5, 0.0, 1.0));
+
+//GLushort indices[] = {0, 1, 2, 1, 3, 2};
+//GLushort indices[] = {1, 3, 2};
+
+//qDebug() << indices[p + 0] << ", " << indices[p + 1] << ", " << indices[p + 2];
+//qDebug() << indices[p + 3] << ", " << indices[p + 4] << ", " << indices[p + 5];
+
+//qDebug() << "(" << float(j) / width << ", 0.0, " << float(i) / depth * -1.0f << ")";
+
+//normals.append(QVector3D(1,0,0));
+//normals.append(QVector3D(0,1,0));
+//normals.append(QVector3D(0,0,1));
+//normals.append(QVector3D(1,0,1));
+
+//normals.append(QVector3D(1,0,0));
+//normals.append(QVector3D(0,1,0));
+//normals.append(QVector3D(0,0,1));
+//normals.append(QVector3D(1,0,1));
+
+//normals.append(QVector3D(1,0,0));
+//normals.append(QVector3D(0,1,0));
+//normals.append(QVector3D(0,0,1));
+//normals.append(QVector3D(1,0,1));
+
+
+//qDebug() << "Left normal from (" << row + j << ", " << row + j + 1 << ", " << row + doubleColumns + j << ")";
+
+//qDebug() << "right normal from (" << row + j +1 << ", " << row + doubleColumns + j + 1 << ", " << row + doubleColumns + j << ")";
+
diff --git a/src/datavis3d/utils/surfaceobject_p.h b/src/datavis3d/utils/surfaceobject_p.h
new file mode 100644
index 00000000..c5f32721
--- /dev/null
+++ b/src/datavis3d/utils/surfaceobject_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtDataVis3D module.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef SURFACEOBJECT_P_H
+#define SURFACEOBJECT_P_H
+
+#include "datavis3dglobal_p.h"
+#include "abstractobjecthelper_p.h"
+#include <QOpenGLFunctions>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class SurfaceObject : public AbstractObjectHelper
+{
+public:
+ SurfaceObject();
+ ~SurfaceObject();
+
+ void setUpData(QList<qreal> series, int columns, int rows, GLfloat yRange);
+ void setUpSmoothData(QList<qreal> series, int columns, int rows, GLfloat yRange);
+ GLuint gridElementBuf();
+ GLuint gridIndexCount();
+
+private:
+ QVector3D normal(const QVector3D &a, const QVector3D &b, const QVector3D &c);
+ void createBuffers(const QVector<QVector3D> &vertices, const QVector<QVector2D> &uvs,
+ const QVector<QVector3D> &normals, const GLushort *indices,
+ const GLushort *gridIndices);
+
+private:
+ QList<qreal> m_series;
+ int m_dataWidth;
+ int m_dataDepth;
+ GLfloat m_yRange;
+ GLuint m_gridElementbuffer;
+ GLuint m_gridIndexCount;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+#endif // SURFACEOBJECT_P_H
diff --git a/src/datavis3d/utils/utils.pri b/src/datavis3d/utils/utils.pri
index 566af55f..cef5ebf0 100644
--- a/src/datavis3d/utils/utils.pri
+++ b/src/datavis3d/utils/utils.pri
@@ -4,7 +4,9 @@ HEADERS += $$PWD/meshloader_p.h \
$$PWD/shaderhelper_p.h \
$$PWD/objecthelper_p.h \
$$PWD/texturehelper_p.h \
- $$PWD/utils_p.h
+ $$PWD/utils_p.h \
+ $$PWD/abstractobjecthelper_p.h \
+ $$PWD/surfaceobject_p.h
SOURCES += $$PWD/meshloader.cpp \
$$PWD/vertexindexer.cpp \
@@ -12,4 +14,6 @@ SOURCES += $$PWD/meshloader.cpp \
$$PWD/shaderhelper.cpp \
$$PWD/objecthelper.cpp \
$$PWD/texturehelper.cpp \
- $$PWD/utils.cpp
+ $$PWD/utils.cpp \
+ $$PWD/abstractobjecthelper.cpp \
+ $$PWD/surfaceobject.cpp