GeometryEngine.cpp 4.96 KB
Newer Older
1 2 3 4 5
#include "..\Header\GeometryEngine.h"

#include <QVector2D>
#include <QVector3D>

Anakin's avatar
Anakin committed
6

7 8
struct VertexData
{
Anakin's avatar
Anakin committed
9 10
	QVector3D position;
	QVector2D texCoord;
11 12
};

Anakin's avatar
Anakin committed
13 14 15 16

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

17
GeometryEngine::GeometryEngine()
Anakin's avatar
Anakin committed
18
	: m_indexBuf(QOpenGLBuffer::IndexBuffer)
19
{
Anakin's avatar
Anakin committed
20
	initializeOpenGLFunctions();
21

Anakin's avatar
Anakin committed
22
	// Generate 2 VBOs
Anakin's avatar
Anakin committed
23 24
	m_arrayBuf.create();
	m_indexBuf.create();
25

Anakin's avatar
Anakin committed
26 27
	// Initializes cube geometry and transfers it to VBOs
	initCubeGeometry();
28 29 30 31
}

GeometryEngine::~GeometryEngine()
{
Anakin's avatar
Anakin committed
32 33 34 35 36 37 38
	m_arrayBuf.destroy();
	m_indexBuf.destroy();

	for (auto it : m_textures)
		delete it;
	m_textures.clear();
	m_textures.squeeze();
39 40
}

Anakin's avatar
Anakin committed
41 42 43 44

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

45 46
void GeometryEngine::initCubeGeometry()
{
Anakin's avatar
Anakin committed
47 48

	QVector<VertexData> vertices = {
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
        // Vertex data for face 0
        {QVector3D(-1.0f, -1.0f,  1.0f), QVector2D(0.0f, 0.0f)},  // v0
        {QVector3D( 1.0f, -1.0f,  1.0f), QVector2D(0.33f, 0.0f)}, // v1
        {QVector3D(-1.0f,  1.0f,  1.0f), QVector2D(0.0f, 0.5f)},  // v2
        {QVector3D( 1.0f,  1.0f,  1.0f), QVector2D(0.33f, 0.5f)}, // v3

        // Vertex data for face 1
        {QVector3D( 1.0f, -1.0f,  1.0f), QVector2D( 0.0f, 0.5f)}, // v4
        {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.33f, 0.5f)}, // v5
        {QVector3D( 1.0f,  1.0f,  1.0f), QVector2D(0.0f, 1.0f)},  // v6
        {QVector3D( 1.0f,  1.0f, -1.0f), QVector2D(0.33f, 1.0f)}, // v7

        // Vertex data for face 2
        {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.66f, 0.5f)}, // v8
        {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(1.0f, 0.5f)},  // v9
        {QVector3D( 1.0f,  1.0f, -1.0f), QVector2D(0.66f, 1.0f)}, // v10
        {QVector3D(-1.0f,  1.0f, -1.0f), QVector2D(1.0f, 1.0f)},  // v11

        // Vertex data for face 3
        {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(0.66f, 0.0f)}, // v12
        {QVector3D(-1.0f, -1.0f,  1.0f), QVector2D(1.0f, 0.0f)},  // v13
        {QVector3D(-1.0f,  1.0f, -1.0f), QVector2D(0.66f, 0.5f)}, // v14
        {QVector3D(-1.0f,  1.0f,  1.0f), QVector2D(1.0f, 0.5f)},  // v15

        // Vertex data for face 4
        {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(0.33f, 0.0f)}, // v16
        {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.66f, 0.0f)}, // v17
        {QVector3D(-1.0f, -1.0f,  1.0f), QVector2D(0.33f, 0.5f)}, // v18
        {QVector3D( 1.0f, -1.0f,  1.0f), QVector2D(0.66f, 0.5f)}, // v19

        // Vertex data for face 5
        {QVector3D(-1.0f,  1.0f,  1.0f), QVector2D(0.33f, 0.5f)}, // v20
        {QVector3D( 1.0f,  1.0f,  1.0f), QVector2D(0.66f, 0.5f)}, // v21
        {QVector3D(-1.0f,  1.0f, -1.0f), QVector2D(0.33f, 1.0f)}, // v22
        {QVector3D( 1.0f,  1.0f, -1.0f), QVector2D(0.66f, 1.0f)}  // v23
    };

