2.12.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

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

* Fixed DataContainerInspector shader for geometry rendering

* Introducing MultiIndexedGeometry data type
* Introducing GeometryDataFactory::createTeapot()
parent 094842ea
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2013, 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".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
#include "tools/shading.frag"
in vec3 ex_TexCoord; ///< incoming texture coordinate
in vec4 ex_Position; ///< incoming texture coordinate
out vec4 out_Color; ///< outgoing fragment color
uniform vec4 _color;
uniform LightSource _lightSource;
uniform vec3 _cameraPosition;
void main() {
out_Color = _color;
#ifdef ENABLE_SHADING
// compute gradient (needed for shading and normals)
vec3 gradient = ex_TexCoord;
out_Color.rgb = calculatePhongShading(ex_Position.xyz / ex_Position.z, _lightSource, _cameraPosition, gradient, _color.rgb, _color.rgb, vec3(1.0, 1.0, 1.0));
#endif
}
......@@ -89,7 +89,7 @@ namespace campvis {
GLJobProc.registerContext(this);
_paintShader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "application/glsl/datacontainerinspector.frag", "", false);
_geometryRenderingShader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "modules/vis/glsl/geometryrenderer.frag", "", false);
_geometryRenderingShader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "application/glsl/datacontainerinspector_geometryrenderer.frag", "", false);
_paintShader->setAttributeLocation(0, "in_Position");
_paintShader->setAttributeLocation(1, "in_TexCoords");
......
......@@ -26,6 +26,11 @@
#include "tgt/assert.h"
#pragma warning(push)
#pragma warning(disable: 4305) // disable warning in external code
#include "core/tools/teapot.h"
#pragma warning(pop)
namespace campvis {
FaceGeometry* GeometryDataFactory::createQuad(const tgt::vec3& llf, const tgt::vec3& urb, const tgt::vec3& texLlf, const tgt::vec3& texUrb) {
......@@ -135,4 +140,27 @@ namespace campvis {
return new MeshGeometry(faces);
}
MultiIndexedGeometry* GeometryDataFactory::createTeapot() {
std::vector<tgt::vec3> vertices, normals;
vertices.reserve(num_teapot_vertices);
normals.reserve(num_teapot_vertices);
for (size_t i = 0; i < num_teapot_vertices; ++i) {
vertices.push_back(tgt::vec3(teapot_vertices + 3*i));
normals.push_back(tgt::vec3(teapot_normals + 3*i));
}
MultiIndexedGeometry* toReturn = new MultiIndexedGeometry(vertices, std::vector<tgt::vec3>(), std::vector<tgt::vec4>(), normals);
// convert indices and add primitives
int currentOffset = 0;
while (currentOffset < num_teapot_indices) {
uint16_t count = new_teapot_indicies[currentOffset];
toReturn->addPrimitive(std::vector<uint16_t>(new_teapot_indicies + currentOffset + 1, new_teapot_indicies + count + currentOffset + 1));
currentOffset += count + 1;
}
return toReturn;
}
}
\ No newline at end of file
......@@ -30,6 +30,7 @@
#include "core/datastructures/geometrydata.h"
#include "core/datastructures/facegeometry.h"
#include "core/datastructures/meshgeometry.h"
#include "core/datastructures/multiindexedgeometry.h"
#include <vector>
......@@ -58,6 +59,11 @@ namespace campvis {
*/
static MeshGeometry* createCube(const tgt::Bounds& bounds, const tgt::Bounds& texBounds);
/**
* Creates an MultiIndexedGeometry storing the famous Utah teapot.
* \return MultiIndexedGeometry storing the famous Utah teapot.
*/
static MultiIndexedGeometry* createTeapot();
};
}
......
......@@ -69,6 +69,7 @@ namespace campvis {
{
}
IndexedMeshGeometry::~IndexedMeshGeometry() {
deleteIndicesBuffer();
}
......@@ -78,6 +79,11 @@ namespace campvis {
return *this;
GeometryData::operator=(rhs);
_indices = rhs._indices;
_vertices = rhs._vertices;
_textureCoordinates = rhs._textureCoordinates;
_colors = rhs._colors;
_normals = rhs._normals;
// delete old VBOs and null pointers
deleteIndicesBuffer();
......
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2013, 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".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
#include "multiindexedgeometry.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 MultiIndexedGeometry::loggerCat_ = "CAMPVis.core.datastructures.MultiIndexedGeometry";
MultiIndexedGeometry::MultiIndexedGeometry(
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()
, _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.");
}
MultiIndexedGeometry::MultiIndexedGeometry(const MultiIndexedGeometry& rhs)
: GeometryData(rhs)
, _indices(rhs._indices)
, _offsets(rhs._offsets)
, _counts(rhs._counts)
, _vertices(rhs._vertices)
, _textureCoordinates(rhs._textureCoordinates)
, _colors(rhs._colors)
, _normals(rhs._normals)
, _indicesBuffer(0)
{
}
MultiIndexedGeometry::~MultiIndexedGeometry() {
deleteIndicesBuffer();
}
MultiIndexedGeometry& MultiIndexedGeometry::operator=(const MultiIndexedGeometry& rhs) {
if (this == &rhs)
return *this;
GeometryData::operator=(rhs);
_indices = rhs._indices;
_offsets = rhs._offsets;
_counts = rhs._counts;
_vertices = rhs._vertices;
_textureCoordinates = rhs._textureCoordinates;
_colors = rhs._colors;
_normals = rhs._normals;
// delete old VBOs and null pointers
deleteIndicesBuffer();
return *this;
}
MultiIndexedGeometry* MultiIndexedGeometry::clone() const {
MultiIndexedGeometry* toReturn = new MultiIndexedGeometry(_vertices, _textureCoordinates, _colors, _normals);
toReturn->_indices = _indices;
toReturn->_offsets = _offsets;
toReturn->_counts = _counts;
return toReturn;
}
size_t MultiIndexedGeometry::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 MultiIndexedGeometry::getVideoMemoryFootprint() const {
return GeometryData::getVideoMemoryFootprint() + (_indicesBuffer == 0 ? 0 : _indicesBuffer->getBufferSize());
}
void MultiIndexedGeometry::addPrimitive(const std::vector<uint16_t>& indices) {
_offsets.push_back(reinterpret_cast<void*>(_indices.size() * 2));
_counts.push_back(static_cast<GLsizei>(indices.size()));
_indices.insert(_indices.end(), indices.begin(), indices.end());
_buffersDirty = true;
}
void MultiIndexedGeometry::render(GLenum mode) const {
createGLBuffers();
if (_buffersDirty) {
LERROR("Cannot render without initialized OpenGL buffers.");
return;
}
tgt::VertexArrayObject vao;
if (_verticesBuffer)
vao.setVertexAttributePointer(0, _verticesBuffer);
if (_texCoordsBuffer)
vao.setVertexAttributePointer(1, _texCoordsBuffer);
if (_colorsBuffer)
vao.setVertexAttributePointer(2, _colorsBuffer);
if (_normalsBuffer)
vao.setVertexAttributePointer(3, _normalsBuffer);
vao.bindIndexBuffer(_indicesBuffer);
const GLvoid** ptr = (const GLvoid**)(&_offsets.front()); // <- hidden reinterpret_cast<const GLvoid**> here, ugly OpenGL...
glMultiDrawElements(mode, &_counts.front(), GL_UNSIGNED_SHORT, ptr, static_cast<GLsizei>(_offsets.size()));
LGL_ERROR;
}
void MultiIndexedGeometry::createGLBuffers() const {
if (_buffersDirty) {
deleteBuffers();
deleteIndicesBuffer();
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());
_buffersDirty = true;
return;
}
LGL_ERROR;
_buffersDirty = false;
}
}
tgt::Bounds MultiIndexedGeometry::getWorldBounds() const {
tgt::Bounds toReturn;
for (std::vector<tgt::vec3>::const_iterator it = _vertices.begin(); it != _vertices.end(); ++it)
toReturn.addPoint(*it);
return toReturn;
}
void MultiIndexedGeometry::deleteIndicesBuffer() const {
delete _indicesBuffer;
_indicesBuffer = 0;
}
void MultiIndexedGeometry::applyTransformation(const tgt::mat4& t) {
for (size_t i = 0; i < _vertices.size(); ++i) {
tgt::vec4 tmp = t * tgt::vec4(_vertices[i], 1.f);
_vertices[i] = tmp.xyz() / tmp.w;
}
_buffersDirty = true;
}
}
\ No newline at end of file
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2013, 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".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
#ifndef MULTIINDEXEDGEOMETRY_H__
#define MULTIINDEXEDGEOMETRY_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 indexed geometry consisting of multiple primitives.
* Internally working with glMultiDrawElements(), every MultiIndexedGeometry consists of a
* stream of vertices, an index list defining the faces and a pair of arrays defining start
* indices and number of indices for each primitive to render.
*
* The internal OpenGL buffers are lazy-instantiated.
*/
class MultiIndexedGeometry : public GeometryData {
public:
/**
* Creates a new MultiIndexedGeometry using the given geometry. Indices are to be provided later.
* \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.
*/
explicit MultiIndexedGeometry(
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>()
);
/**
* Copy constructor
* \param rhs MultiIndexedGeometry to copy
*/
MultiIndexedGeometry(const MultiIndexedGeometry& rhs);
/**
* Destructor, deletes VBOs/VAO if necessary. Hence, needs a valid OpenGL context
*/
virtual ~MultiIndexedGeometry();
/**
* Assignment operator.
* \param rhs MultiIndexedGeometry to assign to this.
* \return *this after assignment
*/
MultiIndexedGeometry& operator=(const MultiIndexedGeometry& rhs);
/// \see AbstractData::clone()
virtual MultiIndexedGeometry* clone() const;
/// \see AbstractData::getLocalMemoryFootprint()
virtual size_t getLocalMemoryFootprint() const;
/// \see AbstractData::getVideoMemoryFootprint()
virtual size_t getVideoMemoryFootprint() const;
/**
* Add a render primitive given by a list of indices.
* \param indices Index list defining the faces.
*/
void addPrimitive(const std::vector<uint16_t>& indices);
/**
* Renders this MultiIndexedGeometry.
* Must be called from a valid OpenGL context.
* \param mode OpenGL rendering mode for this mesh
*/
virtual void render(GLenum mode) const;
/// \see GeometryData::getWorldBounds
virtual tgt::Bounds getWorldBounds() const;
/**
* Applies the transformation matrix \a t to each vertex of this geometry.
* \param t Transformation matrix to apply
*/
void applyTransformation(const tgt::mat4& t);
protected:
/**
* Creates the OpenGL VBOs and the VAO for this face's geometry.
* Must be called from a valid OpenGL context.
*/
void createGLBuffers() const;
/// Deletes the OpenGL BufferObject for the indices.
void deleteIndicesBuffer() const;
std::vector<uint16_t> _indices; ///< Index list defining the faces
std::vector<void*> _offsets; ///< Byte offsets for each primitive to render
std::vector<GLsizei> _counts; ///< Numer of vertices for each primitive to render
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 // MULTIINDEXEDGEOMETRY_H__
This diff is collapsed.
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