Skip to content

Commit 629f408

Browse files
committed
[engine] implement vao + indices vbo
1 parent c2548ae commit 629f408

2 files changed

Lines changed: 96 additions & 58 deletions

File tree

src/Engine/Data/Mesh.cpp

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -251,17 +251,49 @@ void GeometryDisplayable::setAttribNameCorrespondence( const std::string& meshAt
251251
m_translationTableMeshToShader[meshAttribName] = shaderAttribName;
252252
}
253253

254-
bool GeometryDisplayable::addRenderLayer( LayerKeyType key ) {
254+
bool GeometryDisplayable::addRenderLayer( LayerKeyType key, base::MeshRenderMode renderMode ) {
255255
if ( !m_geom.containsLayer( key ) ) return false;
256256
auto it = m_geomLayers.find( key );
257257
if ( it == m_geomLayers.end() ) return false;
258+
const auto& abstractLayer = m_geom.getLayer( key );
259+
260+
using LayerType = Ra::Core::Geometry::TriangleIndexLayer;
261+
const auto& triangleLayer = dynamic_cast<const LayerType&>(abstractLayer);
262+
258263

259-
VaoIndices* vao = new VaoIndices;
260264
auto& geomLayer = m_geom.getLayerWithLock( key );
261-
int observerId = geomLayer.attach( VaoIndices::IndicesObserver( vao ) );
265+
/// \fixme Implement observers for indices
266+
//int observerId = geomLayer.attach( VaoIndices::IndicesObserver( vao ) );
267+
int observerId = -1;
262268
m_geom.unlockLayer( key );
263269

264-
m_geomLayers[key] = { observerId, vao };
270+
// create vao
271+
auto &l = m_geomLayers.insert( {key, LayerEntryType()} ).first->second;
272+
l.observerId = observerId;
273+
l.renderMode = renderMode;
274+
l.vao = globjects::VertexArray::create();
275+
276+
// create indices vbo
277+
m_indicesVBOs.push_back( {} );
278+
auto& vbo = m_indicesVBOs.back();
279+
vbo.buffer = globjects::Buffer::create();
280+
vbo.dirty = true;
281+
282+
/// \todo Move to dedicated method
283+
// upload data to gpu
284+
if( vbo.dirty ){
285+
vbo.numElements = triangleLayer.size() * LayerType::IndexType::RowsAtCompileTime;
286+
/// this one do not work since buffer is not a std::vector
287+
vbo.buffer->setData( static_cast<gl::GLsizeiptr>( triangleLayer.size() *
288+
sizeof( LayerType::IndexType ) ),
289+
triangleLayer.collection().data(),
290+
GL_STATIC_DRAW);
291+
vbo.dirty = false;
292+
}
293+
294+
l.vao->bind();
295+
l.vao->bindElementBuffer( vbo.buffer.get() );
296+
l.vao->unbind();
265297

266298
return false;
267299
}
@@ -273,10 +305,10 @@ bool GeometryDisplayable::removeRenderLayer( LayerKeyType key ) {
273305
if ( m_geom.containsLayer( key ) )
274306
{
275307
auto& geomLayer = m_geom.getLayerWithLock( key );
276-
geomLayer.detach( it->second.first );
308+
geomLayer.detach( it->second.observerId );
277309
m_geom.unlockLayer( key );
278310
}
279-
delete ( it->second.second );
311+
it->second.vao.release();
280312
m_geomLayers.erase( it );
281313

282314
return true;
@@ -370,24 +402,24 @@ void GeometryDisplayable::autoVertexAttribPointer( const ShaderProgram* prog ) {
370402
}
371403
}
372404

373-
//void PointCloud::render( const ShaderProgram* prog ) {
374-
// if ( m_vao )
375-
// {
376-
// autoVertexAttribPointer( prog );
377-
// m_vao->bind();
378-
// m_vao->drawArrays(
379-
// static_cast<GLenum>( m_renderMode ), 0, GLsizei( m_mesh.vertices().size() ) );
380-
// m_vao->unbind();
381-
// }
382-
//}
383-
//
384-
//void PointCloud::loadGeometry( Core::Geometry::PointCloud&& mesh ) {
385-
// loadGeometry_common( std::move( mesh ) );
386-
//}
387-
//
388-
//void PointCloud::updateGL_specific_impl() {
389-
// if ( !m_vao ) { m_vao = globjects::VertexArray::create(); }
390-
//}
405+
void PointCloud::render( const ShaderProgram* prog ) {
406+
if ( m_vao )
407+
{
408+
autoVertexAttribPointer( prog );
409+
m_vao->bind();
410+
m_vao->drawArrays(
411+
static_cast<GLenum>( m_renderMode ), 0, GLsizei( m_mesh.vertices().size() ) );
412+
m_vao->unbind();
413+
}
414+
}
415+
416+
void PointCloud::loadGeometry( Core::Geometry::PointCloud&& mesh ) {
417+
loadGeometry_common( std::move( mesh ) );
418+
}
419+
420+
void PointCloud::updateGL_specific_impl() {
421+
if ( !m_vao ) { m_vao = globjects::VertexArray::create(); }
422+
}
391423

392424
} // namespace Data
393425
} // namespace Engine