Anakin's avatar
Anakin committed
86
	QVector<GLushort> indices = {
Anakin's avatar
Anakin committed
87 88 89 90 91 92 93 94 95 96 97 98
		0,1,2,		//vorne (4)
		3,2,1,
		4,5,7,		//rechts (1)
		6,4,7,
		8,9,11,		//hinten (3)*
		8,11,10,
		14,12,13,	//links (6)*
		14,13,15,
		18,16,17,	//unten (5)
		19,18,17,
		23,22,20,	//oben (2)*
		23,20,21
Anakin's avatar
Anakin committed
99
	};
100

Anakin's avatar
Anakin committed
101 102 103
	// Transfer vertex data to VBO 0
	m_arrayBuf.bind();
	m_arrayBuf.allocate(vertices.data(), vertices.size() * sizeof(VertexData));
104

Anakin's avatar
Anakin committed
105 106 107
	// Transfer index data to VBO 1
	m_indexBuf.bind();
	m_indexBuf.allocate(indices.data(), indices.size() * sizeof(GLushort));
Anakin's avatar
Anakin committed
108

Anakin's avatar
Anakin committed
109
	// load the texture
Anakin's avatar
Anakin committed
110
	initTexture();
111 112
}

Anakin's avatar
Anakin committed
113
void GeometryEngine::initTexture()
114
{
Anakin's avatar
Anakin committed
115
	// Load cube.png image
Anakin's avatar
Anakin committed
116
	QOpenGLTexture* new_texture = new QOpenGLTexture(QImage(":images/cube.png").mirrored());
Anakin's avatar
Anakin committed
117 118

	// Set nearest filtering mode for texture minification
Anakin's avatar
Anakin committed
119
	new_texture->setMinificationFilter(QOpenGLTexture::Nearest);
Anakin's avatar
Anakin committed
120 121

	// Set bilinear filtering mode for texture magnification
Anakin's avatar
Anakin committed
122
	new_texture->setMagnificationFilter(QOpenGLTexture::Linear);
Anakin's avatar
Anakin committed
123 124 125

	// Wrap texture coordinates by repeating
	// f.ex. texture coordinate (1.1, 1.2) is same as (0.1, 0.2)
Anakin's avatar
Anakin committed
126 127 128
	new_texture->setWrapMode(QOpenGLTexture::Repeat);

	m_textures.push_back(new_texture);
Anakin's avatar
Anakin committed
129 130
}

Anakin's avatar
Anakin committed
131 132 133 134

/////////////////////////////////////////////////////////////////////////
// public functions

Anakin's avatar
Anakin committed
135 136 137
void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program)
{
	// Tell OpenGL which VBOs to use
Anakin's avatar
Anakin committed
138 139 140
	m_arrayBuf.bind();
	m_indexBuf.bind();
	m_textures.first()->bind();
Anakin's avatar
Anakin committed
141 142 143

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

Anakin's avatar
Anakin committed
145 146
	// Offset for position
	quintptr offset = 0;
147

Anakin's avatar
Anakin committed
148 149 150 151
	// Tell OpenGL programmable pipeline how to locate vertex position data
	int vertexLocation = program->attributeLocation("a_position");
	program->enableAttributeArray(vertexLocation);
	program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3, sizeof(VertexData));
152

Anakin's avatar
Anakin committed
153 154
	// Offset for texture coordinate
	offset += sizeof(QVector3D);
155

Anakin's avatar
Anakin committed
156 157 158 159
	// Tell OpenGL programmable pipeline how to locate vertex texture coordinate data
	int texcoordLocation = program->attributeLocation("a_texcoord");
	program->enableAttributeArray(texcoordLocation);
	program->setAttributeBuffer(texcoordLocation, GL_FLOAT, offset, 2, sizeof(VertexData));
160

Anakin's avatar
Anakin committed
161 162
	// Draw cube geometry using indices from VBO 1
	glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0);
163
}