#include "..\Header\OglViewerWidget.h" #include #include #include OglViewerWidget::OglViewerWidget(QWidget *parent) : QOpenGLWidget(parent), geometries(0), texture(0) { setFocus(); } OglViewerWidget::~OglViewerWidget() { // Make sure the context is current when deleting the texture // and the buffers. makeCurrent(); delete texture; delete geometries; doneCurrent(); } void OglViewerWidget::mousePressEvent(QMouseEvent *e) { // Save mouse press position m_mouse.position = QVector2D(e->localPos()); // Which button has been pressed? if (e->button() == Qt::LeftButton) m_mouse.left = true; else if (e->button() == Qt::RightButton) m_mouse.right = true; } void OglViewerWidget::mouseReleaseEvent(QMouseEvent *e) { if (e->button() == Qt::LeftButton) m_mouse.left = false; else if (e->button() == Qt::RightButton) m_mouse.right = false; } void OglViewerWidget::mouseMoveEvent(QMouseEvent *e) { if (m_mouse.left) { // get the difference between last press and now QVector2D diff = QVector2D(e->localPos()) - m_mouse.position; // update the new position m_mouse.position = QVector2D(e->localPos()); // calculate the rotation axis and rotate m_rotation = QQuaternion::fromAxisAndAngle(QVector3D(diff.y(), diff.x(), 0.0).normalized(), diff.length() * 0.5) * m_rotation; // request an update update(); } } void OglViewerWidget::keyPressEvent(QKeyEvent *e) { if (e->key() == Qt::Key_Space) m_rotation = QQuaternion(); update(); } void OglViewerWidget::initializeGL() { initializeOpenGLFunctions(); glClearColor(0, 0, 0, 1); initShaders(); initTextures(); // Enable depth buffer glEnable(GL_DEPTH_TEST); // Enable back face culling glEnable(GL_CULL_FACE); geometries = new GeometryEngine; } void OglViewerWidget::initShaders() { // Compile vertex shader if (!program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/vshader.glsl")) close(); // Compile fragment shader if (!program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/fshader.glsl")) close(); // Link shader pipeline if (!program.link()) close(); // Bind shader pipeline for use if (!program.bind()) close(); } void OglViewerWidget::initTextures() { // Load cube.png image texture = new QOpenGLTexture(QImage(":images/cube.png").mirrored()); // Set nearest filtering mode for texture minification texture->setMinificationFilter(QOpenGLTexture::Nearest); // Set bilinear filtering mode for texture magnification texture->setMagnificationFilter(QOpenGLTexture::Linear); // Wrap texture coordinates by repeating // f.ex. texture coordinate (1.1, 1.2) is same as (0.1, 0.2) texture->setWrapMode(QOpenGLTexture::Repeat); } void OglViewerWidget::resizeGL(int w, int h) { // Calculate aspect ratio qreal aspect = qreal(w) / qreal(h ? h : 1); // Set near plane to 3.0, far plane to 7.0, field of view 45 degrees const qreal zNear = 3.0, zFar = 7.0, fov = 45.0; // Reset projection m_projection.setToIdentity(); // Set perspective projection m_projection.perspective(fov, aspect, zNear, zFar); } void OglViewerWidget::paintGL() { // Clear color and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); texture->bind(); // Calculate model view transformation QMatrix4x4 matrix; matrix.translate(0.0, 0.0, -5.0); matrix.rotate(m_rotation); // Set modelview-projection matrix program.setUniformValue("mvp_matrix", m_projection * matrix); // Use texture unit 0 which contains cube.png program.setUniformValue("texture", 0); // Draw cube geometry geometries->drawCubeGeometry(&program); }