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

Commit 535d69e6 authored by mmostajab's avatar mmostajab

# Adding functionality to render the mesh in the DataContainerInspectorCanvas...

# Adding functionality to render the mesh in the DataContainerInspectorCanvas and camera rotating around the object
parent d53dbd6a
......@@ -38,19 +38,21 @@
#include "core/datastructures/renderdata.h"
#include "core/datastructures/imagerepresentationgl.h"
#include "core/datastructures/facegeometry.h"
#include "core/datastructures/meshgeometry.h"
#include "core/tools/job.h"
#include "core/classification/tfgeometry1d.h"
#include "core/classification/geometry1dtransferfunction.h"
#include "datacontainerinspectorwidget.h"
#include "ext/tgt/navigation/trackball.h"
namespace campvis {
DataContainerInspectorCanvas::DataContainerInspectorCanvas(QWidget* parent /*= 0*/)
: tgt::QtThreadedCanvas("DataContainer Inspector", tgt::ivec2(640, 480), tgt::GLCanvas::RGBA_BUFFER, parent, true)
, p_currentSlice("CurrentSlice", "Slice", -1, -1, -1)
, p_meshSolidColor("MeshSolidColor", "Mesh Solid Color", tgt::vec4(1.f), tgt::vec4(0.f), tgt::vec4(255.f))
, p_transferFunction("TransferFunction", "Transfer Function", new Geometry1DTransferFunction(256, tgt::vec2(0.f, 1.f)))
, _dataContainer(0)
, _paintShader(0)
......@@ -61,6 +63,8 @@ namespace campvis {
, _renderFullscreen(false)
, _currentSlice(-1)
, _color(0.0f, 0.0f, 0.0f, 0.0f)
, _geomteryRendering_ColorBuffer(0)
, _geomteryRendering_DepthBuffer(0)
{
static_cast<Geometry1DTransferFunction*>(p_transferFunction.getTF())->addGeometry(TFGeometry1D::createQuad(tgt::vec2(0.f, 1.f), tgt::col4(0, 0, 0, 255), tgt::col4(255, 255, 255, 255)));
......@@ -73,9 +77,16 @@ namespace campvis {
std::cerr << "glewInit failed, error: " << glewGetErrorString(err) << std::endl;
exit(EXIT_FAILURE);
}
addProperty(&p_currentSlice);
addProperty(&p_transferFunction);
addProperty(&p_meshSolidColor);
//addProperty(&_camera);
_trackballCamera = new tgt::Camera(tgt::vec3(0.0f, 0.0f, 100.0f), tgt::vec3(0, 0, -1));
_trackballCameraProperty = new campvis::CameraProperty("camera", "Camera", *_trackballCamera);
_canvasSizeProperty = new campvis::IVec2Property("CanvasSize", "Canvas Size", tgt::ivec2(128, 128), tgt::ivec2(1, 1), tgt::ivec2(4096, 4096));
_trackballEH = new TrackballNavigationEventListener(_trackballCameraProperty, _canvasSizeProperty);
}
DataContainerInspectorCanvas::~DataContainerInspectorCanvas() {
......@@ -89,7 +100,7 @@ namespace campvis {
GLJobProc.registerContext(this);
_paintShader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "application/glsl/datacontainerinspector.frag", "", false);
_geomteryRenderingShader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "modules/vis/glsl/geometryrenderer.frag", "", false);
_geomteryRenderingShader = ShdrMgr.loadSeparate("core/glsl/meshgeomteryrenderer.vert", "modules/vis/glsl/meshgeometryrenderer.frag", "", false);
_paintShader->setAttributeLocation(0, "in_Position");
_paintShader->setAttributeLocation(1, "in_TexCoords");
......@@ -120,6 +131,7 @@ namespace campvis {
void DataContainerInspectorCanvas::paint() {
LGL_ERROR;
tbb::mutex::scoped_lock lock(_localMutex);
if (_texturesDirty)
updateTextures();
......@@ -193,6 +205,95 @@ namespace campvis {
_paintShader->setIgnoreUniformLocationError(false);
_quad->render(GL_POLYGON);
LGL_ERROR;
}
void DataContainerInspectorCanvas::drawMeshGeomtery(const campvis::MeshGeometry* mg)
{
LGL_ERROR;
// Here the object will be rendered into a texture and the texture will be shown on the output buffer
glPushAttrib(GL_ALL_ATTRIB_BITS);
_geomteryRenderingShader->activate();
LGL_ERROR;
_geomteryRenderingShader->setIgnoreUniformLocationError(true);
LGL_ERROR;
//decorateRenderProlog(data, _shader);
//_trackballCamera->setPosition(tgt::vec3(0.0f, 0.0f, dist));
//_trackballCamera->setFocus(tgt::vec3(0, 0, -1));
//_trackballCamera->setFarDist(1000.0f);
_trackballEH->setSceneBounds(mg->getWorldBounds());
campvis::IVec4Property* p_color = new campvis::IVec4Property("myColor", "MyRenderingColor", tgt::vec4(1.f), tgt::vec4(0.f), tgt::vec4(1.f));
_geomteryRenderingShader->setUniform("_projectionMatrix", _trackballEH->_trackball->getCamera()->getProjectionMatrix()/*_trackballCameraProperty->getValue().getProjectionMatrix()*/);
LGL_ERROR;
tgt::Matrix4f mat = _trackballCamera->getProjectionMatrix();
_geomteryRenderingShader->setUniform("_viewMatrix", _trackballEH->_trackball->getCamera()->getViewMatrix());
LGL_ERROR;
LGL_ERROR;
_geomteryRenderingShader->setUniform("_colormory", p_color->getValue());
LGL_ERROR;
_geomteryRenderingShader->setUniform("_cameraPosition", _trackballEH->_trackball->getCamera()->getPosition());
LGL_ERROR;
_geomteryRenderingShader->setIgnoreUniformLocationError(false);
LGL_ERROR;
tgt::FramebufferObject* frameBuffer = new tgt::FramebufferObject();
LGL_ERROR;
frameBuffer->activate();
LGL_ERROR;
// acqiure a new TextureUnit, so that we don't mess with other currently bound textures during texture upload...
//tgt::TextureUnit rtUnit;
//rtUnit.activate();
// Set OpenGL pixel alignment to 1 to avoid problems with NPOT textures
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
_geomteryRendering_ColorBuffer->uploadTexture();
_geomteryRendering_ColorBuffer->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
_geomteryRendering_DepthBuffer->uploadTexture();
_geomteryRendering_DepthBuffer->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
LGL_ERROR;
frameBuffer->attachTexture(_geomteryRendering_ColorBuffer, GL_COLOR_ATTACHMENT0);
frameBuffer->attachTexture(_geomteryRendering_DepthBuffer, GL_DEPTH_ATTACHMENT);
frameBuffer->isComplete();
LGL_ERROR;
glViewport(0, 0, 400, 100);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
LGL_ERROR;
//for (std::map<QString, QtDataHandle>::iterator it = _handles.begin(); it != _handles.end(); ++it) {
// if (const campvis::MeshGeometry* mg = dynamic_cast<const campvis::MeshGeometry*>(it->second.getData())) {
//mg->render(GL_POLYGON);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
mg->render(GL_POLYGON);
// }
// }
LGL_ERROR;
_geomteryRendering_ColorBuffer->downloadTexture();
frameBuffer->deactivate();
LGL_ERROR;
_geomteryRenderingShader->deactivate();
glPopAttrib();
//delete frameBuffer;
}
void DataContainerInspectorCanvas::invalidate() {
......@@ -241,6 +342,7 @@ namespace campvis {
void DataContainerInspectorCanvas::mouseMoveEvent(tgt::MouseEvent* e)
{
LGL_ERROR;
/*if (_renderFullscreen) {
_renderFullscreen = false;
}
......@@ -251,10 +353,25 @@ namespace campvis {
}
e->ignore();
invalidate();*/
if(e->button() == tgt::MouseEvent::MOUSE_BUTTON_RIGHT)
if(e->button() == tgt::MouseEvent::MOUSE_BUTTON_LEFT)
{
tgt::MouseEvent* me = static_cast<tgt::MouseEvent*>(e);
tgt::MouseEvent adjustedMe(
me->x(),
me->y(),
me->action(),
me->modifiers(),
me->button(),
me->viewport()
);
_trackballEH->onEvent(&adjustedMe);
_texturesDirty = true;
invalidate();
}
else if(e->button() == tgt::MouseEvent::MOUSE_BUTTON_RIGHT)
{
tgt::ivec2 dimCanvas = tgt::ivec2(_quadSize.x * _numTiles.x, _quadSize.y * _numTiles.y);
if(e->x() >= dimCanvas.x || e->y() >= dimCanvas.y || e->x() < 0 || e->y() < 0)
return;
......@@ -299,6 +416,38 @@ namespace campvis {
}
}
void DataContainerInspectorCanvas::mousePressEvent(tgt::MouseEvent* e) {
LGL_ERROR;
//if (_renderFullscreen) {
switch (e->button()) {
case tgt::MouseEvent::MOUSE_BUTTON_LEFT:
//++_currentSlice; // we cant clamp the value here to the number of slices - we do this during rendering
_trackballEH->_trackball->startMouseDrag(e);
// e->ignore();
break;
default:
break;
}
//}
}
void DataContainerInspectorCanvas::mouseReleaseEvent(tgt::MouseEvent* e) {
if (_renderFullscreen) {
switch (e->button()) {
case tgt::MouseEvent::MOUSE_BUTTON_LEFT:
//++_currentSlice; // we cant clamp the value here to the number of slices - we do this during rendering
_trackballEH->_trackball->endMouseDrag(e);
// e->ignore();
break;
default:
break;
}
invalidate();
}
}
void DataContainerInspectorCanvas::onDataContainerChanged(const QString& key, QtDataHandle dh) {
{
tbb::mutex::scoped_lock lock(_localMutex);
......@@ -376,85 +525,32 @@ namespace campvis {
}
}
else if(const campvis::MeshGeometry* mg = dynamic_cast<const campvis::MeshGeometry*>(it->second.getData())){
LGL_ERROR;
// Here the object will be rendered into a texture and the texture will be shown on the output buffer
glPushAttrib(GL_ALL_ATTRIB_BITS);
_geomteryRenderingShader->activate();
LGL_ERROR;
_geomteryRenderingShader->setIgnoreUniformLocationError(true);
LGL_ERROR;
//decorateRenderProlog(data, _shader);
float dist = 3 * fabs(mg->getWorldBounds().getLLF().z - mg->getWorldBounds().getURB().z);
tgt::Camera cameraInfo(tgt::vec3(0.0f, 0.0f, dist), tgt::vec3(0, 0, -1));
cameraInfo.setFarDist(1000.0f);
campvis::CameraProperty* p_camera = new campvis::CameraProperty("camera", "Camera", cameraInfo);
campvis::IVec4Property* p_color = new campvis::IVec4Property("color", "Rendering Color", tgt::vec4(1.f), tgt::vec4(0.f), tgt::vec4(1.f));
_geomteryRenderingShader->setUniform("_projectionMatrix", p_camera->getValue().getProjectionMatrix());
LGL_ERROR;
_geomteryRenderingShader->setUniform("_viewMatrix", p_camera->getValue().getViewMatrix());
LGL_ERROR;
LGL_ERROR;
_geomteryRenderingShader->setUniform("_modelMatrix", tgt::mat4::createTranslation(-mg->getWorldBounds().center()));
LGL_ERROR;
LGL_ERROR;
//_geomteryRenderingShader->setUniform("_color", p_color->getValue());
// LGL_ERROR;
_geomteryRenderingShader->setUniform("_cameraPosition", p_camera->getValue().getPosition());
LGL_ERROR;
_geomteryRenderingShader->setIgnoreUniformLocationError(false);
LGL_ERROR;
tgt::FramebufferObject* frameBuffer = new tgt::FramebufferObject();
LGL_ERROR;
frameBuffer->activate();
LGL_ERROR;
// acqiure a new TextureUnit, so that we don't mess with other currently bound textures during texture upload...
//tgt::TextureUnit rtUnit;
//rtUnit.activate();
// Set OpenGL pixel alignment to 1 to avoid problems with NPOT textures
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
tgt::Texture* colorBuff = new tgt::Texture(0, tgt::ivec3(400, 100, 1), GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
tgt::Texture* depthBuff = new tgt::Texture(0, tgt::ivec3(400, 100, 1), GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24, GL_FLOAT, tgt::Texture::LINEAR);
colorBuff->uploadTexture();
colorBuff->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
depthBuff->uploadTexture();
depthBuff->setWrapping(tgt::Texture::CLAMP_TO_EDGE);
LGL_ERROR;
frameBuffer->attachTexture(colorBuff, GL_COLOR_ATTACHMENT0);
frameBuffer->attachTexture(depthBuff, GL_DEPTH_ATTACHMENT);
frameBuffer->isComplete();
LGL_ERROR;
glViewport(0, 0, 400, 100);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
LGL_ERROR;
mg->render(GL_POLYGON);
LGL_ERROR;
colorBuff->downloadTexture();
frameBuffer->deactivate();
LGL_ERROR;
LGL_ERROR;
static bool flag = false;
if(!flag)
{
float dist = 3 * fabs(mg->getWorldBounds().getLLF().z - mg->getWorldBounds().getURB().z);
_trackballEH->reinitializeCamera(mg->getWorldBounds());
_trackballEH->_trackball->moveCameraBackward(dist);
flag = true;
}
_geomteryRenderingShader->deactivate();
if(_geomteryRendering_ColorBuffer)
delete _geomteryRendering_ColorBuffer;
_textures.push_back(colorBuff);
if(_geomteryRendering_DepthBuffer)
delete _geomteryRendering_DepthBuffer;
glPopAttrib();
_geomteryRendering_ColorBuffer = new tgt::Texture(0, tgt::ivec3(400, 100, 1), GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tgt::Texture::LINEAR);
_geomteryRendering_DepthBuffer = new tgt::Texture(0, tgt::ivec3(400, 100, 1), GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24, GL_FLOAT, tgt::Texture::LINEAR);
_meshGeomteryPtr = mg;
drawMeshGeomtery(mg);
_textures.push_back(_geomteryRendering_ColorBuffer);
}else if(const campvis::FaceGeometry* fg = dynamic_cast<const campvis::FaceGeometry*>(it->second.getData())){
......
......@@ -46,6 +46,9 @@
#include "core/tools/opengljobprocessor.h"
#include "modules/vis/processors/geometryrenderer.h"
#include "core/eventhandlers/trackballnavigationeventlistener.h"
#include "core/datastructures/meshgeometry.h"
namespace tgt {
class Shader;
class Texture;
......@@ -126,11 +129,23 @@ namespace campvis {
virtual void mouseMoveEvent(tgt::MouseEvent* e);
/**
* Called on mouse wheel even on this canvas.
* Called on mouse wheel event on this canvas.
* \param e Mouse event arguments
*/
virtual void wheelEvent(tgt::MouseEvent* e);
/**
* Called on mouse press button event on this canvas.
* \param e Mouse event arguments
*/
virtual void mousePressEvent(tgt::MouseEvent* e);
/**
* Called on mouse release button event on this canvas.
* \param e Mouse event arguments
*/
virtual void mouseReleaseEvent(tgt::MouseEvent* e);
/**
* Slot getting called when one of the observed properties changed and notifies its observers.
* \param prop Property that emitted the signal
......@@ -138,6 +153,7 @@ namespace campvis {
virtual void onPropertyChanged(const AbstractProperty* prop);
IntProperty p_currentSlice;
IVec4Property p_meshSolidColor; ///< Color used to render the mesh object
TransferFunctionProperty p_transferFunction; ///< Transfer function
private slots:
......@@ -181,11 +197,11 @@ namespace campvis {
void paintTexture(const tgt::Texture* texture, const tgt::TextureUnit& unit2d, const tgt::TextureUnit& unit3d);
/**
* Renders the given 2D texture.
* Renders the MeshGeomtery into the geomtery renderer color buffer and depth buffer
* Binds the texture to the shader, sets the uniforms and renders the quad.
* \param texture The texture to render.
* \param meshGeomtery The mesh to be rendered.
*/
void drawGeomtery();
void drawMeshGeomtery(const campvis::MeshGeometry* meshGeomtery);
/**
* Creates the quad used for rendering the textures.
......@@ -214,6 +230,14 @@ namespace campvis {
int _currentSlice; ///< current slice if rendering a 3D image fullscreen, render MIP if negative
tgt::Shader* _geomteryRenderingShader; ///< GLSL shader for rendering the geomtery
tgt::Texture* _geomteryRendering_ColorBuffer; ///< Color Buffer used to render the Geomtery for the debugging mode
tgt::Texture* _geomteryRendering_DepthBuffer; ///< Depth Buffer used to render the Geomtery for the debugging mode
const campvis::MeshGeometry* _meshGeomteryPtr;
campvis::IVec2Property* _canvasSizeProperty; ///< The property of the size of the canvas
tgt::Camera* _trackballCamera; ///< Trackball camera
campvis::CameraProperty* _trackballCameraProperty; ///< The property of the trackball camera. Used to pass the trackball camera to the shader.
TrackballNavigationEventListener* _trackballEH; ///< TrackBall Event Handler for the camera rotating around the object in the canvas
};
}
......
......@@ -173,7 +173,9 @@ namespace campvis {
CameraProperty* _cameraProperty; ///< The CameraProperty to apply the navigation to
IVec2Property* _viewportSizeProp; ///< Pointer to the property defining the viewport size
CamPropNavigationWrapper _cpnw; ///< The CamPropNavigationWrapper used to adapt to the tgt::Trackball interface
public:
tgt::Trackball* _trackball; ///< The tgt::Trackball for the navigation logic
protected:
tgt::Bounds _sceneBounds; ///< The extent of the scene (in world coordinates)
/// List of processors for which to enable LQ mode during interaction
......
......@@ -286,6 +286,7 @@ class Trackball : public Navigation {
/// last rotation applied to trackball
quat lastOrientationChange_;
public:
/// Stores mouse coordinates to be able to track relative mouse motions.
/// Should be called when mouse buttons get pressed.
void startMouseDrag(MouseEvent* e);
......@@ -293,6 +294,7 @@ class Trackball : public Navigation {
/// Should be called when mouse buttons get released.
void endMouseDrag(MouseEvent* e);
protected:
/// scale screen-coodinates of mouse to intervall [-1, 1]x[-1, 1]
vec2 scaleMouse(const ivec2& sc) const;
......
......@@ -461,6 +461,36 @@ tgt::Color Texture::texelAsFloat(size_t x, size_t y) const {
return ret;
}
float Texture::depthAsFloat(size_t x, size_t y) const {
float ret = 0.0f;
switch(format_) {
case GL_DEPTH_COMPONENT:
switch(dataType_) {
case GL_UNSIGNED_BYTE: {
ret = (float )(texel<uint8_t>(x,y) / 0xFF);
break;
}
case GL_UNSIGNED_SHORT: {
ret = (float )(texel<uint16_t>(x,y) / 0xFFFF);
break;
}
case GL_FLOAT: {
ret = texel<GLfloat>(x,y);
break;
default:
//int t = 0.0f;
LWARNINGC("tgt.texture", "depthAsFloat: Unknown format!");
}
}
default:
LWARNINGC("tgt.texture", "depthAsFloat: Unknown format!");
}
return ret;
}
void Texture::downloadTexture() {
bind();
......
......@@ -390,7 +390,9 @@ public:
///Return texel as tgt::Color (slow!), downloadTexture() needs to be called first
tgt::Color texelAsFloat(size_t x, size_t y) const;
float depthAsFloat(size_t x, size_t y) const;
tgt::Color texelAsFloat(tgt::svec2 p) const { return texelAsFloat(p.x, p.y); }
float depthAsFloat(tgt::svec2 p) const { return depthAsFloat(p.x, p.y); }
protected:
tgt::ivec3 dimensions_;
GLint format_; ///< GL_RGB...
......
......@@ -40,7 +40,9 @@ uniform LightSource _lightSource;
uniform vec3 _cameraPosition;
void main() {
out_Color = _color;
out_Color = ex_Position;
//out_Color = vec4(1, 1, 0, 1);
//out_Color = _color;
#ifdef ENABLE_SHADING
// compute gradient (needed for shading and normals)
......
// ================================================================================================
//
// 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.
//
// ================================================================================================
#include "tools/shading.frag"
in vec3 ex_TexCoord; ///< incoming texture coordinate
in vec4 ex_Position; ///< incoming texture coordinate
in vec4 ex_Color; ///< outgoing colorin
in vec3 ex_Local_Position; ///< incoming local coordinate
out vec4 out_Color; ///< outgoing fragment color
uniform vec4 _colormory;
//uniform vec4 _color2;
uniform LightSource _lightSource;
uniform vec3 _cameraPosition;
void main() {
out_Color = _colormory;
//out_Color = vec4(normalize(ex_Local_Position), 1);
//out_Color = vec4(0, 1, 0, 1);
//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
}
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