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

#include <QMouseEvent>
Anakin's avatar
Anakin committed
4 5
#include <QDropEvent>
#include <QMimeData>
6
#include <math.h>
Anakin's avatar
Anakin committed
7 8 9
#include <iostream>

#define DEFAULT_Z_DISTANCE -5.0
10

Anakin's avatar
Anakin committed
11 12 13 14

/////////////////////////////////////////////////////////////////////////
// public constructor/destructor

15 16
OglViewerWidget::OglViewerWidget(QWidget *parent) :
	QOpenGLWidget(parent),
Anakin's avatar
Anakin committed
17
	m_dataEngine(0)
18
{
19
	setFocus();
Anakin's avatar
Anakin committed
20
	m_translation.setZ(DEFAULT_Z_DISTANCE);
Anakin's avatar
Anakin committed
21
	setAcceptDrops(true);
22 23 24 25 26 27 28
}

OglViewerWidget::~OglViewerWidget()
{
	// Make sure the context is current when deleting the texture
	// and the buffers.
	makeCurrent();
Anakin's avatar
Anakin committed
29
	delete m_dataEngine;
30 31 32
	doneCurrent();
}

Anakin's avatar
Anakin committed
33 34 35 36

/////////////////////////////////////////////////////////////////////////
// protected functions

37 38 39
void OglViewerWidget::mousePressEvent(QMouseEvent *e)
{
	// Save mouse press position
40 41 42 43 44 45 46
	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;
47 48 49 50
}

void OglViewerWidget::mouseReleaseEvent(QMouseEvent *e)
{
51 52 53 54 55
	if (e->button() == Qt::LeftButton)
		m_mouse.left = false;
	else if (e->button() == Qt::RightButton)
		m_mouse.right = false;
}
56

57 58 59 60 61 62
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;
63

64 65
		// update the new position
		m_mouse.position = QVector2D(e->localPos());
66

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

Anakin's avatar
Anakin committed
70 71 72 73 74 75 76 77 78 79 80 81 82 83
		// request an update
		update();
	}
	else if (m_mouse.right)
	{
		// 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 translation
		m_translation += {(float)(diff.x() * 0.01), (float)(diff.y() * -0.01), 0.0};

84 85 86
		// request an update
		update();
	}
87 88
}

Anakin's avatar
Anakin committed
89 90 91 92 93 94
void OglViewerWidget::wheelEvent(QWheelEvent *e)
{
	m_translation += {0.0, 0.0, (float)e->angleDelta().y() / 240};
	update();
}

Anakin's avatar
Anakin committed
95 96 97 98 99
void OglViewerWidget::dropEvent(QDropEvent * e)
{
	std::cout << e->mimeData()->text().toStdString() << std::endl;
}

100
void OglViewerWidget::keyPressEvent(QKeyEvent *e)
101
{
102
	if (e->key() == Qt::Key_Space)
Anakin's avatar
Anakin committed
103
	{
104
		m_rotation = QQuaternion();
Anakin's avatar
Anakin committed
105 106
		m_translation = { 0.0, 0.0, DEFAULT_Z_DISTANCE };
	}
Anakin's avatar
Anakin committed
107 108 109 110
	else if (e->key() == Qt::Key_Escape)
	{
		parentWidget()->close();
	}
111
	update();
112 113 114 115 116 117
}

void OglViewerWidget::initializeGL()
{
	initializeOpenGLFunctions();

Anakin's avatar
Anakin committed
118
	glClearColor(0.5000f, 0.8000f, 1.0000f, 0.0000f);
119 120 121 122 123 124 125 126 127

	initShaders();

	// Enable depth buffer
	glEnable(GL_DEPTH_TEST);

	// Enable back face culling
	glEnable(GL_CULL_FACE);

Anakin's avatar
Anakin committed
128
	m_dataEngine = new GeometryEngine;
129 130 131 132 133 134 135 136 137

}

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
Anakin's avatar
Anakin committed
138
	const qreal zNear = 0.1, zFar = 100.0, fov = 45.0;
139 140

	// Reset projection
141
	m_projection.setToIdentity();
142 143

	// Set perspective projection
144
	m_projection.perspective(fov, aspect, zNear, zFar);
145 146 147 148 149 150 151 152
}

void OglViewerWidget::paintGL()
{
	// Clear color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Calculate model view transformation
Anakin's avatar
Anakin committed
153
	QMatrix4x4 view;
Anakin's avatar
Anakin committed
154
	view.translate(m_translation);
Anakin's avatar
Anakin committed
155
	view.rotate(m_rotation);
156

Anakin's avatar
Anakin committed
157 158
	// Set view-projection matrix
	m_program.setUniformValue("vp_matrix", m_projection * view);
159 160

	// Draw cube geometry
Anakin's avatar
Anakin committed
161
	m_dataEngine->drawGeometry(&m_program);
162
}
Anakin's avatar
Anakin committed
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188


/////////////////////////////////////////////////////////////////////////
// private functions

void OglViewerWidget::initShaders()
{
	// Compile vertex shader
	if (!m_program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/vshader.glsl"))
		close();

	// Compile fragment shader
	if (!m_program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/fshader.glsl"))
		close();

	// Link shader pipeline
	if (!m_program.link())
		close();

	// Bind shader pipeline for use
	if (!m_program.bind())
		close();
}


/////////////////////////////////////////////////////////////////////////
Anakin's avatar
Anakin committed
189 190 191 192 193 194
// public functions

void OglViewerWidget::openFile(const char * filePath)
{
	m_dataEngine->loadFile(filePath);
}