src/Engine/Data/Mesh.hpp

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ class RA_ENGINE_API AttribArrayDisplayable : public Displayable
8888
};
8989

9090
public:
91-
explicit AttribArrayDisplayable( const std::string& name );
92-
//, MeshRenderMode renderMode = RM_TRIANGLES
91+
explicit AttribArrayDisplayable( const std::string& name ,
92+
MeshRenderMode renderMode = RM_TRIANGLES);
9393

9494
AttribArrayDisplayable( const AttribArrayDisplayable& rhs ) = delete;
9595
void operator=( const AttribArrayDisplayable& rhs ) = delete;
@@ -99,10 +99,10 @@ class RA_ENGINE_API AttribArrayDisplayable : public Displayable
9999

100100
using Displayable::getName;
101101

102-
// /// Set the render mode.
103-
// inline void setRenderMode( MeshRenderMode mode );
104-
// /// Get the render mode.
105-
// inline MeshRenderMode getRenderMode() const;
102+
/// Set the render mode.
103+
inline void setRenderMode( MeshRenderMode mode );
104+
/// Get the render mode.
105+
inline MeshRenderMode getRenderMode() const;
106106

107107
/// @name
108108
/// Mark attrib data as dirty, forcing an update of the OpenGL buffer.
@@ -165,7 +165,7 @@ class RA_ENGINE_API AttribArrayDisplayable : public Displayable
165165
protected:
166166
std::unique_ptr<globjects::VertexArray> m_vao;
167167

168-
// MeshRenderMode m_renderMode { MeshRenderMode::RM_TRIANGLES };
168+
MeshRenderMode m_renderMode { MeshRenderMode::RM_TRIANGLES };
169169

170170
// m_vbos and m_dataDirty have the same size and are indexed thru m_handleToBuffer[attribName]
171171
std::vector<std::unique_ptr<globjects::Buffer>> m_vbos;
@@ -293,27 +293,27 @@ class CoreGeometryDisplayable : public AttribArrayDisplayable
293293
};
294294

