#include "Mesh.hpp" namespace renderer { Mesh::Mesh () : mVAO( 0 ), mVBO( 0 ), mEBO( 0 ), mVertexCount( 0 ), mIndexCount( 0 ), mMode( GL_TRIANGLES ) {} Mesh::~Mesh () { if( mVBO ) { glDeleteBuffers( 1, &mVBO ); } if( mEBO ) { glDeleteBuffers( 1, &mEBO ); } if( mVAO ) { glDeleteVertexArrays( 1, &mVAO ); } } bool Mesh::createFromPositions ( const std::vector& positions, bool lines ) { if( positions.empty() ) { return false; } mMode = lines ? GL_LINES : GL_TRIANGLES; mVertexCount = static_cast( positions.size() / 3 ); glGenVertexArrays( 1, &mVAO ); glGenBuffers( 1, &mVBO ); glBindVertexArray( mVAO ); glBindBuffer( GL_ARRAY_BUFFER, mVBO ); glBufferData( GL_ARRAY_BUFFER, positions.size() * sizeof( float ), positions.data(), GL_STATIC_DRAW ); glEnableVertexAttribArray( 0 ); glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof( float ), (void*)0 ); glBindVertexArray( 0 ); return true; } bool Mesh::createFromPosTex ( const std::vector& data ) { if( data.empty() ) return false; const size_t strideFloats = 5; mMode = GL_TRIANGLES; mVertexCount = static_cast( data.size() / strideFloats ); glGenVertexArrays( 1, &mVAO ); glGenBuffers( 1, &mVBO ); glBindVertexArray( mVAO ); glBindBuffer( GL_ARRAY_BUFFER, mVBO ); glBufferData( GL_ARRAY_BUFFER, data.size() * sizeof( float ), data.data(), GL_STATIC_DRAW ); glEnableVertexAttribArray( 0 ); glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ), (void*)0 ); glEnableVertexAttribArray( 1 ); glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ), (void*)( 3 * sizeof( float ) ) ); glBindVertexArray( 0 ); return true; } bool Mesh::createFromPosTexNormal ( const std::vector& data ) { if( data.empty() ) return false; const size_t strideFloats = 8; mMode = GL_TRIANGLES; mVertexCount = static_cast( data.size() / strideFloats ); glGenVertexArrays( 1, &mVAO ); glGenBuffers( 1, &mVBO ); glBindVertexArray( mVAO ); glBindBuffer( GL_ARRAY_BUFFER, mVBO ); glBufferData( GL_ARRAY_BUFFER, data.size() * sizeof( float ), data.data(), GL_STATIC_DRAW ); glEnableVertexAttribArray( 0 ); glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ), (void*)0 ); glEnableVertexAttribArray( 1 ); glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ), (void*)( 3 * sizeof( float ) ) ); glEnableVertexAttribArray( 2 ); glVertexAttribPointer( 2, 3, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ), (void*)( 5 * sizeof( float ) ) ); glBindVertexArray( 0 ); return true; } bool Mesh::createFromPosTexNormalIndexed ( const std::vector& data, const std::vector& indices ) { if( data.empty() || indices.empty() ) return false; const size_t strideFloats = 8; mMode = GL_TRIANGLES; mVertexCount = static_cast( data.size() / strideFloats ); mIndexCount = static_cast( indices.size() ); glGenVertexArrays( 1, &mVAO ); glGenBuffers( 1, &mVBO ); glGenBuffers( 1, &mEBO ); glBindVertexArray( mVAO ); glBindBuffer( GL_ARRAY_BUFFER, mVBO ); glBufferData( GL_ARRAY_BUFFER, data.size() * sizeof( float ), data.data(), GL_STATIC_DRAW ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mEBO ); glBufferData( GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof( unsigned int ), indices.data(), GL_STATIC_DRAW ); glEnableVertexAttribArray( 0 ); glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ), (void*)0 ); glEnableVertexAttribArray( 1 ); glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ), (void*)( 3 * sizeof( float ) ) ); glEnableVertexAttribArray( 2 ); glVertexAttribPointer( 2, 3, GL_FLOAT, GL_FALSE, strideFloats * sizeof( float ), (void*)( 5 * sizeof( float ) ) ); glBindVertexArray( 0 ); return true; } void Mesh::draw () const { if( mVAO == 0 ) return; glBindVertexArray( mVAO ); if( mEBO && mIndexCount > 0 ) { glDrawElements( mMode, mIndexCount, GL_UNSIGNED_INT, 0 ); } else { glDrawArrays( mMode, 0, mVertexCount ); } glBindVertexArray( 0 ); } } // namespace renderer