/* Copyright 2005 Nicholas Bishop * * This file is part of SharpConstruct. * * SharpConstruct is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * SharpConstruct is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SharpConstruct; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "Mesh.h" #include "Output3D.hh" #include "OglExt.h" #include using SharpConstruct::Buffer; using SharpConstruct::VBO; Buffer::Buffer( const unsigned type ) : index_( 0 ), type_( type ), count_( 0 ), dsize_( 0 ) {} Buffer::~Buffer() { glDeleteBuffersARB( 1, &index_ ); } void Buffer::Create() { if( index_ == 0 ) glGenBuffersARB( 1, &index_ ); } void Buffer::Initialize( const unsigned count, const unsigned dsize, const unsigned hint ) { count_ = count; dsize_ = dsize; glBufferDataARB( type_, count_ * dsize_, 0, hint ); } void Buffer::Initialize( const unsigned count, const unsigned dsize, const unsigned hint, const void* data ) { count_ = count; dsize_ = dsize; glBufferDataARB( type_, count_ * dsize_, data, hint ); } void Buffer::Bind() const { glBindBufferARB( type_, index_ ); } unsigned Buffer::Count() const { return count_; } VBO::VBO() : vert_norm_color_( GL_ARRAY_BUFFER_ARB ), triangle_( GL_ELEMENT_ARRAY_BUFFER_ARB ), quad_( GL_ELEMENT_ARRAY_BUFFER_ARB ) { glEnableClientState( GL_VERTEX_ARRAY ); glEnableClientState( GL_NORMAL_ARRAY ); glEnableClientState( GL_COLOR_ARRAY ); vert_norm_color_.Create(); triangle_.Create(); quad_.Create(); } bool VBO::IsSupported() { return glexExtensionsSupported( "GL_ARB_vertex_buffer_object" ); } void VBO::Set( const Mesh& mesh, const bool vn, const bool c, const bool p ) { if( p ) { set_vert_norm_color_( mesh, true, true ); set_polygons_( mesh ); } else if( vn || c ) set_vert_norm_color_( mesh, vn, c ); } void VBO::set_vert_norm_color_( const Mesh& mesh, bool vn, bool c ) { using SharpConstruct::Optimized::Point3D; vert_norm_color_.Bind(); const unsigned count( mesh.VisibleElements().Vertices ); if( vert_norm_color_.Count() != count * 3 ) { vert_norm_color_.Initialize( count * 3, sizeof( Point3D ), GL_STREAM_DRAW_ARB ); vn = true; c = true; } if( vn ) { // Load vertex locations... glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, 0, count * sizeof( Point3D ), &mesh.VertexLocations()[ 0 ] ); glVertexPointer( 3, GL_FLOAT, sizeof( Point3D ), 0 ); // Load vertex normals... glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, count * sizeof( Point3D ), count * sizeof( Point3D ), &mesh.VertexNormals()[ 0 ] ); glNormalPointer( GL_FLOAT, sizeof( Point3D ), ( ( char* )NULL + ( count * sizeof( Point3D ) ) ) ); } if( c ) { // Load vertex colors... glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, count * 2 * sizeof( Point3D ), count * sizeof( Color ), &mesh.VertexColors()[ 0 ] ); glColorPointer( 3, GL_FLOAT, sizeof( Color ), ( ( char* )NULL + ( count * 2 * sizeof( Point3D ) ) ) ); } } void VBO::set_polygons_( const Mesh& mesh ) { triangle_.Bind(); triangle_.Initialize( mesh.VisibleElements().Triangles, sizeof( Triangle ), GL_STATIC_DRAW_ARB, &mesh.Triangles()[ 0 ] ); quad_.Bind(); quad_.Initialize( mesh.VisibleElements().Quads, sizeof( Quad ), GL_STATIC_DRAW_ARB, &mesh.Quads()[ 0 ] ); } void VBO::Draw() const { vert_norm_color_.Bind(); triangle_.Bind(); glDrawElements( GL_TRIANGLES, triangle_.Count() * 3, GL_UNSIGNED_INT, 0 ); quad_.Bind(); glDrawElements( GL_QUADS, quad_.Count() * 4, GL_UNSIGNED_INT, 0 ); //glDrawArrays( GL_POINTS, 0, vert_norm_color_.Count() / 3 ); }