295295
/// A PointCloud without indices
296-
// class RA_ENGINE_API PointCloud : public CoreGeometryDisplayable<Core::Geometry::PointCloud>
297-
//{
298-
// using base = CoreGeometryDisplayable<Core::Geometry::PointCloud>;
299-
//
300-
// public:
301-
// using base::CoreGeometryDisplayable;
302-
// inline explicit PointCloud(
303-
// const std::string& name,
304-
// typename base::CoreGeometry&& geom,
305-
// typename base::MeshRenderMode renderMode = base::MeshRenderMode::RM_POINTS );
306-
//
307-
// inline explicit PointCloud( const std::string& name, MeshRenderMode renderMode = RM_POINTS );
308-
//
309-
// /// use glDrawArrays to draw all the points in the point cloud
310-
// void render( const ShaderProgram* prog ) override;
311-
//
312-
// void loadGeometry( Core::Geometry::PointCloud&& mesh ) override;
313-
//
314-
// protected:
315-
// void updateGL_specific_impl() override;
316-
// };
296+
class RA_ENGINE_API PointCloud : public CoreGeometryDisplayable<Core::Geometry::PointCloud>
297+
{
298+
using base = CoreGeometryDisplayable<Core::Geometry::PointCloud>;
299+
300+
public:
301+
using base::CoreGeometryDisplayable;
302+
inline explicit PointCloud(
303+
const std::string& name,
304+
typename base::CoreGeometry&& geom,
305+
typename base::MeshRenderMode renderMode = base::MeshRenderMode::RM_POINTS );
306+
307+
inline explicit PointCloud( const std::string& name, MeshRenderMode renderMode = RM_POINTS );
308+
309+
/// use glDrawArrays to draw all the points in the point cloud
310+
void render( const ShaderProgram* prog ) override;
311+
312+
void loadGeometry( Core::Geometry::PointCloud&& mesh ) override;
313+
314+
protected:
315+
void updateGL_specific_impl() override;
316+
};
317317

318318
/// An engine mesh owning CoreGeometry, with indices
319319
template <typename T>
@@ -369,18 +369,20 @@ class RA_ENGINE_API GeometryDisplayable : public AttribArrayDisplayable
369369
const std::string& shaderAttribName );
370370

371371
void loadGeometry( Core::Geometry::MultiIndexedGeometry&& mesh );
372-
inline void loadGeometry( Core::Geometry::MultiIndexedGeometry&& mesh, LayerKeyType key ) {
372+
inline void loadGeometry( Core::Geometry::MultiIndexedGeometry&& mesh, LayerKeyType key, base::MeshRenderMode renderMode ) {
373373
loadGeometry( std::move( mesh ) );
374-
addRenderLayer( key );
374+
addRenderLayer( key, renderMode );
375375
}
376+
377+
/// \param r is a collection of keys and renderMode, e.g. { {key1, RM_TRIANGLES}, {key2, RM_LINES} }
376378
template <typename RangeOfLayerKeys>
377379
inline void loadGeometry( Core::Geometry::MultiIndexedGeometry&& mesh,
378380
const RangeOfLayerKeys& r ) {
379381
loadGeometry( std::move( mesh ) );
380382
for ( const auto& k : r )
381-
addRenderLayer( k );
383+
addRenderLayer( k.first, k.second );
382384
}
383-
bool addRenderLayer( LayerKeyType key );
385+
bool addRenderLayer( LayerKeyType key, base::MeshRenderMode renderMode );
384386
bool removeRenderLayer( LayerKeyType key );
385387
// bool setRenderMode( LayerKeyType key, RenderMode );
386388
// RenderMode getRenderMode( LayerKeyType key );
@@ -403,17 +405,21 @@ class RA_ENGINE_API GeometryDisplayable : public AttribArrayDisplayable
403405
Core::Geometry::MultiIndexedGeometry m_geom;
404406

405407
/// Data required to configure rendering for each layer
408+
/// \note In the current version, do not know which VBOEntryType is associated to this vao:
409+
/// there is no way to clean m_indicesVBOs when a LayerEntryType is removed.
406410
struct LayerEntryType {
407411
int observerId { -1 };
408-
globjects::VertexArray vao {};
412+
std::unique_ptr<globjects::VertexArray> vao {nullptr};
409413
base::MeshRenderMode renderMode { RM_TRIANGLES };
414+
415+
inline LayerEntryType () = default;
410416
};
411417
std::unordered_map<LayerKeyType, LayerEntryType, LayerKeyHash> m_geomLayers;
412418

413419
/// Data required to store and used VBOs
414420
struct VBOEntryType {
415421
bool dirty { false };
416-
globjects::Buffer buffer {};
422+
std::unique_ptr<globjects::Buffer> buffer { nullptr };
417423
size_t numElements { 0 };
418424
};
419425
using VBOCollection = std::vector<VBOEntryType>;

0 commit comments

Comments
 (0)