From 624666518e9e2d5628ab042f30e70ca747fb4da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomi=20Korpip=C3=A4=C3=A4?= Date: Fri, 12 Apr 2013 07:44:19 +0300 Subject: Implemented label printing using opengl (QPainter version ifdeffed, either one can be used) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Id7d6761b0ad447c7f4f18f0933d065f190ad82b6 Change-Id: Id7d6761b0ad447c7f4f18f0933d065f190ad82b6 Reviewed-by: Miikka Heikkinen Reviewed-by: Tomi Korpipää --- src/datavis3d/engine/engine.qrc | 2 + src/datavis3d/engine/meshes/plane.obj | 20 +-- src/datavis3d/engine/q3dbars.cpp | 184 ++++++++++++++++++--- src/datavis3d/engine/q3dbars_p.h | 6 + src/datavis3d/engine/q3dwindow.cpp | 12 +- src/datavis3d/engine/q3dwindow.h | 2 +- src/datavis3d/engine/shaders/fragmentShaderLabel | 6 + src/datavis3d/engine/shaders/fragmentShaderTexture | 40 +++-- src/datavis3d/engine/shaders/vertexShaderLabel | 8 + src/datavis3d/engine/shaders/vertexShaderTexture | 2 - src/datavis3d/utils/objecthelper.cpp | 50 +++--- src/datavis3d/utils/objecthelper_p.h | 6 +- src/datavis3d/utils/texturehelper.cpp | 70 ++++---- src/datavis3d/utils/texturehelper_p.h | 16 +- src/datavis3d/utils/utils.cpp | 48 ++++++ src/datavis3d/utils/utils_p.h | 3 + 16 files changed, 347 insertions(+), 128 deletions(-) create mode 100644 src/datavis3d/engine/shaders/fragmentShaderLabel create mode 100644 src/datavis3d/engine/shaders/vertexShaderLabel (limited to 'src/datavis3d') diff --git a/src/datavis3d/engine/engine.qrc b/src/datavis3d/engine/engine.qrc index 6803d1b7..62384afb 100644 --- a/src/datavis3d/engine/engine.qrc +++ b/src/datavis3d/engine/engine.qrc @@ -21,6 +21,8 @@ shaders/vertexShaderSelection shaders/fragmentShaderTexture shaders/vertexShaderTexture + shaders/fragmentShaderLabel + shaders/vertexShaderLabel textures/cube.png diff --git a/src/datavis3d/engine/meshes/plane.obj b/src/datavis3d/engine/meshes/plane.obj index a03e3532..0483285b 100644 --- a/src/datavis3d/engine/meshes/plane.obj +++ b/src/datavis3d/engine/meshes/plane.obj @@ -1,15 +1,15 @@ -# Blender v2.66 (sub 0) OBJ File: '' +# Blender v2.66 (sub 0) OBJ File: 'plane.blend' # www.blender.org o Plane -v 1.000000 0.000000 1.000000 -v -1.000000 0.000000 1.000000 -v 1.000000 0.000000 -1.000000 -v -1.000000 0.000000 -1.000000 +v -1.000000 1.000000 0.000000 +v -1.000000 -1.000000 0.000001 +v 1.000000 1.000000 -0.000001 +v 1.000000 -1.000000 0.000000 vt 0.003058 1.000000 -vt 0.000000 0.003058 -vt 0.996942 0.000000 vt 1.000000 0.996942 -vn 0.000000 1.000000 -0.000000 +vt 0.996942 0.000000 +vt 0.000000 0.003058 +vn 0.000001 0.000001 1.000000 s off -f 2/1/1 1/2/1 3/3/1 -f 4/4/1 2/1/1 3/3/1 +f 2/1/1 4/2/1 3/3/1 +f 1/4/1 2/1/1 3/3/1 diff --git a/src/datavis3d/engine/q3dbars.cpp b/src/datavis3d/engine/q3dbars.cpp index 9a72bd1a..e8372bd2 100644 --- a/src/datavis3d/engine/q3dbars.cpp +++ b/src/datavis3d/engine/q3dbars.cpp @@ -63,6 +63,7 @@ QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE #define USE_HAX0R_SELECTION // keep this defined until the "real" method works +//#define USE_PAINTER_TEXT // Use QPainter labels or opengl labels const float zComp = 10.0f; // Compensation for z position; move all objects to positive z, as shader can't handle negative values correctly const QVector3D defaultLightPos = QVector3D(0.0f, 3.0f, zComp); @@ -86,11 +87,14 @@ void Q3DBars::initialize() d_ptr->initShaders(QStringLiteral(":/shaders/vertex") , QStringLiteral(":/shaders/fragment")); } - // TODO: Texture test - d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertexTexture") - , QStringLiteral(":/shaders/fragmentTexture")); // d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertexTexture") // , QStringLiteral(":/shaders/fragmentTexture")); + d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertex") + , QStringLiteral(":/shaders/fragment")); +#ifndef USE_PAINTER_TEXT + d_ptr->initLabelShaders(QStringLiteral(":/shaders/vertexLabel") + , QStringLiteral(":/shaders/fragmentLabel")); +#endif d_ptr->initSelectionShader(); #ifndef USE_HAX0R_SELECTION @@ -104,6 +108,11 @@ void Q3DBars::initialize() // Load background mesh d_ptr->loadBackgroundMesh(); +#ifndef USE_PAINTER_TEXT + // Load label mesh + d_ptr->loadLabelMesh(); +#endif + // Set OpenGL features glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); @@ -131,6 +140,7 @@ void Q3DBars::render() if (!d_ptr->m_isInitialized) return; +#ifdef USE_PAINTER_TEXT if (d_ptr->m_paintDevice) { QPainter painter(d_ptr->m_paintDevice); painter.setRenderHint(QPainter::HighQualityAntialiasing, true); @@ -140,6 +150,17 @@ void Q3DBars::render() } else { d_ptr->m_paintDevice = getDevice(); } +#else + // Set OpenGL features + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + // If zoom selection is on, draw zoom scene + drawZoomScene(); + // Draw bars scene + drawScene(); +#endif } void Q3DBars::render(QPainter *painter) @@ -422,6 +443,99 @@ void Q3DBars::drawZoomScene() #endif // Release bar shader d_ptr->m_barShader->release(); + +#ifndef USE_PAINTER_TEXT + // Draw labels (or values of bars) + const bool transparentLabel = false; + d_ptr->m_labelShader->bind(); + glDisable(GL_DEPTH_TEST); + glEnable(GL_TEXTURE_2D); + if (transparentLabel) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + for (int col = 0; col < d_ptr->m_zoomSelection->d_ptr->row().size(); col++) { + // TODO: Optimize! Create textures only when zoomselection changes! Store the texture id's into zoomselection + QDataItem *item = d_ptr->m_zoomSelection->d_ptr->getItem(col); + // Create labels + // Print label into a QImage using QPainter + QImage label = Utils::printTextToImage(item->d_ptr->valueStr(), d_ptr->m_backgroundColor + , d_ptr->m_textColor, transparentLabel); + + // Insert text texture into label + GLuint labelTexture = d_ptr->m_textureHelper->create2DTexture(label, false, false); + + // Draw label + QMatrix4x4 modelMatrix; + QMatrix4x4 MVPMatrix; + if (ZoomColumn == d_ptr->m_selectionMode) { + modelMatrix.translate(-(item->d_ptr->translation().z()) - zComp + , -1.5f//item->d_ptr->translation().y() + , zComp); + } else { + modelMatrix.translate(item->d_ptr->translation().x() + , -1.5f//item->d_ptr->translation().y() + , zComp); + } + + // Rotate + modelMatrix.rotate(-45.0f, 0.0f, 0.0f, 1.0f); + + // TODO: Calculate uniform scaling from font height + // Scale label based on text size + modelMatrix.scale(QVector3D((float)label.width() / 450.0f + , (float)label.height() / 450.0f + , 0.0f)); + + MVPMatrix = projectionMatrix * viewMatrix * modelMatrix; + + d_ptr->m_labelShader->setUniformValue(d_ptr->m_labelShader->MVP() + , MVPMatrix); + + // Activate texture + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, labelTexture); + d_ptr->m_labelShader->setUniformValue(d_ptr->m_labelShader->texture() + , 0); + + // 1st attribute buffer : vertices + glEnableVertexAttribArray(d_ptr->m_labelShader->posAtt()); + glBindBuffer(GL_ARRAY_BUFFER, d_ptr->m_labelObj->vertexBuf()); + glVertexAttribPointer(d_ptr->m_labelShader->posAtt() + , 3, GL_FLOAT, GL_FALSE, 0, (void*)0); + + // 2nd attribute buffer : UVs + glEnableVertexAttribArray(d_ptr->m_labelShader->uvAtt()); + glBindBuffer(GL_ARRAY_BUFFER, d_ptr->m_labelObj->uvBuf()); + glVertexAttribPointer(d_ptr->m_labelShader->uvAtt() + , 2, GL_FLOAT, GL_FALSE, 0, (void*)0); + + // Index buffer + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, d_ptr->m_labelObj->elementBuf()); + + // Draw the triangles + glDrawElements(GL_TRIANGLES, d_ptr->m_labelObj->indexCount() + , GL_UNSIGNED_SHORT, (void*)0); + + // Free buffers + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glDisableVertexAttribArray(d_ptr->m_labelShader->uvAtt()); + glDisableVertexAttribArray(d_ptr->m_labelShader->posAtt()); + + glBindTexture(GL_TEXTURE_2D, 0); + glDeleteTextures(1, &labelTexture); + } + + glDisable(GL_TEXTURE_2D); + if (transparentLabel) + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + + // Release label shader + d_ptr->m_labelShader->release(); +#endif } void Q3DBars::drawScene() @@ -627,9 +741,11 @@ void Q3DBars::drawScene() // Bind background shader d_ptr->m_backgroundShader->bind(); - // TODO: Texture test - glEnable(GL_TEXTURE_2D); - GLuint bgrTexture = TextureHelper::create2DTexture(QImage(QStringLiteral(":/textures/cubetex"))); + // TODO: If we want to use background texture, we should create it in initBackground instead of here and keep the texture id in d_ptr + // Create texture + //glEnable(GL_TEXTURE_2D); + //GLuint bgrTexture = d_ptr->m_textureHelper->create2DTexture( + // QImage(QStringLiteral(":/textures/cubetex")), true); // Draw background if (d_ptr->m_backgroundObj) { @@ -662,11 +778,11 @@ void Q3DBars::drawScene() , d_ptr->m_lightStrength); d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->ambientS() , d_ptr->m_ambientStrength); - // TODO: Texture test - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, bgrTexture); - d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->texture() - , 0); + // Activate texture + //glActiveTexture(GL_TEXTURE0); + //glBindTexture(GL_TEXTURE_2D, bgrTexture); + //d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->texture() + // , 0); // 1st attribute buffer : vertices glEnableVertexAttribArray(d_ptr->m_backgroundShader->posAtt()); @@ -680,12 +796,11 @@ void Q3DBars::drawScene() glVertexAttribPointer(d_ptr->m_backgroundShader->normalAtt() , 3, GL_FLOAT, GL_FALSE, 0, (void*)0); - // TODO: Texture test // 3rd attribute buffer : UVs - glEnableVertexAttribArray(d_ptr->m_backgroundShader->uvAtt()); - glBindBuffer(GL_ARRAY_BUFFER, d_ptr->m_backgroundObj->uvBuf()); - glVertexAttribPointer(d_ptr->m_backgroundShader->uvAtt() - , 2, GL_FLOAT, GL_FALSE, 0, (void*)0); + //glEnableVertexAttribArray(d_ptr->m_backgroundShader->uvAtt()); + //glBindBuffer(GL_ARRAY_BUFFER, d_ptr->m_backgroundObj->uvBuf()); + //glVertexAttribPointer(d_ptr->m_backgroundShader->uvAtt() + // , 2, GL_FLOAT, GL_FALSE, 0, (void*)0); // Index buffer glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, d_ptr->m_backgroundObj->elementBuf()); @@ -698,17 +813,15 @@ void Q3DBars::drawScene() glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - // TODO: Texture test - glDisableVertexAttribArray(d_ptr->m_backgroundShader->uvAtt()); - + //glDisableVertexAttribArray(d_ptr->m_backgroundShader->uvAtt()); glDisableVertexAttribArray(d_ptr->m_backgroundShader->normalAtt()); glDisableVertexAttribArray(d_ptr->m_backgroundShader->posAtt()); } - // TODO: Texture test - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &bgrTexture); - glDisable(GL_TEXTURE_2D); + // Disable textures + //glBindTexture(GL_TEXTURE_2D, 0); + //glDeleteTextures(1, &bgrTexture); // TODO: If we want to use background texture, we should create it in initBackground and delete on exit + //glDisable(GL_TEXTURE_2D); // Release background shader d_ptr->m_backgroundShader->release(); @@ -1456,8 +1569,10 @@ Q3DBarsPrivate::Q3DBarsPrivate(Q3DBars *q) , m_barShader(0) , m_selectionShader(0) , m_backgroundShader(0) + , m_labelShader(0) , m_barObj(0) , m_backgroundObj(0) + , m_labelObj(0) , m_sampleCount(QPoint(0, 0)) , m_objFile(QStringLiteral(":/defaultMeshes/bar")) , m_mousePressed(MouseNone) @@ -1502,6 +1617,7 @@ Q3DBarsPrivate::Q3DBarsPrivate(Q3DBars *q) , m_sceneViewPort(0, 0, q->width(), q->height()) , m_zoomViewPort(0, 0, q->width(), q->height()) , m_zoomActivated(false) + , m_textureHelper(new TextureHelper()) { } @@ -1518,6 +1634,7 @@ Q3DBarsPrivate::~Q3DBarsPrivate() delete m_backgroundShader; delete m_barObj; delete m_backgroundObj; + delete m_textureHelper; #ifndef USE_HAX0R_SELECTION q_ptr->glDeleteFramebuffers(1, &m_framebufferSelection); @@ -1530,7 +1647,7 @@ void Q3DBarsPrivate::loadBarMesh() { if (m_barObj) delete m_barObj; - m_barObj = new ObjectHelper(q_ptr, m_objFile); + m_barObj = new ObjectHelper(m_objFile); m_barObj->load(); } @@ -1538,10 +1655,18 @@ void Q3DBarsPrivate::loadBackgroundMesh() { if (m_backgroundObj) delete m_backgroundObj; - m_backgroundObj = new ObjectHelper(q_ptr, QStringLiteral(":/defaultMeshes/background")); + m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/background")); m_backgroundObj->load(); } +void Q3DBarsPrivate::loadLabelMesh() +{ + if (m_labelObj) + delete m_labelObj; + m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/label")); + m_labelObj->load(); +} + void Q3DBarsPrivate::initShaders(const QString &vertexShader, const QString &fragmentShader) { if (m_barShader) @@ -1605,6 +1730,15 @@ void Q3DBarsPrivate::initBackgroundShaders(const QString &vertexShader m_backgroundShader->initialize(); } +void Q3DBarsPrivate::initLabelShaders(const QString &vertexShader + , const QString &fragmentShader) +{ + if (m_labelShader) + delete m_labelShader; + m_labelShader = new ShaderHelper(q_ptr, vertexShader, fragmentShader); + m_labelShader->initialize(); +} + void Q3DBarsPrivate::calculateSceneScalingFactors() { // Calculate scene scaling and translation factors diff --git a/src/datavis3d/engine/q3dbars_p.h b/src/datavis3d/engine/q3dbars_p.h index 4c0af822..1e26b092 100644 --- a/src/datavis3d/engine/q3dbars_p.h +++ b/src/datavis3d/engine/q3dbars_p.h @@ -57,6 +57,7 @@ class QDataRow; class QDataSet; class ShaderHelper; class ObjectHelper; +class TextureHelper; class Q3DBarsPrivate { @@ -82,9 +83,11 @@ public: void loadBarMesh(); void loadBackgroundMesh(); + void loadLabelMesh(); void initShaders(const QString &vertexShader, const QString &fragmentShader); void initSelectionShader(); void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader); + void initLabelShaders(const QString &vertexShader, const QString &fragmentShader); void initSelectionBuffer(); void calculateSceneScalingFactors(); SelectionType isSelected(int row, int bar, const QVector3D &selection); @@ -97,8 +100,10 @@ public: ShaderHelper *m_barShader; ShaderHelper *m_selectionShader; ShaderHelper *m_backgroundShader; + ShaderHelper *m_labelShader; ObjectHelper *m_barObj; ObjectHelper *m_backgroundObj; + ObjectHelper *m_labelObj; QPoint m_sampleCount; QString m_objFile; MousePressType m_mousePressed; @@ -146,6 +151,7 @@ public: QRect m_sceneViewPort; QRect m_zoomViewPort; bool m_zoomActivated; + TextureHelper *m_textureHelper; }; diff --git a/src/datavis3d/engine/q3dwindow.cpp b/src/datavis3d/engine/q3dwindow.cpp index 54300793..86278a61 100644 --- a/src/datavis3d/engine/q3dwindow.cpp +++ b/src/datavis3d/engine/q3dwindow.cpp @@ -124,13 +124,13 @@ void Q3DWindow::exposeEvent(QExposeEvent *event) renderNow(); } -void Q3DWindow::resizeEvent(QResizeEvent *event) -{ - Q_UNUSED(event); +//void Q3DWindow::resizeEvent(QResizeEvent *event) +//{ +// Q_UNUSED(event); - if (isExposed()) - renderNow(); -} +// if (isExposed()) +// renderLater(); +//} void Q3DWindow::renderNow() { diff --git a/src/datavis3d/engine/q3dwindow.h b/src/datavis3d/engine/q3dwindow.h index 3bea4dd7..975ae253 100644 --- a/src/datavis3d/engine/q3dwindow.h +++ b/src/datavis3d/engine/q3dwindow.h @@ -76,7 +76,7 @@ protected: bool event(QEvent *event); void exposeEvent(QExposeEvent *event); - void resizeEvent(QResizeEvent *event); +// void resizeEvent(QResizeEvent *event); private: QOpenGLPaintDevice *getDevice(); diff --git a/src/datavis3d/engine/shaders/fragmentShaderLabel b/src/datavis3d/engine/shaders/fragmentShaderLabel new file mode 100644 index 00000000..ed3f91b1 --- /dev/null +++ b/src/datavis3d/engine/shaders/fragmentShaderLabel @@ -0,0 +1,6 @@ +varying highp vec2 UV; +uniform sampler2D textureSampler; +void main() { + gl_FragColor = texture2D(textureSampler, UV); +} + diff --git a/src/datavis3d/engine/shaders/fragmentShaderTexture b/src/datavis3d/engine/shaders/fragmentShaderTexture index 9f2692f2..95c4f1a1 100644 --- a/src/datavis3d/engine/shaders/fragmentShaderTexture +++ b/src/datavis3d/engine/shaders/fragmentShaderTexture @@ -1,5 +1,4 @@ varying highp vec2 UV; -varying highp vec2 coords_mdl; varying highp vec3 position_wrld; varying highp vec3 normal_cmr; varying highp vec3 eyeDirection_cmr; @@ -10,25 +9,24 @@ uniform highp float lightStrength; uniform highp float ambientStrength; uniform sampler2D textureSampler; void main() { - //highp vec3 materialDiffuseColor = texture2D(textureSampler, UV).rgb; - //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 = dot(n, l); - //if (cosTheta < 0.0) { cosTheta = 0.0; } - //if (cosTheta > 1.0) { cosTheta = 1.0; } - //highp vec3 E = normalize(eyeDirection_cmr); - //highp vec3 R = reflect(-l, n); - //highp float cosAlpha = dot(E, R); - //if (cosAlpha < 0.0) { cosAlpha = 0.0; } - //if (cosAlpha > 1.0) { cosAlpha = 1.0; } - //gl_FragColor.rgb = //color_mdl + color_mdl * vec3(cosTheta * cosTheta) / (distance * distance) + vec3(cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / (distance * distance); - // materialAmbientColor + - // materialDiffuseColor * lightStrength * (cosTheta * cosTheta) / distance + - // materialSpecularColor * lightStrength * (cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / distance;//(distance * distance); - //gl_FragColor.a = 1.0; - gl_FragColor = texture2D(textureSampler, UV); + highp vec3 materialDiffuseColor = texture2D(textureSampler, UV).rgb; + 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 = dot(n, l); + if (cosTheta < 0.0) { cosTheta = 0.0; } + if (cosTheta > 1.0) { cosTheta = 1.0; } + highp vec3 E = normalize(eyeDirection_cmr); + highp vec3 R = reflect(-l, n); + highp float cosAlpha = dot(E, R); + if (cosAlpha < 0.0) { cosAlpha = 0.0; } + if (cosAlpha > 1.0) { cosAlpha = 1.0; } + gl_FragColor.rgb = //color_mdl + color_mdl * vec3(cosTheta * cosTheta) / (distance * distance) + vec3(cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / (distance * distance); + materialAmbientColor + + materialDiffuseColor * lightStrength * (cosTheta * cosTheta) / distance + + materialSpecularColor * lightStrength * (cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / distance;//(distance * distance); + gl_FragColor.a = 1.0; } diff --git a/src/datavis3d/engine/shaders/vertexShaderLabel b/src/datavis3d/engine/shaders/vertexShaderLabel new file mode 100644 index 00000000..5959b47b --- /dev/null +++ b/src/datavis3d/engine/shaders/vertexShaderLabel @@ -0,0 +1,8 @@ +attribute highp vec3 vertexPosition_mdl; +attribute highp vec2 vertexUV; +uniform highp mat4 MVP; +varying highp vec2 UV; +void main() { + gl_Position = MVP * vec4(vertexPosition_mdl, 1.0); + UV = vertexUV; +} diff --git a/src/datavis3d/engine/shaders/vertexShaderTexture b/src/datavis3d/engine/shaders/vertexShaderTexture index 19f9d617..fb23b252 100644 --- a/src/datavis3d/engine/shaders/vertexShaderTexture +++ b/src/datavis3d/engine/shaders/vertexShaderTexture @@ -11,10 +11,8 @@ 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; diff --git a/src/datavis3d/utils/objecthelper.cpp b/src/datavis3d/utils/objecthelper.cpp index b6193bfe..7e418a4f 100644 --- a/src/datavis3d/utils/objecthelper.cpp +++ b/src/datavis3d/utils/objecthelper.cpp @@ -47,9 +47,8 @@ QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE -ObjectHelper::ObjectHelper(QOpenGLFunctions *parent, const QString &objectFile) - : m_caller(parent) - , m_objectFile(objectFile) +ObjectHelper::ObjectHelper(const QString &objectFile) + : m_objectFile(objectFile) , m_vertexbuffer(0) , m_normalbuffer(0) , m_uvbuffer(0) @@ -57,14 +56,15 @@ ObjectHelper::ObjectHelper(QOpenGLFunctions *parent, const QString &objectFile) , m_indexCount(0) , m_meshDataLoaded(false) { + initializeOpenGLFunctions(); } ObjectHelper::~ObjectHelper() { - m_caller->glDeleteBuffers(1, &m_vertexbuffer); - m_caller->glDeleteBuffers(1, &m_uvbuffer); - m_caller->glDeleteBuffers(1, &m_normalbuffer); - m_caller->glDeleteBuffers(1, &m_elementbuffer); + glDeleteBuffers(1, &m_vertexbuffer); + glDeleteBuffers(1, &m_uvbuffer); + glDeleteBuffers(1, &m_normalbuffer); + glDeleteBuffers(1, &m_elementbuffer); } void ObjectHelper::setObjectFile(const QString &objectFile) @@ -76,10 +76,10 @@ void ObjectHelper::load() { if (m_meshDataLoaded) { // Delete old data - m_caller->glDeleteBuffers(1, &m_vertexbuffer); - m_caller->glDeleteBuffers(1, &m_uvbuffer); - m_caller->glDeleteBuffers(1, &m_normalbuffer); - m_caller->glDeleteBuffers(1, &m_elementbuffer); + glDeleteBuffers(1, &m_vertexbuffer); + glDeleteBuffers(1, &m_uvbuffer); + glDeleteBuffers(1, &m_normalbuffer); + glDeleteBuffers(1, &m_elementbuffer); } QVector vertices; QVector uvs; @@ -101,30 +101,30 @@ void ObjectHelper::load() m_indexCount = indices.size(); //qDebug() << "index count" << m_indexCount; - m_caller->glGenBuffers(1, &m_vertexbuffer); - m_caller->glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer); - m_caller->glBufferData(GL_ARRAY_BUFFER, indexed_vertices.size() * sizeof(QVector3D) + glGenBuffers(1, &m_vertexbuffer); + glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer); + glBufferData(GL_ARRAY_BUFFER, indexed_vertices.size() * sizeof(QVector3D) , &indexed_vertices.at(0) , GL_STATIC_DRAW); - m_caller->glGenBuffers(1, &m_normalbuffer); - m_caller->glBindBuffer(GL_ARRAY_BUFFER, m_normalbuffer); - m_caller->glBufferData(GL_ARRAY_BUFFER, indexed_normals.size() * sizeof(QVector3D) + glGenBuffers(1, &m_normalbuffer); + glBindBuffer(GL_ARRAY_BUFFER, m_normalbuffer); + glBufferData(GL_ARRAY_BUFFER, indexed_normals.size() * sizeof(QVector3D) , &indexed_normals.at(0) , GL_STATIC_DRAW); - m_caller->glGenBuffers(1, &m_uvbuffer); - m_caller->glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer); - m_caller->glBufferData(GL_ARRAY_BUFFER, indexed_uvs.size() * sizeof(QVector2D) + glGenBuffers(1, &m_uvbuffer); + glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer); + glBufferData(GL_ARRAY_BUFFER, indexed_uvs.size() * sizeof(QVector2D) , &indexed_uvs.at(0), GL_STATIC_DRAW); - m_caller->glGenBuffers(1, &m_elementbuffer); - m_caller->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbuffer); - m_caller->glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned short) + glGenBuffers(1, &m_elementbuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned short) , &indices.at(0), GL_STATIC_DRAW); - m_caller->glBindBuffer(GL_ARRAY_BUFFER, 0); - m_caller->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); m_meshDataLoaded = true; } diff --git a/src/datavis3d/utils/objecthelper_p.h b/src/datavis3d/utils/objecthelper_p.h index 17f2d294..73523fbf 100644 --- a/src/datavis3d/utils/objecthelper_p.h +++ b/src/datavis3d/utils/objecthelper_p.h @@ -47,10 +47,10 @@ QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE -class ObjectHelper +class ObjectHelper: protected QOpenGLFunctions { public: - ObjectHelper(QOpenGLFunctions *parent, const QString &objectFile = QString()); + ObjectHelper(const QString &objectFile = QString()); ~ObjectHelper(); void setObjectFile(const QString &objectFile); @@ -64,8 +64,6 @@ class ObjectHelper GLuint indexCount(); private: - QOpenGLFunctions *m_caller; - QString m_objectFile; GLuint m_vertexbuffer; diff --git a/src/datavis3d/utils/texturehelper.cpp b/src/datavis3d/utils/texturehelper.cpp index 395ed1f3..f6308ea6 100644 --- a/src/datavis3d/utils/texturehelper.cpp +++ b/src/datavis3d/utils/texturehelper.cpp @@ -47,18 +47,32 @@ QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE -GLuint TextureHelper::create2DTexture(const QImage &image, bool useTrilinearFiltering) +TextureHelper::TextureHelper() +{ + initializeOpenGLFunctions(); +} + +TextureHelper::~TextureHelper() +{ +} + +GLuint TextureHelper::create2DTexture(const QImage &image, bool useTrilinearFiltering, bool convert) { GLuint textureId; glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_2D, textureId); - QImage glTexture = TextureHelper::convertToGLFormat(image); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glTexture.width(), glTexture.height() - , 0, GL_RGBA, GL_UNSIGNED_BYTE, glTexture.bits()); + if (convert) { + QImage glTexture = convertToGLFormat(image); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glTexture.width(), glTexture.height() + , 0, GL_RGBA, GL_UNSIGNED_BYTE, glTexture.bits()); + } else { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height() + , 0, GL_RGBA, GL_UNSIGNED_BYTE, image.bits()); + } if (useTrilinearFiltering) { -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); -// glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glGenerateMipmap(GL_TEXTURE_2D); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -71,19 +85,19 @@ GLuint TextureHelper::createCubeMapTexture(const QImage &image, bool useTrilinea { GLuint textureId; glGenTextures(1, &textureId); -// glBindTexture(GL_TEXTURE_CUBE_MAP, textureId); -// QImage glTexture = convertToGLFormat(image); -// glTexImage2D(GL_TEXTURE_CUBE_MAP, 0, GL_RGB, glTexture.width(), glTexture.height() -// , 0, GL_RGB, GL_UNSIGNED_BYTE, glTexture.bits()); -// if (useTrilinearFiltering) { -// glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -// glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); -// glGenerateMipmap(GL_TEXTURE_CUBE_MAP); -// } else { -// glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); -// glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -// } -// glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_CUBE_MAP, textureId); + QImage glTexture = convertToGLFormat(image); + glTexImage2D(GL_TEXTURE_CUBE_MAP, 0, GL_RGB, glTexture.width(), glTexture.height() + , 0, GL_RGB, GL_UNSIGNED_BYTE, glTexture.bits()); + if (useTrilinearFiltering) { + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glGenerateMipmap(GL_TEXTURE_CUBE_MAP); + } else { + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + glBindTexture(GL_TEXTURE_2D, 0); return textureId; } @@ -141,9 +155,9 @@ void TextureHelper::convertToGLFormatHelper(QImage &dstImage, const QImage &srcI const uint *end = p + width; while (p < end) { *q = ((*p << 24) & 0xff000000) - | ((*p >> 24) & 0x000000ff) - | ((*p << 8) & 0x00ff0000) - | ((*p >> 8) & 0x0000ff00); + | ((*p >> 24) & 0x000000ff) + | ((*p << 8) & 0x00ff0000) + | ((*p >> 8) & 0x0000ff00); p++; q++; } @@ -188,9 +202,9 @@ QRgb TextureHelper::qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture if (texture_format == GL_BGRA) { if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { return ((src_pixel << 24) & 0xff000000) - | ((src_pixel >> 24) & 0x000000ff) - | ((src_pixel << 8) & 0x00ff0000) - | ((src_pixel >> 8) & 0x0000ff00); + | ((src_pixel >> 24) & 0x000000ff) + | ((src_pixel << 8) & 0x00ff0000) + | ((src_pixel >> 8) & 0x0000ff00); } else { return src_pixel; } @@ -199,8 +213,8 @@ QRgb TextureHelper::qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture return (src_pixel << 8) | ((src_pixel >> 24) & 0xff); } else { return ((src_pixel << 16) & 0xff0000) - | ((src_pixel >> 16) & 0xff) - | (src_pixel & 0xff00ff00); + | ((src_pixel >> 16) & 0xff) + | (src_pixel & 0xff00ff00); } } } diff --git a/src/datavis3d/utils/texturehelper_p.h b/src/datavis3d/utils/texturehelper_p.h index ac86bccf..35d651b7 100644 --- a/src/datavis3d/utils/texturehelper_p.h +++ b/src/datavis3d/utils/texturehelper_p.h @@ -48,17 +48,21 @@ QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE -class TextureHelper +class TextureHelper: protected QOpenGLFunctions { public: + TextureHelper(); + ~TextureHelper(); + // Ownership of created texture is transferred to caller - static GLuint create2DTexture(const QImage &image, bool useTrilinearFiltering = false); - static GLuint createCubeMapTexture(const QImage &image, bool useTrilinearFiltering = false); + GLuint create2DTexture(const QImage &image, bool useTrilinearFiltering = false + , bool convert = true); + GLuint createCubeMapTexture(const QImage &image, bool useTrilinearFiltering = false); private: - static QImage convertToGLFormat(const QImage &srcImage); - static void convertToGLFormatHelper(QImage &dstImage, const QImage &srcImage, GLenum texture_format); - static QRgb qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture_format); + QImage convertToGLFormat(const QImage &srcImage); + void convertToGLFormatHelper(QImage &dstImage, const QImage &srcImage, GLenum texture_format); + QRgb qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture_format); }; QTCOMMERCIALDATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/utils/utils.cpp b/src/datavis3d/utils/utils.cpp index 74e7cca7..f7138602 100644 --- a/src/datavis3d/utils/utils.cpp +++ b/src/datavis3d/utils/utils.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -140,4 +141,51 @@ void Utils::printText(QPainter *painter, const QString &text, const QPoint &posi painter->restore(); } +QImage Utils::printTextToImage(const QString &text, const QColor &bgrColor, const QColor &txtColor + , bool noBackground) +{ + // Calculate text dimensions + QFont valueFont = QFont(QStringLiteral("Arial"), 11); + valueFont.setBold(true); + QFontMetrics valueFM(valueFont); + int valueStrWidth = valueFM.width(text); + int valueStrHeight = valueFM.height(); + QSize labelSize; + if (noBackground) + labelSize = QSize(valueStrWidth, valueStrHeight); + else + labelSize = QSize(valueStrWidth + 10, valueStrHeight + 10); + + // Create image + QImage image = QImage(labelSize, QImage::Format_ARGB32); + + // Init painter + QPainter painter(&image); + // Paint text + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setCompositionMode(QPainter::CompositionMode_Source); + if (noBackground) { + painter.setBackgroundMode(Qt::OpaqueMode); + painter.setBackground(Qt::transparent); + painter.setBrush(Qt::transparent); + painter.setFont(valueFont); + painter.setPen(txtColor); + painter.drawText(0, 0 + , valueStrWidth, valueStrHeight + , Qt::AlignCenter | Qt::AlignVCenter + , text); + } else { + painter.setBrush(QBrush(bgrColor)); + painter.setPen(bgrColor); + painter.drawRect(0, 0, labelSize.width(), labelSize.height()); + painter.setFont(valueFont); + painter.setPen(txtColor); + painter.drawText(5, 5 + , valueStrWidth, valueStrHeight + , Qt::AlignCenter | Qt::AlignVCenter + , text); + } + return image; +} + QTCOMMERCIALDATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/utils/utils_p.h b/src/datavis3d/utils/utils_p.h index 9752066e..028cd716 100644 --- a/src/datavis3d/utils/utils_p.h +++ b/src/datavis3d/utils/utils_p.h @@ -49,6 +49,7 @@ class QColor; class QPainter; class QString; class QPoint; +class QImage; QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE @@ -58,6 +59,8 @@ public: static QVector3D vectorFromColor(const QColor &color); static void printText(QPainter *painter, const QString &text, const QPoint &position , bool absoluteCoords = true, qreal rotation = 0, qreal scale = 1.0f); + static QImage printTextToImage(const QString &text, const QColor &bgrColor + , const QColor &txtColor, bool noBackground = false); }; QTCOMMERCIALDATAVIS3D_END_NAMESPACE -- cgit v1.2.3