Commit d5a2b1f4 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

introducing IndexedMeshGeometry

parent 3aa094f7
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitt Mnchen
// Boltzmannstr. 3, 85748 Garching b. Mnchen, Germany
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#include "indexedmeshgeometry.h"
#include "tgt/assert.h"
#include "tgt/logmanager.h"
#include "tgt/buffer.h"
#include "tgt/vertexarrayobject.h"
#include <algorithm>
#include <list>
#include <utility>
namespace campvis {
const std::string IndexedMeshGeometry::loggerCat_ = "CAMPVis.core.datastructures.IndexedMeshGeometry";
IndexedMeshGeometry::IndexedMeshGeometry(
const std::vector<uint16_t>& indices,
const std::vector<tgt::vec3>& vertices,
const std::vector<tgt::vec3>& textureCoordinates /*= std::vector<tgt::vec3>()*/,
const std::vector<tgt::vec4>& colors /*= std::vector<tgt::vec4>()*/,
const std::vector<tgt::vec3>& normals /*= std::vector<tgt::vec3>() */)
: GeometryData()
, _indices(indices)
, _vertices(vertices)
, _textureCoordinates(textureCoordinates)
, _colors(colors)
, _normals(normals)
, _indicesBuffer(0)
{
tgtAssert(textureCoordinates.empty() || textureCoordinates.size() == vertices.size(), "Texture coordinates vector must be either empty or of the same size as the vertex vector.");
tgtAssert(colors.empty() || colors.size() == vertices.size(), "Colors vector must be either empty or of the same size as the vertex vector.");
tgtAssert(normals.empty() || normals.size() == vertices.size(), "Normals vector must be either empty or of the same size as the vertex vector.");
}
IndexedMeshGeometry::~IndexedMeshGeometry() {
}
IndexedMeshGeometry* IndexedMeshGeometry::clone() const {
return new IndexedMeshGeometry(_indices, _vertices, _textureCoordinates, _colors, _normals);
}
size_t IndexedMeshGeometry::getLocalMemoryFootprint() const {
size_t sum = 0;
if (_indicesBuffer != 0)
sum += sizeof(tgt::BufferObject);
if (_verticesBuffer != 0)
sum += sizeof(tgt::BufferObject);
if (_texCoordsBuffer != 0)
sum += sizeof(tgt::BufferObject);
if (_colorsBuffer != 0)
sum += sizeof(tgt::BufferObject);
if (_normalsBuffer != 0)
sum += sizeof(tgt::BufferObject);
return sizeof(*this) + sum + (sizeof(size_t) * _indices.size()) + (sizeof(tgt::vec3) * (_vertices.size() + _textureCoordinates.size() + _normals.size())) + (sizeof(tgt::vec4) * _colors.size());
}
size_t IndexedMeshGeometry::getVideoMemoryFootprint() const {
return GeometryData::getVideoMemoryFootprint() + (_indicesBuffer == 0 ? 0 : _indicesBuffer->getBufferSize());
}
void IndexedMeshGeometry::render(GLenum mode) const {
createGLBuffers();
if (! _buffersInitialized) {
LERROR("Cannot render without initialized OpenGL buffers.");
return;
}
tgt::VertexArrayObject vao;
if (_verticesBuffer)
vao.addVertexAttribute(tgt::VertexArrayObject::VerticesAttribute, _verticesBuffer);
if (_texCoordsBuffer)
vao.addVertexAttribute(tgt::VertexArrayObject::TextureCoordinatesAttribute, _texCoordsBuffer);
if (_colorsBuffer)
vao.addVertexAttribute(tgt::VertexArrayObject::ColorsAttribute, _colorsBuffer);
if (_normalsBuffer)
vao.addVertexAttribute(tgt::VertexArrayObject::NormalsAttribute, _normalsBuffer);
vao.setIndexBuffer(_indicesBuffer);
LGL_ERROR;
glDrawElements(mode, static_cast<GLsizei>(_indices.size()), GL_UNSIGNED_SHORT, 0);
LGL_ERROR;
}
void IndexedMeshGeometry::createGLBuffers() const {
GeometryData::createGLBuffers();
if (! _buffersInitialized) {
try {
_indicesBuffer = new tgt::BufferObject(tgt::BufferObject::ELEMENT_ARRAY_BUFFER, tgt::BufferObject::USAGE_STATIC_DRAW);
_indicesBuffer->data(&_indices.front(), _indices.size() * sizeof(uint16_t), tgt::BufferObject::UNSIGNED_SHORT, 1);
_verticesBuffer = new tgt::BufferObject(tgt::BufferObject::ARRAY_BUFFER, tgt::BufferObject::USAGE_STATIC_DRAW);
_verticesBuffer->data(&_vertices.front(), _vertices.size() * sizeof(tgt::vec3), tgt::BufferObject::FLOAT, 3);
if (! _textureCoordinates.empty()) {
_texCoordsBuffer = new tgt::BufferObject(tgt::BufferObject::ARRAY_BUFFER, tgt::BufferObject::USAGE_STATIC_DRAW);
_texCoordsBuffer->data(&_textureCoordinates.front(), _textureCoordinates.size() * sizeof(tgt::vec3), tgt::BufferObject::FLOAT, 3);
}
if (! _colors.empty()) {
_colorsBuffer = new tgt::BufferObject(tgt::BufferObject::ARRAY_BUFFER, tgt::BufferObject::USAGE_STATIC_DRAW);
_colorsBuffer->data(&_colors.front(), _colors.size() * sizeof(tgt::vec4), tgt::BufferObject::FLOAT, 4);
}
if (! _normals.empty()) {
_normalsBuffer = new tgt::BufferObject(tgt::BufferObject::ARRAY_BUFFER, tgt::BufferObject::USAGE_STATIC_DRAW);
_normalsBuffer->data(&_normals.front(), _normals.size() * sizeof(tgt::vec3), tgt::BufferObject::FLOAT, 3);
}
}
catch (tgt::Exception& e) {
LERROR("Error creating OpenGL Buffer objects: " << e.what());
_buffersInitialized = false;
return;
}
LGL_ERROR;
_buffersInitialized = true;
}
}
}
\ No newline at end of file
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universität München
// Boltzmannstr. 3, 85748 Garching b. München, Germany
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#ifndef INDEXEDIndexedMeshGeometry_H__
#define INDEXEDIndexedMeshGeometry_H__
#include "tgt/bounds.h"
#include "tgt/vector.h"
#include "core/datastructures/geometrydata.h"
#include "core/datastructures/facegeometry.h"
#include <vector>
namespace campvis {
/**
* Class for mesh geometry.
* Every IndexedMeshGeometry consists of a stream of vertices and an index list defining the faces.
*
* The internal OpenGL buffers are lazy-instantiated.
*
* \note Like all Geometry classes IndexedMeshGeometry has value-sematics: Once created, the
* faces cannot be altered anymore.
*/
class IndexedMeshGeometry : public GeometryData {
public:
/**
* Creates a new IndexedMeshGeometry built from the given faces.
* \param indices Index list defining the faces.
* \param vertices The list of the vertex positions of the face.
* \param textureCoordinates The list of vertex texture coordinates, may be empty.
* \param colors The list of vertex colors, may be empty.
* \param normals The list of vertex normals, may be empty.
*/
IndexedMeshGeometry(
const std::vector<uint16_t>& indices,
const std::vector<tgt::vec3>& vertices,
const std::vector<tgt::vec3>& textureCoordinates = std::vector<tgt::vec3>(),
const std::vector<tgt::vec4>& colors = std::vector<tgt::vec4>(),
const std::vector<tgt::vec3>& normals = std::vector<tgt::vec3>()
);
/**
* Destructor, deletes VBOs/VAO if necessary. Hence, needs a valid OpenGL context
*/
virtual ~IndexedMeshGeometry();
/// \see AbstractData::clone()
virtual IndexedMeshGeometry* clone() const;
/// \see AbstractData::getLocalMemoryFootprint()
virtual size_t getLocalMemoryFootprint() const;
/// \see AbstractData::getVideoMemoryFootprint()
virtual size_t getVideoMemoryFootprint() const;
/**
* Renders this IndexedMeshGeometry.
* Must be called from a valid OpenGL context.
* \param mode OpenGL rendering mode for this mesh
*/
virtual void render(GLenum mode) const;
/**
* Creates the OpenGL VBOs and the VAO for this face's geometry.
* Must be called from a valid OpenGL context.
*/
virtual void createGLBuffers() const;
protected:
std::vector<uint16_t> _indices; ///< Index list defining the faces
std::vector<tgt::vec3> _vertices; ///< The list of the vertex positions of the face.
std::vector<tgt::vec3> _textureCoordinates; ///< The list of vertex texture coordinates, may be empty.
std::vector<tgt::vec4> _colors; ///< The list of vertex colors, may be empty.
std::vector<tgt::vec3> _normals; ///< The list of vertex normals, may be empty.
mutable tgt::BufferObject* _indicesBuffer;
static const std::string loggerCat_;
};
}
#endif // INDEXEDIndexedMeshGeometry_H__
......@@ -62,4 +62,8 @@ namespace tgt {
return _size;
}
BufferObject::TargetType BufferObject::getTargetType() const {
return _targetType;
}
}
\ No newline at end of file
......@@ -14,7 +14,8 @@ namespace tgt {
public:
enum TargetType {
ARRAY_BUFFER = GL_ARRAY_BUFFER
ARRAY_BUFFER = GL_ARRAY_BUFFER,
ELEMENT_ARRAY_BUFFER = GL_ELEMENT_ARRAY_BUFFER
};
enum UsageType {
......@@ -62,6 +63,12 @@ namespace tgt {
*/
BaseType getBaseType() const;
/**
* Gets the target type of this buffer
* \return _targetType
*/
TargetType getTargetType() const;
/**
* Gets the number of elements per element (1, 2, 3 or 4).
* \return _elementSize
......
......@@ -70,6 +70,13 @@ namespace tgt {
// }
}
void VertexArrayObject::setIndexBuffer(BufferObject* bufferObject) {
tgtAssert(bufferObject->getTargetType() == BufferObject::ELEMENT_ARRAY_BUFFER, "Buffer needs to have target type ELEMENT_ARRAY_BUFFER!");
bind();
bufferObject->bind();
}
size_t VertexArrayObject::addVertexAttribute(AttributeType attributeType, BufferObject* bufferObject, GLsizei stride /*= 0*/, size_t offset /*= 0*/, bool enableNow /*= true*/) {
if (_attributes.size() > 16) {
// TODO: The better way would be to check glGet(GL_MAX_VERTEX_ATTRIBS), but the standard says 16 is the minimum
......
......@@ -90,6 +90,8 @@ namespace tgt {
*/
void unbind();
void setIndexBuffer(BufferObject* bufferObject);
/**
* Add a VertexAttribute to this VertexArrayObject.
* A VertexAttribute refers to a BufferObject and defines where to find the (geometry, normal, ...) data
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment