Skip to content

Commit 1e88873

Browse files
committed
[engine] GeometryDisplayable works, for HelloRadium.
1 parent 4240f7f commit 1e88873

2 files changed

Lines changed: 82 additions & 107 deletions

File tree

src/Engine/Data/Mesh.cpp

Lines changed: 62 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,24 @@ void AttribArrayDisplayable::setDirty( const Ra::Core::Geometry::MeshAttrib& typ
153153

154154
GeometryDisplayable::GeometryDisplayable( const std::string& name,
155155
typename Core::Geometry::MultiIndexedGeometry&& geom ) :
156-
base( name ), m_geom( std::move( geom ) ) {}
156+
base( name ) {
157+
loadGeometry( std::move( geom ) );
158+
}
157159

158160
GeometryDisplayable::~GeometryDisplayable() {}
159161

160162
void GeometryDisplayable::loadGeometry( Core::Geometry::MultiIndexedGeometry&& mesh ) {
161163
m_geomLayers.clear();
162164
m_geom = std::move( mesh );
163165
setupCoreMeshObservers();
166+
167+
/// \todo check if other layer ? at least triangulate
168+
if ( m_geom.containsLayer( Core::Geometry::TriangleIndexLayer::staticSemanticName ) ) {
169+
auto [key, layer] = m_geom.getFirstLayerOccurrence(
170+
Core::Geometry::TriangleIndexLayer::staticSemanticName );
171+
addRenderLayer( key, AttribArrayDisplayable::RM_TRIANGLES );
172+
}
173+
m_isDirty = true;
164174
}
165175

166176
void GeometryDisplayable::setupCoreMeshObservers() {
@@ -244,48 +254,15 @@ void GeometryDisplayable::setAttribNameCorrespondence( const std::string& meshAt
244254
bool GeometryDisplayable::addRenderLayer( LayerKeyType key, base::MeshRenderMode renderMode ) {
245255
if ( !m_geom.containsLayer( key ) ) return false;
246256
auto it = m_geomLayers.find( key );
247-
if ( it == m_geomLayers.end() ) return false;
248-
const auto& abstractLayer = m_geom.getLayer( key );
257+
if ( it != m_geomLayers.end() ) return false;
249258

250-
using LayerType = Ra::Core::Geometry::TriangleIndexLayer;
251-
const auto& triangleLayer = dynamic_cast<const LayerType&>( abstractLayer );
259+
m_activeLayerKey = key;
260+
auto& l = m_geomLayers.insert( { m_activeLayerKey, LayerEntryType() } ).first->second;
252261

253-
auto& geomLayer = m_geom.getLayerWithLock( key );
254-
/// \fixme Implement observers for indices
255-
// int observerId = geomLayer.attach( VaoIndices::IndicesObserver( vao ) );
256-
int observerId = -1;
257-
m_geom.unlockLayer( key );
258-
259-
// create vao
260-
auto& l = m_geomLayers.insert( { key, LayerEntryType() } ).first->second;
261-
l.observerId = observerId;
262+
l.observerId = -1;
262263
l.renderMode = renderMode;
263-
l.vao = globjects::VertexArray::create();
264-
265-
// create indices vbo
266-
m_indicesVBOs.push_back( {} );
267-
auto& vbo = m_indicesVBOs.back();
268-
vbo.buffer = globjects::Buffer::create();
269-
vbo.dirty = true;
270-
271-
/// \todo Move to dedicated method
272-
// upload data to gpu
273-
if ( vbo.dirty ) {
274-
// vbo.numElements = triangleLayer.getSize() *
275-
// LayerType::IndexType::RowsAtCompileTime;
276-
/// this one do not work since buffer is not a std::vector
277-
vbo.buffer->setData(
278-
static_cast<gl::GLsizeiptr>( triangleLayer.getSize() * sizeof( LayerType::IndexType ) ),
279-
triangleLayer.collection().data(),
280-
GL_STATIC_DRAW );
281-
vbo.dirty = false;
282-
}
283-
284-
l.vao->bind();
285-
l.vao->bindElementBuffer( vbo.buffer.get() );
286-
l.vao->unbind();
287264

288-
return false;
265+
return true;
289266
}
290267

291268
bool GeometryDisplayable::removeRenderLayer( LayerKeyType key ) {
@@ -298,21 +275,43 @@ bool GeometryDisplayable::removeRenderLayer( LayerKeyType key ) {
298275
geomLayer.detach( it->second.observerId );
299276
m_geom.unlockLayer( key );
300277
}
301-
it->second.vao.release();
278+
it->second.vao.reset();
302279
m_geomLayers.erase( it );
303280

304281
return true;
305282
}
306283

307284
void GeometryDisplayable::updateGL() {
308285
if ( m_isDirty ) {
309-
// Check that our dirty bits are consistent.
310-
ON_ASSERT( bool dirtyTest = false; for ( auto d
311-
: m_dataDirty ) { dirtyTest = dirtyTest || d; } );
312-
CORE_ASSERT( dirtyTest == m_isDirty, "Dirty flags inconsistency" );
313-
CORE_ASSERT( !( m_geom.vertices().empty() ), "No vertex." );
314286

315-
updateGL_specific_impl();
287+
const auto& abstractLayer = m_geom.getLayerWithLock( m_activeLayerKey );
288+
using LayerType = Ra::Core::Geometry::TriangleIndexLayer;
289+
const auto& triangleLayer = dynamic_cast<const LayerType&>( abstractLayer );
290+
// create vao
291+
auto& l = m_geomLayers[m_activeLayerKey];
292+
if ( !l.vao ) { l.vao = globjects::VertexArray::create(); }
293+
294+
auto& vbo = l.indices;
295+
if ( !vbo.buffer ) {
296+
vbo.buffer = globjects::Buffer::create();
297+
vbo.dirty = true;
298+
vbo.numElements = triangleLayer.getSize() * triangleLayer.getNumberOfComponents();
299+
}
300+
301+
// upload data to gpu
302+
if ( vbo.dirty ) {
303+
vbo.buffer->setData( static_cast<gl::GLsizeiptr>( triangleLayer.getSize() *
304+
sizeof( LayerType::IndexType ) ),
305+
triangleLayer.collection().data(),
306+
GL_STATIC_DRAW );
307+
vbo.dirty = false;
308+
}
309+
m_geom.unlockLayer( m_activeLayerKey );
310+
311+
l.vao->bind();
312+
l.vao->bindElementBuffer( vbo.buffer.get() );
313+
l.vao->unbind();
314+
GL_CHECK_ERROR;
316315

317316
auto func = [this]( Ra::Core::Utils::AttribBase* b ) {
318317
auto idx = m_handleToBuffer[b->getName()];
@@ -341,52 +340,18 @@ void GeometryDisplayable::updateGL() {
341340
}
342341
}
343342

344-
void GeometryDisplayable::updateGL_specific_impl() {
345-
CORE_ASSERT( false, "not implemented yet" );
346-
// if ( !m_indices )
347-
// {
348-
// m_indices = globjects::Buffer::create();
349-
// m_indicesDirty = true;
350-
// }
351-
// if ( m_indicesDirty )
352-
// {
353-
// /// this one do not work since m_indices is not a std::vector
354-
// // m_indices->setData( m_mesh.m_indices, GL_DYNAMIC_DRAW );
355-
// m_numElements =
356-
// base::m_mesh.getIndices().size() *
357-
// base::CoreGeometry::IndexType::RowsAtCompileTime;
358-
//
359-
// m_indices->setData(
360-
// static_cast<gl::GLsizeiptr>( base::m_mesh.getIndices().size() *
361-
// sizeof( typename base::CoreGeometry::IndexType ) ),
362-
// base::m_mesh.getIndices().data(),
363-
// GL_STATIC_DRAW );
364-
// m_indicesDirty = false;
365-
// }
366-
// if ( !base::m_vao ) { base::m_vao = globjects::VertexArray::create(); }
367-
// base::m_vao->bind();
368-
// base::m_vao->bindElementBuffer( m_indices.get() );
369-
// base::m_vao->unbind();
370-
/// \todo implement !
371-
}
372-
373-
void GeometryDisplayable::render( const ShaderProgram* ) {
374-
CORE_ASSERT( false, "not implemented yet" );
375-
// if ( base::m_vao )
376-
// {
377-
// GL_CHECK_ERROR;
378-
// base::m_vao->bind();
379-
// base::autoVertexAttribPointer( prog );
380-
// GL_CHECK_ERROR;
381-
// base::m_vao->drawElements( static_cast<GLenum>( base::m_renderMode ),
382-
// GLsizei( m_numElements ),
383-
// GL_UNSIGNED_INT,
384-
// nullptr );
385-
// GL_CHECK_ERROR;
386-
// base::m_vao->unbind();
387-
// GL_CHECK_ERROR;
388-
// }
389-
/// \todo implement !
343+
void GeometryDisplayable::render( const ShaderProgram* prog ) {
344+
if ( m_geomLayers[m_activeLayerKey].vao ) {
345+
m_geomLayers[m_activeLayerKey].vao->bind();
346+
autoVertexAttribPointer( prog );
347+
m_geomLayers[m_activeLayerKey].vao->drawElements(
348+
static_cast<GLenum>( base::m_renderMode ),
349+
GLsizei( m_geomLayers[m_activeLayerKey].indices.numElements ),
350+
GL_UNSIGNED_INT,
351+
nullptr );
352+
m_geomLayers[m_activeLayerKey].vao->unbind();
353+
GL_CHECK_ERROR;
354+
}
390355
}
391356

392357
void GeometryDisplayable::autoVertexAttribPointer( const ShaderProgram* prog ) {
@@ -407,8 +372,9 @@ void GeometryDisplayable::autoVertexAttribPointer( const ShaderProgram* prog ) {
407372
auto attrib = m_geom.getAttribBase( attribName );
408373

409374
if ( attrib && attrib->getSize() > 0 ) {
410-
m_vao->enable( loc );
411-
auto binding = m_vao->binding( idx );
375+
m_geomLayers[m_activeLayerKey].vao->enable( loc );
376+
auto binding = m_geomLayers[m_activeLayerKey].vao->binding( idx );
377+
412378
binding->setAttribute( loc );
413379
CORE_ASSERT( m_vbos[m_handleToBuffer[attribName]].get(), "vbo is nullptr" );
414380
#ifdef CORE_USE_DOUBLE
@@ -423,9 +389,10 @@ void GeometryDisplayable::autoVertexAttribPointer( const ShaderProgram* prog ) {
423389
binding->setFormat( attrib->getNumberOfComponents(), GL_SCALAR );
424390
}
425391
else {
426-
m_vao->disable( loc );
392+
m_geomLayers[m_activeLayerKey].vao->disable( loc );
427393
}
428394
}
395+
GL_CHECK_ERROR;
429396
}
430397

431398
Ra::Core::Utils::optional<gl::GLuint> AttribArrayDisplayable::getVaoHandle() {

src/Engine/Data/Mesh.hpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,6 @@ class RA_ENGINE_API GeometryDisplayable : public AttribArrayDisplayable
399399
void updateGL() override;
400400

401401
protected:
402-
void updateGL_specific_impl();
403402
void setupCoreMeshObservers();
404403

405404
/// assume m_vao is bound.
@@ -415,29 +414,38 @@ class RA_ENGINE_API GeometryDisplayable : public AttribArrayDisplayable
415414
private:
416415
Core::Geometry::MultiIndexedGeometry m_geom;
417416

418-
/// Data required to configure rendering for each layer
419-
/// \note In the current version, do not know which VBOEntryType is associated to this vao:
420-
/// there is no way to clean m_indicesVBOs when a LayerEntryType is removed.
417+
// for vertex attribs, with dirty
418+
struct VBOEntryType {
419+
bool dirty { false };
420+
std::unique_ptr<globjects::Buffer> buffer { nullptr };
421+
};
422+
423+
// for indices, with dirty and num elements
424+
struct IndicesVBO {
425+
bool dirty { false };
426+
std::unique_ptr<globjects::Buffer> buffer { nullptr };
427+
size_t numElements { 0 };
428+
};
429+
430+
/// LayerKey with it's corresponding indices.
421431
struct LayerEntryType {
422432
int observerId { -1 };
423433
std::unique_ptr<globjects::VertexArray> vao { nullptr };
434+
IndicesVBO indices;
424435
base::MeshRenderMode renderMode { RM_TRIANGLES };
425436

426437
inline LayerEntryType() = default;
427438
};
439+
440+
/// The collection of indices layer we can use for rendering
428441
std::unordered_map<LayerKeyType, LayerEntryType, LayerKeyHash> m_geomLayers;
429442

430-
/// Data required to store and used VBOs
431-
struct VBOEntryType {
432-
bool dirty { false };
433-
std::unique_ptr<globjects::Buffer> buffer { nullptr };
434-
size_t numElements { 0 };
435-
};
443+
/// "main" triangle layer
444+
LayerKeyType m_activeLayerKey;
445+
436446
using VBOCollection = std::vector<VBOEntryType>;
437447
/// Collection of VBOs for per-vertex attributes
438448
VBOCollection m_attribVBOs;
439-
/// Collection of VBOs for each layer indices
440-
VBOCollection m_indicesVBOs;
441449

442450
using TranslationTable = std::map<std::string, std::string>;
443451
TranslationTable m_translationTableMeshToShader;

0 commit comments

Comments
 (0)