diff options
Diffstat (limited to 'src/Authoring/Qt3DStudio/Palettes/scenecamera/scenecameraglwidget.cpp')
-rw-r--r-- | src/Authoring/Qt3DStudio/Palettes/scenecamera/scenecameraglwidget.cpp | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/src/Authoring/Qt3DStudio/Palettes/scenecamera/scenecameraglwidget.cpp b/src/Authoring/Qt3DStudio/Palettes/scenecamera/scenecameraglwidget.cpp new file mode 100644 index 00000000..ce7d8e37 --- /dev/null +++ b/src/Authoring/Qt3DStudio/Palettes/scenecamera/scenecameraglwidget.cpp @@ -0,0 +1,208 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "Qt3DSCommonPrecompile.h" +#include "scenecameraglwidget.h" +#include "StudioApp.h" +#include "IStudioRenderer.h" +#include "WGLRenderContext.h" +#include "StudioPreferences.h" + +#include <QtGui/qopenglshaderprogram.h> +#include <QtGui/qopengltexture.h> +#include <QtGui/qopenglbuffer.h> +#include <QtGui/qopenglvertexarrayobject.h> + +const QVector4D defaultTextureOffset = QVector4D(0.0f, 0.0f, 1.0f, 1.0f); +const QVector2D defaultGeometryOffset = QVector2D(1.0f, 1.0f); + +SceneCameraGlWidget::SceneCameraGlWidget(QWidget *parent) + : QOpenGLWidget(parent) + , m_textureOffset(defaultTextureOffset) + , m_geometryOffset(defaultGeometryOffset) +{ + QSurfaceFormat format = CWGLRenderContext::selectSurfaceFormat(this); + format.setSamples(1); // We want pixel perfect view, not aliased one + setFormat(format); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); +} + +SceneCameraGlWidget::~SceneCameraGlWidget() +{ + cleanup(); +} + +void SceneCameraGlWidget::initializeGL() +{ + initializeOpenGLFunctions(); + QObject::connect(context(), &QOpenGLContext::aboutToBeDestroyed, + this, &SceneCameraGlWidget::cleanup); + + m_program = new QOpenGLShaderProgram(); + if (!m_program->addShaderFromSourceCode( + QOpenGLShader::Vertex, + "#version 330 core\n" + "in vec2 vertexPos;\n" + "in vec2 vertexTexCoord;\n" + "uniform vec4 uTexOffset;\n" + "uniform vec4 uGeomOffset;\n" + "out vec2 texCoord;\n" + "void main(void)\n" + "{\n" + " gl_Position = vec4(uGeomOffset.xy + vertexPos * uGeomOffset.zw, 0.0, 1.0);\n" + " texCoord = vec2(uTexOffset.z * vertexTexCoord.x + uTexOffset.x,\n" + " uTexOffset.w * vertexTexCoord.y + uTexOffset.y);\n" + "}")) { + qWarning() << __FUNCTION__ << "Failed to add vertex shader for scene camera preview"; + return; + } + if (!m_program->addShaderFromSourceCode( + QOpenGLShader::Fragment, + "#version 330 core\n" + "in vec2 texCoord;\n" + "uniform sampler2D uSampler;\n" + "out vec4 fragColor;\n" + "void main(void) {\n" + " vec4 oc = texture(uSampler, texCoord);\n" + " fragColor = vec4(oc);\n" + "}")) { + + qWarning() << __FUNCTION__ << "Failed to add fragment shader for scene camera preview"; + return; + } + if (!m_program->link()) { + qWarning() << __FUNCTION__ << "Failed to link program for scene camera preview"; + return; + } + if (!m_program->bind()) { + qWarning() << __FUNCTION__ << "Failed to bind program for scene camera preview"; + return; + } else { + GLint vertexAtt = GLint(m_program->attributeLocation("vertexPos")); + GLint uvAtt = GLint(m_program->attributeLocation("vertexTexCoord")); + m_uniformTextureOffset = GLint(m_program->uniformLocation("uTexOffset")); + m_uniformGeometryOffset = GLint(m_program->uniformLocation("uGeomOffset")); + m_program->setUniformValue("uSampler", 0); + + m_vao = new QOpenGLVertexArrayObject; + if (m_vao->create()) { + m_vao->bind(); + m_vertexBuffer = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + if (m_vertexBuffer->create() && m_vertexBuffer->bind()) { + GLfloat vertexBuffer[] = {-1.0f, 1.0f, + -1.0f, -1.0f, + 1.0f, 1.0f, + 1.0f, -1.0f}; + m_vertexBuffer->allocate(vertexBuffer, 8 * sizeof(GLfloat)); + glEnableVertexAttribArray(vertexAtt); + glVertexAttribPointer(vertexAtt, 2, GL_FLOAT, GL_FALSE, 0, (void *)0); + } else { + qWarning() << __FUNCTION__ + << "Failed to create/bind vertex buffer for scene camera preview"; + return; + } + m_uvBuffer = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + if (m_uvBuffer->create() && m_uvBuffer->bind()) { + GLfloat uvBuffer[] = {0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 1.0f, + 1.0f, 0.0f}; + m_uvBuffer->allocate(uvBuffer, 8 * sizeof(GLfloat)); + glEnableVertexAttribArray(uvAtt); + glVertexAttribPointer(uvAtt, 2, GL_FLOAT, GL_FALSE, 0, (void *)0); + } else { + qWarning() << __FUNCTION__ + << "Failed to create/bind UV buffer for scene camera preview"; + return; + } + + m_vao->release(); + } else { + qWarning() << __FUNCTION__ << "Failed to create/bind vertex array object"; + return; + } + } + + const QColor matteColor = CStudioPreferences::matteColor(); + glClearColor(matteColor.redF(), matteColor.greenF(), matteColor.blueF(), 1.0f); +} + +void SceneCameraGlWidget::paintGL() +{ + Q3DStudio::IStudioRenderer &renderer(g_StudioApp.getRenderer()); + if (renderer.IsInitialized()) { + m_vao->bind(); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_SCISSOR_TEST); + glDisable(GL_BLEND); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + QSize fboSize; + qt3ds::QT3DSU32 textureId; + renderer.getPreviewFbo(fboSize, textureId); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, GLuint(textureId)); + + m_program->setUniformValueArray(m_uniformTextureOffset, &m_textureOffset, 1); + m_program->setUniformValueArray(m_uniformGeometryOffset, &m_geometryOffset, 1); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + m_vao->release(); + } +} + +void SceneCameraGlWidget::resizeGL(int, int) +{ + // We need to update immediately to avoid flicker + update(); +} + +void SceneCameraGlWidget::cleanup() +{ + makeCurrent(); + + delete m_program; + delete m_vertexBuffer; + delete m_uvBuffer; + delete m_vao; + m_program = nullptr; + m_vertexBuffer = nullptr; + m_uvBuffer = nullptr; + m_vao = nullptr; + m_uniformTextureOffset = 0; + m_uniformGeometryOffset = 0; + m_textureOffset = defaultTextureOffset; + m_geometryOffset = defaultGeometryOffset; + + doneCurrent(); +} |