Introduced VertexArray object to handle terrain vertex data
This will be used later with opengl vertex arrays
This commit is contained in:
parent
ac5c0fd584
commit
f97823604e
8 changed files with 291 additions and 21 deletions
|
@ -8,6 +8,7 @@
|
|||
#include "CameraDefinition.h"
|
||||
#include "OpenGLRenderer.h"
|
||||
#include "TerrainRenderer.h"
|
||||
#include "VertexArray.h"
|
||||
|
||||
ExplorerChunkTerrain::ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, double z, double size, int nbchunks, double water_height):
|
||||
_renderer(renderer)
|
||||
|
@ -33,8 +34,11 @@ ExplorerChunkTerrain::ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, d
|
|||
_water_height = water_height;
|
||||
_overwater = false;
|
||||
|
||||
_tessellation_max_size = 32;
|
||||
_tessellation = new double[(_tessellation_max_size + 1) * (_tessellation_max_size + 1)];
|
||||
tessellation_count = 33;
|
||||
tessellated = new VertexArray<TerrainVertex>();
|
||||
tessellated->setGridSize(tessellation_count);
|
||||
tessellated->setAutoGridIndices(tessellation_count);
|
||||
_tessellation_max_size = tessellation_count - 1;
|
||||
_tessellation_current_size = 0;
|
||||
_tessellation_step = _size / (double) _tessellation_max_size;
|
||||
|
||||
|
@ -49,7 +53,7 @@ ExplorerChunkTerrain::~ExplorerChunkTerrain()
|
|||
delete _color_profile;
|
||||
delete _texture;
|
||||
delete texture;
|
||||
delete [] _tessellation;
|
||||
delete tessellated;
|
||||
_lock_data.unlock();
|
||||
}
|
||||
|
||||
|
@ -116,24 +120,39 @@ bool ExplorerChunkTerrain::onMaintainEvent()
|
|||
int new_tessellation_size = _tessellation_current_size ? _tessellation_current_size * 4 : 2;
|
||||
int old_tessellation_inc = _tessellation_current_size ? _tessellation_max_size / _tessellation_current_size : 1;
|
||||
int new_tessellation_inc = _tessellation_max_size / new_tessellation_size;
|
||||
float internal_step = 1.0f / (float)_tessellation_max_size;
|
||||
for (int j = 0; j <= _tessellation_max_size; j += new_tessellation_inc)
|
||||
{
|
||||
for (int i = 0; i <= _tessellation_max_size; i += new_tessellation_inc)
|
||||
{
|
||||
if (_tessellation_current_size == 0 || i % old_tessellation_inc != 0 || j % old_tessellation_inc != 0)
|
||||
{
|
||||
double height = _renderer->getTerrainRenderer()->getHeight(_startx + _tessellation_step * (double) i, _startz + _tessellation_step * (double) j, 1);
|
||||
double x = _startx + _tessellation_step * (float)i;
|
||||
double z = _startz + _tessellation_step * (float)j;
|
||||
|
||||
double height = _renderer->getTerrainRenderer()->getHeight(x, z, 1);
|
||||
if (height >= _water_height)
|
||||
{
|
||||
_overwater = true;
|
||||
}
|
||||
_tessellation[j * (_tessellation_max_size + 1) + i] = height;
|
||||
|
||||
TerrainVertex v;
|
||||
|
||||
v.uv[0] = internal_step * (float)i;
|
||||
v.uv[1] = internal_step * (float)j;
|
||||
|
||||
v.location[0] = x;
|
||||
v.location[1] = height;
|
||||
v.location[2] = z;
|
||||
|
||||
tessellated->setGridVertex(tessellation_count, i, j, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_lock_data.lock();
|
||||
_tessellation_current_size = new_tessellation_size;
|
||||
tessellated->setAutoGridIndices(tessellation_count, new_tessellation_inc);
|
||||
_lock_data.unlock();
|
||||
|
||||
if (_tessellation_current_size < 4 && _tessellation_current_size < _tessellation_max_size)
|
||||
|
@ -216,7 +235,6 @@ void ExplorerChunkTerrain::render(OpenGLFunctions* functions)
|
|||
{
|
||||
_lock_data.lock();
|
||||
int tessellation_size = _tessellation_current_size;
|
||||
double tsize = 1.0 / (double) _tessellation_max_size;
|
||||
_lock_data.unlock();
|
||||
|
||||
if (tessellation_size <= 1 or not _overwater)
|
||||
|
@ -224,19 +242,17 @@ void ExplorerChunkTerrain::render(OpenGLFunctions* functions)
|
|||
return;
|
||||
}
|
||||
|
||||
int tessellation_inc = _tessellation_max_size / (double) tessellation_size;
|
||||
for (int j = 0; j < _tessellation_max_size; j += tessellation_inc)
|
||||
_lock_data.lock(); // TEMP
|
||||
int n = tessellated->getIndexCount();
|
||||
functions->glBegin(GL_TRIANGLES);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
functions->glBegin(GL_QUAD_STRIP);
|
||||
for (int i = 0; i <= _tessellation_max_size; i += tessellation_inc)
|
||||
{
|
||||
functions->glTexCoord2d(tsize * (double) i, tsize * (double) j);
|
||||
functions->glVertex3d(_startx + _tessellation_step * (double) i, _tessellation[j * (_tessellation_max_size + 1) + i], _startz + _tessellation_step * (double) j);
|
||||
functions->glTexCoord2d(tsize * (double) i, tsize * (double) (j + tessellation_inc));
|
||||
functions->glVertex3d(_startx + _tessellation_step * (double) i, _tessellation[(j + tessellation_inc) * (_tessellation_max_size + 1) + i], _startz + _tessellation_step * (double) (j + tessellation_inc));
|
||||
TerrainVertex v = tessellated->getVertexByIndex(i);
|
||||
functions->glTexCoord2d(v.uv[0], v.uv[1]);
|
||||
functions->glVertex3d(v.location[0], v.location[1], v.location[2]);
|
||||
}
|
||||
functions->glEnd();
|
||||
}
|
||||
_lock_data.unlock(); // TEMP
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,13 @@ namespace opengl {
|
|||
|
||||
class OPENGLSHARED_EXPORT ExplorerChunkTerrain
|
||||
{
|
||||
public:
|
||||
typedef struct
|
||||
{
|
||||
float location[3];
|
||||
float uv[2];
|
||||
} TerrainVertex;
|
||||
|
||||
public:
|
||||
ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, double z, double size, int nbchunks, double water_height);
|
||||
~ExplorerChunkTerrain();
|
||||
|
@ -41,7 +48,8 @@ private:
|
|||
double _water_height;
|
||||
bool _overwater;
|
||||
|
||||
double* _tessellation;
|
||||
int tessellation_count;
|
||||
VertexArray<TerrainVertex> *tessellated;
|
||||
int _tessellation_max_size;
|
||||
int _tessellation_current_size;
|
||||
double _tessellation_step;
|
||||
|
|
1
src/render/opengl/VertexArray.cpp
Normal file
1
src/render/opengl/VertexArray.cpp
Normal file
|
@ -0,0 +1 @@
|
|||
#include "VertexArray.h"
|
135
src/render/opengl/VertexArray.h
Normal file
135
src/render/opengl/VertexArray.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
#ifndef VERTEXARRAY_H
|
||||
#define VERTEXARRAY_H
|
||||
|
||||
#include "opengl_global.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
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;
|
||||
indices = new int[1];
|
||||
}
|
||||
|
||||
~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;
|
||||
indices = new int[index_count];
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
Vertex getVertexByIndex(int index)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
int getIndex(int position)
|
||||
{
|
||||
assert(position >= 0 and position < index_count);
|
||||
|
||||
return indices[position];
|
||||
}
|
||||
|
||||
private:
|
||||
bool ready;
|
||||
bool changed;
|
||||
|
||||
int vertex_count;
|
||||
Vertex* vertices;
|
||||
|
||||
int index_count;
|
||||
int* indices;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // VERTEXARRAY_H
|
|
@ -23,7 +23,8 @@ SOURCES += \
|
|||
OpenGLWater.cpp \
|
||||
OpenGLSharedState.cpp \
|
||||
OpenGLVariable.cpp \
|
||||
OpenGLTerrain.cpp
|
||||
OpenGLTerrain.cpp \
|
||||
VertexArray.cpp
|
||||
|
||||
HEADERS +=\
|
||||
opengl_global.h \
|
||||
|
@ -36,7 +37,8 @@ HEADERS +=\
|
|||
OpenGLWater.h \
|
||||
OpenGLSharedState.h \
|
||||
OpenGLVariable.h \
|
||||
OpenGLTerrain.h
|
||||
OpenGLTerrain.h \
|
||||
VertexArray.h
|
||||
|
||||
unix:!symbian {
|
||||
maemo5 {
|
||||
|
|
|
@ -22,6 +22,7 @@ namespace opengl {
|
|||
class OpenGLWater;
|
||||
class OpenGLTerrain;
|
||||
class ExplorerChunkTerrain;
|
||||
template <typename Vertex> class VertexArray;
|
||||
}
|
||||
}
|
||||
using namespace paysages::opengl;
|
||||
|
|
100
src/tests/VertexArray_Test.cpp
Normal file
100
src/tests/VertexArray_Test.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
#include "BaseTestCase.h"
|
||||
|
||||
#include "VertexArray.h"
|
||||
|
||||
class TestVertex
|
||||
{
|
||||
public:
|
||||
float uv[2];
|
||||
int loc[3];
|
||||
|
||||
bool operator==(const TestVertex &other) const
|
||||
{
|
||||
return other.uv[0] == uv[0]
|
||||
and other.uv[1] == uv[1]
|
||||
and other.loc[0] == loc[0]
|
||||
and other.loc[1] == loc[1]
|
||||
and other.loc[2] == loc[2];
|
||||
}
|
||||
};
|
||||
|
||||
TEST(VertexArray, grid)
|
||||
{
|
||||
VertexArray<TestVertex> array;
|
||||
|
||||
array.setGridSize(3);
|
||||
|
||||
ASSERT_EQ(9, array.getVertexCount());
|
||||
|
||||
TestVertex v1 = {{0.1, 0.2}, {1, 2, 3}};
|
||||
TestVertex vgot;
|
||||
|
||||
array.setGridVertex(3, 1, 2, v1);
|
||||
vgot = array.getGridVertex(3, 1, 2);
|
||||
EXPECT_EQ(v1, vgot);
|
||||
vgot = array.getVertex(7);
|
||||
EXPECT_EQ(v1, vgot);
|
||||
}
|
||||
|
||||
TEST(VertexArray, gridIndices)
|
||||
{
|
||||
VertexArray<TestVertex> array;
|
||||
|
||||
array.setGridSize(3);
|
||||
|
||||
array.setAutoGridIndices(3);
|
||||
ASSERT_EQ(24, array.getIndexCount());
|
||||
|
||||
EXPECT_EQ(0, array.getIndex(0));
|
||||
EXPECT_EQ(3, array.getIndex(1));
|
||||
EXPECT_EQ(1, array.getIndex(2));
|
||||
|
||||
EXPECT_EQ(1, array.getIndex(3));
|
||||
EXPECT_EQ(3, array.getIndex(4));
|
||||
EXPECT_EQ(4, array.getIndex(5));
|
||||
|
||||
EXPECT_EQ(1, array.getIndex(6));
|
||||
EXPECT_EQ(4, array.getIndex(7));
|
||||
EXPECT_EQ(2, array.getIndex(8));
|
||||
|
||||
EXPECT_EQ(2, array.getIndex(9));
|
||||
EXPECT_EQ(4, array.getIndex(10));
|
||||
EXPECT_EQ(5, array.getIndex(11));
|
||||
|
||||
EXPECT_EQ(3, array.getIndex(12));
|
||||
EXPECT_EQ(6, array.getIndex(13));
|
||||
EXPECT_EQ(4, array.getIndex(14));
|
||||
}
|
||||
|
||||
TEST(VertexArray, gridIndicesStride)
|
||||
{
|
||||
VertexArray<TestVertex> array;
|
||||
|
||||
array.setGridSize(5);
|
||||
|
||||
array.setAutoGridIndices(5, 1);
|
||||
ASSERT_EQ(96, array.getIndexCount());
|
||||
|
||||
array.setAutoGridIndices(5, 2);
|
||||
ASSERT_EQ(24, array.getIndexCount());
|
||||
|
||||
EXPECT_EQ(0, array.getIndex(0));
|
||||
EXPECT_EQ(10, array.getIndex(1));
|
||||
EXPECT_EQ(2, array.getIndex(2));
|
||||
|
||||
EXPECT_EQ(2, array.getIndex(3));
|
||||
EXPECT_EQ(10, array.getIndex(4));
|
||||
EXPECT_EQ(12, array.getIndex(5));
|
||||
|
||||
EXPECT_EQ(2, array.getIndex(6));
|
||||
EXPECT_EQ(12, array.getIndex(7));
|
||||
EXPECT_EQ(4, array.getIndex(8));
|
||||
|
||||
EXPECT_EQ(4, array.getIndex(9));
|
||||
EXPECT_EQ(12, array.getIndex(10));
|
||||
EXPECT_EQ(14, array.getIndex(11));
|
||||
|
||||
EXPECT_EQ(10, array.getIndex(12));
|
||||
EXPECT_EQ(20, array.getIndex(13));
|
||||
EXPECT_EQ(12, array.getIndex(14));
|
||||
}
|
|
@ -17,7 +17,8 @@ SOURCES += main.cpp \
|
|||
Bruneton_Test.cpp \
|
||||
Camera_Test.cpp \
|
||||
Clouds_Test.cpp \
|
||||
FluidMediumManager_Test.cpp
|
||||
FluidMediumManager_Test.cpp \
|
||||
VertexArray_Test.cpp
|
||||
|
||||
HEADERS += \
|
||||
BaseTestCase.h
|
||||
|
@ -51,3 +52,9 @@ else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../render/software/
|
|||
else:unix: LIBS += -L$$OUT_PWD/../render/software/ -lpaysages_render_software
|
||||
INCLUDEPATH += $$PWD/../render/software
|
||||
DEPENDPATH += $$PWD/../render/software
|
||||
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../render/opengl/release/ -lpaysages_render_opengl
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../render/opengl/debug/ -lpaysages_render_opengl
|
||||
else:unix: LIBS += -L$$OUT_PWD/../render/opengl/ -lpaysages_render_opengl
|
||||
INCLUDEPATH += $$PWD/../render/opengl
|
||||
DEPENDPATH += $$PWD/../render/opengl
|
||||
|
|
Loading…
Reference in a new issue