1 #include <Engine/Data/Mesh.hpp>
5 #include <Core/Utils/Attribs.hpp>
6 #include <Core/Utils/Log.hpp>
7 #include <Engine/Data/ShaderProgram.hpp>
8 #include <Engine/OpenGL.hpp>
10 #include <globjects/Buffer.h>
11 #include <globjects/VertexArray.h>
16 using namespace Ra::Core::Utils;
20 AttribArrayDisplayable::AttribArrayDisplayable(
const std::string& name,
21 MeshRenderMode renderMode ) :
22 Displayable( name ), m_renderMode { renderMode } {
23 CORE_ASSERT( m_renderMode == RM_POINTS || m_renderMode == RM_LINES ||
24 m_renderMode == RM_LINE_LOOP || m_renderMode == RM_LINE_STRIP ||
25 m_renderMode == RM_TRIANGLES || m_renderMode == RM_TRIANGLE_STRIP ||
26 m_renderMode == RM_TRIANGLE_FAN || m_renderMode == RM_LINES_ADJACENCY ||
27 m_renderMode == RM_LINE_STRIP_ADJACENCY,
28 "Unsupported render mode" );
30 updatePickingRenderMode();
33 size_t Mesh::getNumFaces()
const {
35 switch ( getRenderMode() ) {
36 case MeshRenderMode::RM_TRIANGLE_STRIP:
38 case MeshRenderMode::RM_TRIANGLE_FAN:
39 return ( getCoreGeometry().getIndices().size() - 1 ) * 3 + 1;
40 case MeshRenderMode::RM_TRIANGLES:
41 return getCoreGeometry().getIndices().size();
47 void Mesh::loadGeometry(
const Core::Vector3Array& vertices,
const std::vector<uint>& indices ) {
51 Core::Geometry::TriangleMesh mesh;
53 auto nIdx = indices.size();
55 if ( indices.empty() ) {
56 m_numElements = vertices.size();
57 setRenderMode( RM_POINTS );
61 mesh.setVertices( vertices );
64 CORE_ASSERT( m_renderMode != GL_TRIANGLES || nIdx % 3 == 0,
65 "There should be 3 indices per triangle " );
66 CORE_ASSERT( m_renderMode != GL_LINES || nIdx % 2 == 0,
"There should be 2 indices per line" );
67 CORE_ASSERT( m_renderMode != GL_LINES_ADJACENCY || nIdx % 4 == 0,
68 "There should be 4 indices per line adjacency" );
70 for ( uint i = 0; i < indices.size(); i = i + 3 ) {
73 mindices.push_back( { indices[i], indices[( i + 1 ) % nIdx], indices[( i + 2 ) % nIdx] } );
76 mesh.setIndices( std::move( mindices ) );
81 loadGeometry( std::move( mesh ) );
84 void AttribArrayDisplayable::updatePickingRenderMode() {
85 switch ( getRenderMode() ) {
86 case AttribArrayDisplayable::RM_POINTS: {
87 Displayable::m_pickingRenderMode = PKM_POINTS;
90 case AttribArrayDisplayable::RM_LINES:
92 case AttribArrayDisplayable::RM_LINE_LOOP:
94 case AttribArrayDisplayable::RM_LINE_STRIP: {
95 Displayable::m_pickingRenderMode = PKM_LINES;
98 case AttribArrayDisplayable::RM_LINES_ADJACENCY:
100 case AttribArrayDisplayable::RM_LINE_STRIP_ADJACENCY: {
101 Displayable::m_pickingRenderMode = PKM_LINE_ADJ;
104 case AttribArrayDisplayable::RM_TRIANGLES:
106 case AttribArrayDisplayable::RM_TRIANGLE_STRIP:
108 case AttribArrayDisplayable::RM_TRIANGLE_FAN: {
109 Displayable::m_pickingRenderMode = PKM_TRI;
113 Displayable::m_pickingRenderMode = NO_PICKING;
119 void AttribArrayDisplayable::setDirty(
const std::string& name ) {
120 auto itr = m_handleToBuffer.find( name );
121 if ( itr == m_handleToBuffer.end() ) {
122 m_handleToBuffer[name] = m_dataDirty.size();
123 m_dataDirty.push_back(
true );
124 m_vbos.emplace_back(
nullptr );
127 m_dataDirty[itr->second] =
true;
132 void AttribArrayDisplayable::setDirty(
unsigned int index ) {
133 if ( index < m_dataDirty.size() ) {
134 m_dataDirty[index] =
true;
139 void AttribArrayDisplayable::setDirty(
const Ra::Core::Geometry::MeshAttrib& type ) {
140 auto name = Core::Geometry::getAttribName( type );
141 auto itr = m_handleToBuffer.find( name );
142 if ( itr == m_handleToBuffer.end() ) {
143 m_handleToBuffer[name] = m_dataDirty.size();
144 m_dataDirty.push_back(
true );
145 m_vbos.emplace_back(
nullptr );
148 m_dataDirty[itr->second] =
true;
153 Ra::Core::Utils::optional<gl::GLuint> AttribArrayDisplayable::getVaoHandle() {
154 if ( m_vao )
return m_vao->id();
157 Ra::Core::Utils::optional<gl::GLuint>
158 AttribArrayDisplayable::getVboHandle(
const std::string& name ) {
159 auto idx = m_handleToBuffer.find( name );
160 if ( idx != m_handleToBuffer.end() && m_vbos[idx->second] )
return m_vbos[idx->second]->id();
166 autoVertexAttribPointer( prog );
169 static_cast<GLenum
>( m_renderMode ), 0, GLsizei( m_mesh.vertices().size() ) );
174 void PointCloud::loadGeometry( Core::Geometry::PointCloud&& mesh ) {
175 loadGeometry_common( std::move( mesh ) );
178 void PointCloud::updateGL_specific_impl() {
179 if ( !m_vao ) { m_vao = globjects::VertexArray::create(); }