OglViewerWidget.cpp 3.55 KB
Newer Older
1 2 3 4
#include "..\Header\OglViewerWidget.h"

#include <QMouseEvent>
#include <math.h>
5
#include <iostream>
6 7 8 9

OglViewerWidget::OglViewerWidget(QWidget *parent) :
	QOpenGLWidget(parent),
	geometries(0),
10
	texture(0)
11
{
12
	setFocus();
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
}

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
28 29 30 31 32 33 34
	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;
35 36 37 38
}

void OglViewerWidget::mouseReleaseEvent(QMouseEvent *e)
{
39 40 41 42 43
	if (e->button() == Qt::LeftButton)
		m_mouse.left = false;
	else if (e->button() == Qt::RightButton)
		m_mouse.right = false;
}
44

45 46 47 48 49 50
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;
51

52 53
		// update the new position
		m_mouse.position = QVector2D(e->localPos());
54

55 56
		// calculate the rotation axis and rotate
		m_rotation = QQuaternion::fromAxisAndAngle(QVector3D(diff.y(), diff.x(), 0.0).normalized(), diff.length() * 0.5) * m_rotation;
57

58 59 60
		// request an update
		update();
	}
61 62
}

63
void OglViewerWidget::keyPressEvent(QKeyEvent *e)
64
{
65 66
	if (e->key() == Qt::Key_Space)
		m_rotation = QQuaternion();
67

68
	update();
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
}

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
134
	m_projection.setToIdentity();
135 136

	// Set perspective projection
137
	m_projection.perspective(fov, aspect, zNear, zFar);
138 139 140 141 142 143 144 145 146 147 148 149
}

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);
150
	matrix.rotate(m_rotation);
151 152

	// Set modelview-projection matrix
153
	program.setUniformValue("mvp_matrix", m_projection * matrix);
154 155 156 157 158 159 160

	// Use texture unit 0 which contains cube.png
	program.setUniformValue("texture", 0);

	// Draw cube geometry
	geometries->drawCubeGeometry(&program);
}