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 "CameraDefinition.h"
|
||||||
#include "OpenGLRenderer.h"
|
#include "OpenGLRenderer.h"
|
||||||
#include "TerrainRenderer.h"
|
#include "TerrainRenderer.h"
|
||||||
|
#include "VertexArray.h"
|
||||||
|
|
||||||
ExplorerChunkTerrain::ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, double z, double size, int nbchunks, double water_height):
|
ExplorerChunkTerrain::ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, double z, double size, int nbchunks, double water_height):
|
||||||
_renderer(renderer)
|
_renderer(renderer)
|
||||||
|
@ -33,8 +34,11 @@ ExplorerChunkTerrain::ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, d
|
||||||
_water_height = water_height;
|
_water_height = water_height;
|
||||||
_overwater = false;
|
_overwater = false;
|
||||||
|
|
||||||
_tessellation_max_size = 32;
|
tessellation_count = 33;
|
||||||
_tessellation = new double[(_tessellation_max_size + 1) * (_tessellation_max_size + 1)];
|
tessellated = new VertexArray<TerrainVertex>();
|
||||||
|
tessellated->setGridSize(tessellation_count);
|
||||||
|
tessellated->setAutoGridIndices(tessellation_count);
|
||||||
|
_tessellation_max_size = tessellation_count - 1;
|
||||||
_tessellation_current_size = 0;
|
_tessellation_current_size = 0;
|
||||||
_tessellation_step = _size / (double) _tessellation_max_size;
|
_tessellation_step = _size / (double) _tessellation_max_size;
|
||||||
|
|
||||||
|
@ -49,7 +53,7 @@ ExplorerChunkTerrain::~ExplorerChunkTerrain()
|
||||||
delete _color_profile;
|
delete _color_profile;
|
||||||
delete _texture;
|
delete _texture;
|
||||||
delete texture;
|
delete texture;
|
||||||
delete [] _tessellation;
|
delete tessellated;
|
||||||
_lock_data.unlock();
|
_lock_data.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,24 +120,39 @@ bool ExplorerChunkTerrain::onMaintainEvent()
|
||||||
int new_tessellation_size = _tessellation_current_size ? _tessellation_current_size * 4 : 2;
|
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 old_tessellation_inc = _tessellation_current_size ? _tessellation_max_size / _tessellation_current_size : 1;
|
||||||
int new_tessellation_inc = _tessellation_max_size / new_tessellation_size;
|
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 j = 0; j <= _tessellation_max_size; j += new_tessellation_inc)
|
||||||
{
|
{
|
||||||
for (int i = 0; i <= _tessellation_max_size; i += 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)
|
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)
|
if (height >= _water_height)
|
||||||
{
|
{
|
||||||
_overwater = true;
|
_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();
|
_lock_data.lock();
|
||||||
_tessellation_current_size = new_tessellation_size;
|
_tessellation_current_size = new_tessellation_size;
|
||||||
|
tessellated->setAutoGridIndices(tessellation_count, new_tessellation_inc);
|
||||||
_lock_data.unlock();
|
_lock_data.unlock();
|
||||||
|
|
||||||
if (_tessellation_current_size < 4 && _tessellation_current_size < _tessellation_max_size)
|
if (_tessellation_current_size < 4 && _tessellation_current_size < _tessellation_max_size)
|
||||||
|
@ -216,7 +235,6 @@ void ExplorerChunkTerrain::render(OpenGLFunctions* functions)
|
||||||
{
|
{
|
||||||
_lock_data.lock();
|
_lock_data.lock();
|
||||||
int tessellation_size = _tessellation_current_size;
|
int tessellation_size = _tessellation_current_size;
|
||||||
double tsize = 1.0 / (double) _tessellation_max_size;
|
|
||||||
_lock_data.unlock();
|
_lock_data.unlock();
|
||||||
|
|
||||||
if (tessellation_size <= 1 or not _overwater)
|
if (tessellation_size <= 1 or not _overwater)
|
||||||
|
@ -224,19 +242,17 @@ void ExplorerChunkTerrain::render(OpenGLFunctions* functions)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tessellation_inc = _tessellation_max_size / (double) tessellation_size;
|
_lock_data.lock(); // TEMP
|
||||||
for (int j = 0; j < _tessellation_max_size; j += tessellation_inc)
|
int n = tessellated->getIndexCount();
|
||||||
|
functions->glBegin(GL_TRIANGLES);
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
functions->glBegin(GL_QUAD_STRIP);
|
TerrainVertex v = tessellated->getVertexByIndex(i);
|
||||||
for (int i = 0; i <= _tessellation_max_size; i += tessellation_inc)
|
functions->glTexCoord2d(v.uv[0], v.uv[1]);
|
||||||
{
|
functions->glVertex3d(v.location[0], v.location[1], v.location[2]);
|
||||||
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));
|
|
||||||
}
|
|
||||||
functions->glEnd();
|
|
||||||
}
|
}
|
||||||
|
functions->glEnd();
|
||||||
|
_lock_data.unlock(); // TEMP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,13 @@ namespace opengl {
|
||||||
|
|
||||||
class OPENGLSHARED_EXPORT ExplorerChunkTerrain
|
class OPENGLSHARED_EXPORT ExplorerChunkTerrain
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float location[3];
|
||||||
|
float uv[2];
|
||||||
|
} TerrainVertex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, double z, double size, int nbchunks, double water_height);
|
ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, double z, double size, int nbchunks, double water_height);
|
||||||
~ExplorerChunkTerrain();
|
~ExplorerChunkTerrain();
|
||||||
|
@ -41,7 +48,8 @@ private:
|
||||||
double _water_height;
|
double _water_height;
|
||||||
bool _overwater;
|
bool _overwater;
|
||||||
|
|
||||||
double* _tessellation;
|
int tessellation_count;
|
||||||
|
VertexArray<TerrainVertex> *tessellated;
|
||||||
int _tessellation_max_size;
|
int _tessellation_max_size;
|
||||||
int _tessellation_current_size;
|
int _tessellation_current_size;
|
||||||
double _tessellation_step;
|
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 \
|
OpenGLWater.cpp \
|
||||||
OpenGLSharedState.cpp \
|
OpenGLSharedState.cpp \
|
||||||
OpenGLVariable.cpp \
|
OpenGLVariable.cpp \
|
||||||
OpenGLTerrain.cpp
|
OpenGLTerrain.cpp \
|
||||||
|
VertexArray.cpp
|
||||||
|
|
||||||
HEADERS +=\
|
HEADERS +=\
|
||||||
opengl_global.h \
|
opengl_global.h \
|
||||||
|
@ -36,7 +37,8 @@ HEADERS +=\
|
||||||
OpenGLWater.h \
|
OpenGLWater.h \
|
||||||
OpenGLSharedState.h \
|
OpenGLSharedState.h \
|
||||||
OpenGLVariable.h \
|
OpenGLVariable.h \
|
||||||
OpenGLTerrain.h
|
OpenGLTerrain.h \
|
||||||
|
VertexArray.h
|
||||||
|
|
||||||
unix:!symbian {
|
unix:!symbian {
|
||||||
maemo5 {
|
maemo5 {
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace opengl {
|
||||||
class OpenGLWater;
|
class OpenGLWater;
|
||||||
class OpenGLTerrain;
|
class OpenGLTerrain;
|
||||||
class ExplorerChunkTerrain;
|
class ExplorerChunkTerrain;
|
||||||
|
template <typename Vertex> class VertexArray;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
using namespace paysages::opengl;
|
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 \
|
Bruneton_Test.cpp \
|
||||||
Camera_Test.cpp \
|
Camera_Test.cpp \
|
||||||
Clouds_Test.cpp \
|
Clouds_Test.cpp \
|
||||||
FluidMediumManager_Test.cpp
|
FluidMediumManager_Test.cpp \
|
||||||
|
VertexArray_Test.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
BaseTestCase.h
|
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
|
else:unix: LIBS += -L$$OUT_PWD/../render/software/ -lpaysages_render_software
|
||||||
INCLUDEPATH += $$PWD/../render/software
|
INCLUDEPATH += $$PWD/../render/software
|
||||||
DEPENDPATH += $$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