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

Implemented GPU Upload of fiber data

parent 9a76bebc
......@@ -29,30 +29,77 @@
#include "fiberdata.h"
#include "tgt/buffer.h"
#include "tgt/logmanager.h"
#include "tgt/vertexarrayobject.h"
namespace campvis {
FiberData::FiberData()
: AbstractData()
, _vertexBuffer(0)
, _tangentBuffer(0)
, _buffersInitialized(false)
, _vboFiberStartIndices(0)
, _vboFiberCounts(0)
{
}
FiberData::FiberData(const FiberData& rhs)
: AbstractData(rhs)
, _vertices(rhs._vertices)
, _fibers(rhs._fibers)
, _vertexBuffer(0)
, _tangentBuffer(0)
, _buffersInitialized(false)
, _vboFiberStartIndices(0)
, _vboFiberCounts(0)
{}
FiberData::~FiberData() {
delete _vertexBuffer;
delete _tangentBuffer;
delete [] _vboFiberStartIndices;
delete [] _vboFiberCounts;
}
FiberData& FiberData::operator=(const FiberData& rhs) {
if (this == &rhs)
return *this;
AbstractData::operator=(rhs);
_vertices = rhs._vertices;
_fibers = rhs._fibers;
// delete old VBOs and null pointers
delete _vertexBuffer;
delete _tangentBuffer;
_vertexBuffer = 0;
_tangentBuffer = 0;
_buffersInitialized = false;
return *this;
}
void FiberData::addFiber(const std::deque<tgt::vec3>& vertices) {
_vertices.insert(_vertices.end(), vertices.begin(), vertices.end());
_fibers.push_back(Fiber(_vertices.size() - vertices.size(), _vertices.size()));
_buffersInitialized = false;
}
void FiberData::addFiber(const std::vector<tgt::vec3>& vertices) {
_vertices.insert(_vertices.end(), vertices.begin(), vertices.end());
_fibers.push_back(Fiber(_vertices.size() - vertices.size(), _vertices.size()));
_buffersInitialized = false;
}
void FiberData::clear() {
_fibers.clear();
_vertices.clear();
_buffersInitialized = false;
}
void FiberData::updateLengths() const {
......@@ -93,7 +140,87 @@ namespace campvis {
}
size_t FiberData::getVideoMemoryFootprint() const {
return 0;
size_t sum = 0;
if (_vertexBuffer != 0)
sum += _vertexBuffer->getBufferSize();
if (_tangentBuffer != 0)
sum += _tangentBuffer->getBufferSize();
return sum;
}
void FiberData::createGlBuffers() const {
if (_buffersInitialized)
return;
// reset everything
delete _vertexBuffer;
delete _tangentBuffer;
delete [] _vboFiberStartIndices;
delete [] _vboFiberCounts;
_vboFiberArraySize = 0;
_vboFiberStartIndices = new GLint[_vertices.size()];
_vboFiberCounts = new GLint[_vertices.size()];
std::vector<tgt::vec3> tangents;
tangents.resize(_vertices.size());
for (std::vector<Fiber>::const_iterator it = _fibers.begin(); it != _fibers.end(); ++it) {
_vboFiberStartIndices[_vboFiberArraySize] = static_cast<GLint>(it->_startIndex);
_vboFiberCounts[_vboFiberArraySize] = static_cast<GLsizei>(it->_endIndex - it->_startIndex);
++_vboFiberArraySize;
tgt::vec3 dirPrev = tgt::vec3::zero;
tgt::vec3 dirNext = tgt::vec3::zero;
for (size_t i = it->_startIndex; i < it->_endIndex-1; ++i) {
dirNext = _vertices[i+1] - _vertices[i];
tangents[i] = tgt::normalize(dirPrev + dirNext);
dirPrev = dirNext;
}
tangents[it->_endIndex - 1] = dirPrev;
}
try {
_vertexBuffer = new tgt::BufferObject(tgt::BufferObject::ARRAY_BUFFER, tgt::BufferObject::USAGE_STATIC_DRAW);
_vertexBuffer->data(&_vertices.front(), _vertices.size() * sizeof(tgt::vec3), tgt::BufferObject::FLOAT, 3);
_tangentBuffer = new tgt::BufferObject(tgt::BufferObject::ARRAY_BUFFER, tgt::BufferObject::USAGE_STATIC_DRAW);
_tangentBuffer->data(&tangents.front(), tangents.size() * sizeof(tgt::vec3), tgt::BufferObject::FLOAT, 3);
}
catch (tgt::Exception& e) {
LERRORC("CAMPVis.modules.columbia.FiberData", "Error creating OpenGL Buffer objects: " << e.what());
_buffersInitialized = false;
return;
}
LGL_ERROR;
_buffersInitialized = true;
}
void FiberData::render(GLenum mode /*= GL_LINE_STRIP*/) const {
createGlBuffers();
if (! _buffersInitialized) {
LERRORC("CAMPVis.modules.columbia.FiberData", "Cannot render without initialized OpenGL buffers.");
return;
}
tgt::VertexArrayObject vao;
vao.addVertexAttribute(tgt::VertexArrayObject::VerticesAttribute, _vertexBuffer);
vao.addVertexAttribute(tgt::VertexArrayObject::NormalsAttribute, _tangentBuffer);
LGL_ERROR;
glMultiDrawArrays(mode, _vboFiberStartIndices, _vboFiberCounts, _vboFiberArraySize);
LGL_ERROR;
}
tgt::Bounds FiberData::getWorldBounds() const {
tgt::Bounds toReturn;
for (std::vector<tgt::vec3>::const_iterator it = _vertices.begin(); it != _vertices.end(); ++it)
toReturn.addPoint(*it);
return toReturn;
}
}
\ No newline at end of file
......@@ -30,12 +30,19 @@
#ifndef FIBERDATA_H__
#define FIBERDATA_H__
#include "tgt/bounds.h"
#include "tgt/tgt_gl.h"
#include "tgt/vector.h"
#include "core/datastructures/abstractdata.h"
#include <deque>
#include <vector>
namespace tgt {
class BufferObject;
}
namespace campvis {
/**
......@@ -66,12 +73,25 @@ namespace campvis {
*/
FiberData();
/**
* Copy Constructor.
* \param rhs source
*/
FiberData(const FiberData& rhs);
/**
* Destructor.
*/
virtual ~FiberData();
/**
* Assignment Operator
* \param rhs Source
* \return *this
*/
FiberData& operator=(const FiberData& rhs);
/**
* Generates a new fiber from the given vertices and adds it to this data structure.
* \param vertices Coordinates of the fiber points.
......@@ -114,6 +134,20 @@ namespace campvis {
*/
bool empty() const;
/**
* Returns the fiber data extent in world coordinates.
* \note Caution: Calling this method is expensive as the bounds are computed each time.
* \return The fiber data extent in world coordinates.
*/
tgt::Bounds getWorldBounds() const;
/**
* Renders the Fiber geometry of this data set in the current OpenGL context.
* \note Must be called from a valid openGL context!
* \param mode OpenGL render mode (defaults to GL_LINE_STRIP).
*/
void render(GLenum mode = GL_LINE_STRIP) const;
/// \see AbstractData::clone()
virtual FiberData* clone() const;
......@@ -125,9 +159,21 @@ namespace campvis {
virtual size_t getVideoMemoryFootprint() const;
protected:
/**
* Creates the OpenGL buffers with vertex and tangent data.
*/
void createGlBuffers() const;
std::vector<tgt::vec3> _vertices; ///< The fiber vertex (coordinates) data
std::vector<Fiber> _fibers; ///< The fiber meta data
mutable tgt::BufferObject* _vertexBuffer; ///< Pointer to OpenGL buffer with vertex data (lazy-instantiated)
mutable tgt::BufferObject* _tangentBuffer; ///< Pointer to OpenGL buffer with tangent data (lazy-instantiated)
mutable bool _buffersInitialized; ///< flag whether all OpenGL buffers were successfully initialized
mutable GLint* _vboFiberStartIndices; ///< VBO start indices for each fiber
mutable GLsizei* _vboFiberCounts; ///< number of indices for each fiber
mutable GLsizei _vboFiberArraySize; ///< number of elements in the above two lists
};
}
......
......@@ -224,9 +224,9 @@ namespace campvis {
const tgt::mat4& VtW = strainData.getParent()->getMappingInformation().getVoxelToWorldMatrix();
float threshold = p_strainThreshold.getValue() * p_strainThreshold.getValue();
for (size_t z = 0; z < strainData.getSize().z; ++z) {
for (size_t y = 0; y < strainData.getSize().y; ++y) {
for (size_t x = 0; x < strainData.getSize().x; ++x) {
for (size_t z = 0; z < strainData.getSize().z; z += 2) {
for (size_t y = 0; y < strainData.getSize().y; y += 2) {
for (size_t x = 0; x < strainData.getSize().x; x += 2) {
tgt::vec3 pos(x, y, z);
if (tgt::lengthSq(getVec3FloatLinear(strainData, pos)) > threshold) {
seeds.push_back((VtW * tgt::vec4(pos, 1.f)).xyz());
......
......@@ -91,10 +91,13 @@ namespace campvis {
// set modelview and projection matrices
_shader->activate();
_shader->setIgnoreUniformLocationError(true);
decorateRenderProlog(data, _shader);
_shader->setUniform("_projectionMatrix", p_camera.getValue().getProjectionMatrix());
_shader->setUniform("_viewMatrix", p_camera.getValue().getViewMatrix());
_shader->setUniform("_color", p_color.getValue());
_shader->setUniform("_cameraPosition", p_camera.getValue().getPosition());
_shader->setIgnoreUniformLocationError(false);
// create entry points texture
std::pair<ImageData*, ImageRepresentationRenderTarget*> rt = ImageRepresentationRenderTarget::createWithImageData(_renderTargetSize.getValue(), GL_RGBA16);
......
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