GeometryEngine.cpp 4.02 KB
Newer Older
1
#include "..\Header\GeometryEngine.h"
Anakin's avatar
Anakin committed
2
#include "..\Header\MshFile.h"
3

Anakin's avatar
Anakin committed
4 5 6 7

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

8
GeometryEngine::GeometryEngine()
Anakin's avatar
Anakin committed
9
	: m_indexBuf(QOpenGLBuffer::IndexBuffer)
10
{
Anakin's avatar
Anakin committed
11
	initializeOpenGLFunctions();
12

Anakin's avatar
Anakin committed
13
	// Generate 2 VBOs
Anakin's avatar
Anakin committed
14 15
	m_arrayBuf.create();
	m_indexBuf.create();
16

Anakin's avatar
Anakin committed
17 18
	// Initializes cube geometry and transfers it to VBOs
	initCubeGeometry();
19 20 21 22
}

GeometryEngine::~GeometryEngine()
{
Anakin's avatar
Anakin committed
23 24 25 26 27 28
	m_arrayBuf.destroy();
	m_indexBuf.destroy();

	for (auto it : m_textures)
		delete it;
	m_textures.clear();
Anakin's avatar
Anakin committed
29
	m_drawList.clear();
30 31
}

Anakin's avatar
Anakin committed
32 33 34 35

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

36 37
void GeometryEngine::initCubeGeometry()
{
Anakin's avatar
Anakin committed
38 39 40
	QVector<Model*>* models;
	QVector<VertexData> vertexData;
	QVector<GLuint> indexData;
Anakin's avatar
Anakin committed
41

Anakin's avatar
Anakin committed
42 43
	try
	{
Anakin's avatar
Anakin committed
44
		MshFile file("..\\Release\\Msh\\triClothMan.msh");
Anakin's avatar
Anakin committed
45
		 models = file.getModels();
Anakin's avatar
Anakin committed
46
		//TODO normalize
Anakin's avatar
Anakin committed
47
		//TODO: handle the textures
Anakin's avatar
Anakin committed
48 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 86

		// collect data
		unsigned int offsetCount(0);
		for (auto& modelIterator : *models)
		{
			for (auto& segmentIterator : modelIterator->segmList)
			{
				// get draw information
				DrawInformation new_info;
				new_info.offset = offsetCount;
				new_info.size = segmentIterator->indices.size();
				new_info.textureIndex = segmentIterator->textureIndex;
				new_info.modelMatrix = modelIterator->m4x4Translation;

				// add offset to indices
				for (auto& it : segmentIterator->indices)
					it += new_info.offset;

				// save data
				vertexData += segmentIterator->vertices;
				indexData += segmentIterator->indices;
				m_drawList.push_back(new_info);

				// update offset
				offsetCount += new_info.size;
			}
		}

		// Transfer vertex data to VBO 0
		m_arrayBuf.bind();
		m_arrayBuf.allocate(vertexData.data(), vertexData.size() * sizeof(VertexData));

		// Transfer index data to VBO 1
		m_indexBuf.bind();
		m_indexBuf.allocate(indexData.data(), indexData.size() * sizeof(GLuint));

		// load the texture
		initTexture();

Anakin's avatar
Anakin committed
87 88 89 90 91 92
	}
	catch (std::invalid_argument e)
	{
		//TODO: make a cool message box
		auto msg = e.what();
	}
93

Anakin's avatar
Anakin committed
94
	
95 96
}

Anakin's avatar
Anakin committed
97
void GeometryEngine::initTexture()
98
{
Anakin's avatar
Anakin committed
99
	// Load cube.png image
Anakin's avatar
Anakin committed
100
	QOpenGLTexture* new_texture = new QOpenGLTexture(QImage(":images/cube.png").mirrored());
Anakin's avatar
Anakin committed
101 102

	// Set nearest filtering mode for texture minification
Anakin's avatar
Anakin committed
103
	new_texture->setMinificationFilter(QOpenGLTexture::Nearest);
Anakin's avatar
Anakin committed
104 105

	// Set bilinear filtering mode for texture magnification
Anakin's avatar
Anakin committed
106
	new_texture->setMagnificationFilter(QOpenGLTexture::Linear);
Anakin's avatar
Anakin committed
107 108 109

	// 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
110 111 112
	new_texture->setWrapMode(QOpenGLTexture::Repeat);

	m_textures.push_back(new_texture);
Anakin's avatar
Anakin committed
113 114
}

Anakin's avatar
Anakin committed
115 116 117 118

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

Anakin's avatar
Anakin committed
119 120
void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program)
{
Anakin's avatar
Anakin committed
121
// Setup
Anakin's avatar
Anakin committed
122
	// Tell OpenGL which VBOs to use
Anakin's avatar
Anakin committed
123 124
	m_arrayBuf.bind();
	m_indexBuf.bind();
Anakin's avatar
Anakin committed
125

Anakin's avatar
Anakin committed
126
	// Allways use texture unit 0
Anakin's avatar
Anakin committed
127
	program->setUniformValue("texture", 0);
128

Anakin's avatar
Anakin committed
129 130
	// Offset for position
	quintptr offset = 0;
131

Anakin's avatar
Anakin committed
132 133 134 135
	// 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));
136

Anakin's avatar
Anakin committed
137 138
	// Offset for texture coordinate
	offset += sizeof(QVector3D);
139

Anakin's avatar
Anakin committed
140 141 142 143
	// 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));
144

Anakin's avatar
Anakin committed
145 146 147 148 149 150 151
// Paint

	for (auto& it : m_drawList)
	{
		// bind the correct texture
		if (it.textureIndex < m_textures.size())
			m_textures.at(it.textureIndex)->bind();
Anakin's avatar
Anakin committed
152 153
		else
			m_textures.last()->bind();
Anakin's avatar
Anakin committed
154 155 156 157 158 159 160

		// Set model matrix
		program->setUniformValue("m_matrix", it.modelMatrix);

		// Draw cube geometry using indices from VBO 1
		glDrawElements(GL_TRIANGLES, it.size, GL_UNSIGNED_INT, (void*)(it.offset * sizeof(GLuint)));
	}
161
}