2013-12-23 16:24:05 +00:00
|
|
|
#ifndef VERTEXARRAY_H
|
|
|
|
#define VERTEXARRAY_H
|
|
|
|
|
|
|
|
#include "opengl_global.h"
|
|
|
|
|
2013-12-24 10:44:39 +00:00
|
|
|
#include OPENGL_FUNCTIONS_INCLUDE
|
2013-12-23 16:24:05 +00:00
|
|
|
#include <cassert>
|
2013-12-24 10:44:39 +00:00
|
|
|
#include <QOpenGLShaderProgram>
|
2013-12-23 16:24:05 +00:00
|
|
|
|
|
|
|
namespace paysages {
|
|
|
|
namespace opengl {
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Wrapper for OpenGL vertex arrays.
|
|
|
|
*/
|
|
|
|
template <typename Vertex> class VertexArray
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
VertexArray()
|
|
|
|
{
|
|
|
|
ready = false;
|
|
|
|
changed = false;
|
|
|
|
vertex_count = 1;
|
|
|
|
vertices = new Vertex[1];
|
|
|
|
index_count = 1;
|
2013-12-24 10:44:39 +00:00
|
|
|
indices = new unsigned short[1];
|
2013-12-23 16:24:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
~VertexArray()
|
|
|
|
{
|
|
|
|
delete[] vertices;
|
|
|
|
delete[] indices;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline int getVertexCount() {return vertex_count;}
|
|
|
|
inline int getIndexCount() {return index_count;}
|
|
|
|
inline bool isReady() {return ready;}
|
|
|
|
inline bool isChanged() {return changed;}
|
|
|
|
|
|
|
|
void setVertexCount(int count)
|
|
|
|
{
|
|
|
|
assert(count > 0 and count <= 16384);
|
|
|
|
|
|
|
|
delete[] vertices;
|
|
|
|
vertices = new Vertex[count];
|
|
|
|
|
|
|
|
vertex_count = count;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setGridSize(int edge_vertex_count)
|
|
|
|
{
|
|
|
|
assert(edge_vertex_count >= 2);
|
|
|
|
|
|
|
|
setVertexCount(edge_vertex_count * edge_vertex_count);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setVertex(int position, const Vertex &vertex)
|
|
|
|
{
|
|
|
|
assert(position >= 0 and position < vertex_count);
|
|
|
|
|
|
|
|
vertices[position] = vertex;
|
|
|
|
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setGridVertex(int edge_vertex_count, int x, int y, const Vertex &vertex)
|
|
|
|
{
|
|
|
|
setVertex(y * edge_vertex_count + x, vertex);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setAutoGridIndices(int edge_vertex_count, int stride=1)
|
|
|
|
{
|
|
|
|
assert(stride >= 1);
|
|
|
|
|
|
|
|
delete[] indices;
|
|
|
|
int cell_count = edge_vertex_count - 1;
|
|
|
|
|
|
|
|
index_count = (cell_count / stride) * (cell_count / stride) * 6;
|
2013-12-24 10:44:39 +00:00
|
|
|
indices = new unsigned short[index_count];
|
2013-12-23 16:24:05 +00:00
|
|
|
|
|
|
|
int idx = 0;
|
|
|
|
for (int y = 0; y < cell_count; y += stride)
|
|
|
|
{
|
|
|
|
for (int x = 0; x < cell_count; x += stride)
|
|
|
|
{
|
|
|
|
int base = y * edge_vertex_count + x;
|
|
|
|
indices[idx++] = base;
|
|
|
|
indices[idx++] = base + edge_vertex_count * stride;
|
|
|
|
indices[idx++] = base + stride;
|
|
|
|
indices[idx++] = base + stride;
|
|
|
|
indices[idx++] = base + edge_vertex_count * stride;
|
|
|
|
indices[idx++] = base + edge_vertex_count * stride + stride;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Vertex getVertex(int position)
|
|
|
|
{
|
|
|
|
assert(position >= 0 and position < vertex_count);
|
|
|
|
|
|
|
|
return vertices[position];
|
|
|
|
}
|
|
|
|
|
2013-12-24 10:44:39 +00:00
|
|
|
Vertex getVertexByIndex(unsigned short index)
|
2013-12-23 16:24:05 +00:00
|
|
|
{
|
|
|
|
assert(index >= 0 and index < index_count);
|
|
|
|
|
|
|
|
return getVertex(indices[index]);
|
|
|
|
}
|
|
|
|
|
|
|
|
Vertex getGridVertex(int edge_vertex_count, int x, int y)
|
|
|
|
{
|
|
|
|
return getVertex(y * edge_vertex_count + x);
|
|
|
|
}
|
|
|
|
|
2013-12-24 10:44:39 +00:00
|
|
|
unsigned short getIndex(int position)
|
2013-12-23 16:24:05 +00:00
|
|
|
{
|
|
|
|
assert(position >= 0 and position < index_count);
|
|
|
|
|
|
|
|
return indices[position];
|
|
|
|
}
|
|
|
|
|
2013-12-24 10:44:39 +00:00
|
|
|
void render(QOpenGLShaderProgram* program, OpenGLFunctions* functions)
|
|
|
|
{
|
|
|
|
size_t ptr = (size_t)vertices;
|
|
|
|
|
|
|
|
GLuint vertex = program->attributeLocation("vertex");
|
|
|
|
program->setAttributeArray(vertex, GL_FLOAT, (void*)(ptr + offsetof(Vertex, location)), 3, sizeof(Vertex));
|
|
|
|
program->enableAttributeArray(vertex);
|
|
|
|
|
|
|
|
GLuint uv = program->attributeLocation("uv");
|
|
|
|
program->setAttributeArray(uv, GL_FLOAT, (void*)(ptr + offsetof(Vertex, uv)), 2, sizeof(Vertex));
|
|
|
|
program->enableAttributeArray(uv);
|
|
|
|
|
|
|
|
functions->glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_SHORT, indices);
|
|
|
|
|
|
|
|
program->disableAttributeArray(vertex);
|
|
|
|
program->disableAttributeArray(uv);
|
|
|
|
}
|
|
|
|
|
2013-12-23 16:24:05 +00:00
|
|
|
private:
|
|
|
|
bool ready;
|
|
|
|
bool changed;
|
|
|
|
|
|
|
|
int vertex_count;
|
|
|
|
Vertex* vertices;
|
|
|
|
|
|
|
|
int index_count;
|
2013-12-24 10:44:39 +00:00
|
|
|
unsigned short* indices;
|
2013-12-23 16:24:05 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // VERTEXARRAY_H
|