diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5cd972bd9..e9e696730 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,7 +7,7 @@ PROJECT(GUACAMOLE CXX)
# version number
set(GUACAMOLE_MAJOR 0)
set(GUACAMOLE_MINOR 7)
-set(GUACAMOLE_PATCH 0)
+set(GUACAMOLE_PATCH 1)
set(GUACAMOLE_VERSION ${GUACAMOLE_MAJOR}.${GUACAMOLE_MINOR}.${GUACAMOLE_PATCH})
set(GUACAMOLE_DESCRIPTION "GUACAMOLE - an astonishing virtual reality engine")
set(GUACAMOLE_HOMEPAGE "http://www.GUACAMOLE.org")
diff --git a/include/gua/renderer/CompositePass.hpp b/include/gua/renderer/CompositePass.hpp
index 607518f9b..37793495c 100644
--- a/include/gua/renderer/CompositePass.hpp
+++ b/include/gua/renderer/CompositePass.hpp
@@ -1,88 +1,89 @@
-/******************************************************************************
- * guacamole - delicious VR *
- * *
- * Copyright: (c) 2011-2013 Bauhaus-Universität Weimar *
- * Contact: felix.lauer@uni-weimar.de / simon.schneegans@uni-weimar.de *
- * *
- * This program 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 3 of the License, or (at your option) *
- * any later version. *
- * *
- * This program 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 this program. If not, see . *
- * *
- ******************************************************************************/
-
-#ifndef GUA_COMPOSITE_PASS_HPP
-#define GUA_COMPOSITE_PASS_HPP
-
-// guacamole headers
-#include
-#include
-#include
-
-namespace gua {
-
-class GBuffer;
-
-/**
- *
- */
-class CompositePass : public Pass {
- public:
-
- /**
- *
- */
- CompositePass(Pipeline* pipeline);
-
- /**
- *
- */
- virtual ~CompositePass();
-
- virtual void create(RenderContext const& ctx,
- std::vector > const& layers);
-
- /* virtual */ LayerMapping const* get_gbuffer_mapping() const;
-
- void print_shaders(std::string const& directory,
- std::string const& name) const;
-
- bool pre_compile_shaders(RenderContext const& ctx);
-
- /* virtual */ void render_scene(Camera const& camera,
- SceneGraph const&,
- RenderContext const& ctx);
-
-protected :
-
- /* virtual */ void rendering( SerializedScene const& scene,
- RenderContext const& ctx,
- CameraMode eye,
- Camera const& camera,
- FrameBufferObject* target);
-
- void init_resources (RenderContext const& ctx);
-
- private:
-
- GBuffer* volume_raygeneration_buffer_;
-
- scm::gl::depth_stencil_state_ptr depth_stencil_state_;
- scm::gl::quad_geometry_ptr fullscreen_quad_;
-
- ShaderProgram* composite_shader_;
- ShaderProgram* ray_generation_shader_;
-};
-
-}
-
-#endif // GUA_COMPOSITE_PASS_HPP
+/******************************************************************************
+ * guacamole - delicious VR *
+ * *
+ * Copyright: (c) 2011-2013 Bauhaus-Universität Weimar *
+ * Contact: felix.lauer@uni-weimar.de / simon.schneegans@uni-weimar.de *
+ * *
+ * This program 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 3 of the License, or (at your option) *
+ * any later version. *
+ * *
+ * This program 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 this program. If not, see . *
+ * *
+ ******************************************************************************/
+
+#ifndef GUA_COMPOSITE_PASS_HPP
+#define GUA_COMPOSITE_PASS_HPP
+
+// guacamole headers
+#include
+#include
+#include
+
+namespace gua {
+
+class GBuffer;
+
+/**
+ *
+ */
+class CompositePass : public Pass {
+ public:
+
+ /**
+ *
+ */
+ CompositePass(Pipeline* pipeline);
+
+ /**
+ *
+ */
+ virtual ~CompositePass();
+
+ virtual void create(RenderContext const& ctx,
+ std::vector > const& layers);
+
+ /* virtual */ LayerMapping const* get_gbuffer_mapping() const;
+
+ void print_shaders(std::string const& directory,
+ std::string const& name) const;
+
+ bool pre_compile_shaders(RenderContext const& ctx);
+
+ /* virtual */ void render_scene(Camera const& camera,
+ SceneGraph const&,
+ RenderContext const& ctx,
+ std::size_t viewid);
+
+protected :
+
+ /* virtual */ void rendering( SerializedScene const& scene,
+ RenderContext const& ctx,
+ CameraMode eye,
+ Camera const& camera,
+ FrameBufferObject* target);
+
+ void init_resources (RenderContext const& ctx);
+
+ private:
+
+ GBuffer* volume_raygeneration_buffer_;
+
+ scm::gl::depth_stencil_state_ptr depth_stencil_state_;
+ scm::gl::quad_geometry_ptr fullscreen_quad_;
+
+ ShaderProgram* composite_shader_;
+ ShaderProgram* ray_generation_shader_;
+};
+
+}
+
+#endif // GUA_COMPOSITE_PASS_HPP
diff --git a/include/gua/renderer/FullscreenPass.hpp b/include/gua/renderer/FullscreenPass.hpp
index 9a445e35a..d74c13ce3 100644
--- a/include/gua/renderer/FullscreenPass.hpp
+++ b/include/gua/renderer/FullscreenPass.hpp
@@ -1,109 +1,109 @@
-/******************************************************************************
- * guacamole - delicious VR *
- * *
- * Copyright: (c) 2011-2013 Bauhaus-Universität Weimar *
- * Contact: felix.lauer@uni-weimar.de / simon.schneegans@uni-weimar.de *
- * *
- * This program 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 3 of the License, or (at your option) *
- * any later version. *
- * *
- * This program 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 this program. If not, see . *
- * *
- ******************************************************************************/
-
-#ifndef GUA_FULLSCREEN_PASS_HPP
-#define GUA_FULLSCREEN_PASS_HPP
-
-// guacamole headers
-#include
-
-// external headers
-#include
-#include
-
-namespace gua {
-
-class ShaderProgram;
-class SceneGraph;
-
-/**
- * A GeometryPass which automatically renders to a fullscreen quad.
- *
- * This is especially useful for deferred shading or other post
- * processing purposes.
- *
- * Render passes are part of a rendering pipeline. Basically they encapsulate
- * some FBOs to which the scene is rendered. The user has to add some color
- * buffers to this pass and a depth stencil buffer if desired. The scene is
- * rendered frome the point of view of a given camera through a given screen.
- * With render masks a part of the scene may be hidden.
- */
-class FullscreenPass : public Pass {
- public:
-
- /**
- *
- */
- FullscreenPass(Pipeline* pipeline);
-
- /**
- * Destructor.
- *
- * Deletes the FullscreenPass and frees all associated data.
- */
- virtual ~FullscreenPass();
-
- /**
- *
- */
- void render_scene(Camera const& camera, SceneGraph const&, RenderContext const& ctx);
-
- protected:
-
- /**
- *
- */
- virtual void set_uniforms(SerializedScene const& scene,
- RenderContext const& ctx) {}
-
- /**
- *
- */
- virtual void pre_rendering(Camera const& camera,
- SerializedScene const& scene,
- CameraMode eye,
- RenderContext const& ctx) {}
-
- /**
- *
- */
- virtual void rendering(Camera const& camera,
- SerializedScene const& scene,
- CameraMode eye,
- RenderContext const& ctx) = 0;
-
- /**
- *
- */
- virtual void post_rendering(Camera const& camera,
- SerializedScene const& scene,
- CameraMode eye,
- RenderContext const& ctx) {}
-
- scm::gl::quad_geometry_ptr fullscreen_quad_;
- scm::gl::depth_stencil_state_ptr depth_stencil_state_;
-
- private:
-};
-
-}
-
-#endif // GUA_FULLSCREEN_PASS_HPP
+/******************************************************************************
+ * guacamole - delicious VR *
+ * *
+ * Copyright: (c) 2011-2013 Bauhaus-Universität Weimar *
+ * Contact: felix.lauer@uni-weimar.de / simon.schneegans@uni-weimar.de *
+ * *
+ * This program 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 3 of the License, or (at your option) *
+ * any later version. *
+ * *
+ * This program 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 this program. If not, see . *
+ * *
+ ******************************************************************************/
+
+#ifndef GUA_FULLSCREEN_PASS_HPP
+#define GUA_FULLSCREEN_PASS_HPP
+
+// guacamole headers
+#include
+
+// external headers
+#include
+#include
+
+namespace gua {
+
+class ShaderProgram;
+class SceneGraph;
+
+/**
+ * A GeometryPass which automatically renders to a fullscreen quad.
+ *
+ * This is especially useful for deferred shading or other post
+ * processing purposes.
+ *
+ * Render passes are part of a rendering pipeline. Basically they encapsulate
+ * some FBOs to which the scene is rendered. The user has to add some color
+ * buffers to this pass and a depth stencil buffer if desired. The scene is
+ * rendered frome the point of view of a given camera through a given screen.
+ * With render masks a part of the scene may be hidden.
+ */
+class FullscreenPass : public Pass {
+ public:
+
+ /**
+ *
+ */
+ FullscreenPass(Pipeline* pipeline);
+
+ /**
+ * Destructor.
+ *
+ * Deletes the FullscreenPass and frees all associated data.
+ */
+ virtual ~FullscreenPass();
+
+ /**
+ *
+ */
+ void render_scene(Camera const& camera, SceneGraph const&, RenderContext const& ctx, std::size_t viewid);
+
+ protected:
+
+ /**
+ *
+ */
+ virtual void set_uniforms(SerializedScene const& scene,
+ RenderContext const& ctx) {}
+
+ /**
+ *
+ */
+ virtual void pre_rendering(Camera const& camera,
+ SerializedScene const& scene,
+ CameraMode eye,
+ RenderContext const& ctx) {}
+
+ /**
+ *
+ */
+ virtual void rendering(Camera const& camera,
+ SerializedScene const& scene,
+ CameraMode eye,
+ RenderContext const& ctx) = 0;
+
+ /**
+ *
+ */
+ virtual void post_rendering(Camera const& camera,
+ SerializedScene const& scene,
+ CameraMode eye,
+ RenderContext const& ctx) {}
+
+ scm::gl::quad_geometry_ptr fullscreen_quad_;
+ scm::gl::depth_stencil_state_ptr depth_stencil_state_;
+
+ private:
+};
+
+}
+
+#endif // GUA_FULLSCREEN_PASS_HPP
diff --git a/include/gua/renderer/GBufferPass.hpp b/include/gua/renderer/GBufferPass.hpp
index 118e3f08e..bcaf5b481 100644
--- a/include/gua/renderer/GBufferPass.hpp
+++ b/include/gua/renderer/GBufferPass.hpp
@@ -74,15 +74,19 @@ class GBufferPass : public GeometryPass {
RenderContext const& ctx,
CameraMode eye,
Camera const& camera,
- FrameBufferObject* target);
+ FrameBufferObject* target,
+ std::size_t viewid);
void display_bboxes(RenderContext const& ctx,
- SerializedScene const& scene);
+ SerializedScene const& scene,
+ std::size_t viewid);
void display_rays (RenderContext const& ctx,
- SerializedScene const& scene);
+ SerializedScene const& scene,
+ std::size_t viewid);
void display_quads (RenderContext const& ctx,
SerializedScene const& scene,
- CameraMode eye);
+ CameraMode eye,
+ std::size_t viewid);
void update_ubershader_from_scene(SerializedScene const& scene,
SceneGraph const& graph);
diff --git a/include/gua/renderer/GeometryPass.hpp b/include/gua/renderer/GeometryPass.hpp
index 990e5d31b..07c4cccf6 100644
--- a/include/gua/renderer/GeometryPass.hpp
+++ b/include/gua/renderer/GeometryPass.hpp
@@ -58,7 +58,8 @@ class GeometryPass : public Pass {
virtual void render_scene(Camera const& camera,
SceneGraph const& current_graph,
- RenderContext const& ctx);
+ RenderContext const& ctx,
+ std::size_t viewid);
protected:
virtual void rendering(SerializedScene const& scene,
@@ -66,7 +67,8 @@ class GeometryPass : public Pass {
RenderContext const& ctx,
CameraMode eye,
Camera const& camera,
- FrameBufferObject* target) = 0;
+ FrameBufferObject* target,
+ std::size_t viewid) = 0;
private:
};
diff --git a/include/gua/renderer/GeometryUberShader.hpp b/include/gua/renderer/GeometryUberShader.hpp
index 6c203486e..ebbde7c05 100644
--- a/include/gua/renderer/GeometryUberShader.hpp
+++ b/include/gua/renderer/GeometryUberShader.hpp
@@ -85,7 +85,8 @@ class GeometryUberShader : public UberShader {
std::string const& material,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& frustum) const = 0;
+ Frustum const& frustum,
+ std::size_t viewid ) const = 0;
/**
* This method is called for ONCE per drawable to perform draw operations
@@ -97,7 +98,8 @@ class GeometryUberShader : public UberShader {
std::string const& material,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& frustum) const = 0;
+ Frustum const& frustum,
+ std::size_t viewid) const = 0;
/**
* This method is called for ONCE per drawable to perform postdraw operations
@@ -109,7 +111,8 @@ class GeometryUberShader : public UberShader {
std::string const& material,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& frustum) const = 0;
+ Frustum const& frustum,
+ std::size_t viewid) const = 0;
/**
* This callback is called ONCE per frame AFTER rendering all drawables of this type
diff --git a/include/gua/renderer/LightingPass.hpp b/include/gua/renderer/LightingPass.hpp
index bcfb2748e..70ce747bc 100644
--- a/include/gua/renderer/LightingPass.hpp
+++ b/include/gua/renderer/LightingPass.hpp
@@ -74,7 +74,8 @@ class LightingPass : public GeometryPass {
RenderContext const& ctx,
CameraMode eye,
Camera const& camera,
- FrameBufferObject* target);
+ FrameBufferObject* target,
+ std::size_t viewid);
void init_resources(RenderContext const& ctx);
diff --git a/include/gua/renderer/NURBSUberShader.hpp b/include/gua/renderer/NURBSUberShader.hpp
index dc2f5d32a..b426c1c4e 100644
--- a/include/gua/renderer/NURBSUberShader.hpp
+++ b/include/gua/renderer/NURBSUberShader.hpp
@@ -52,21 +52,24 @@ class NURBSUberShader : public GeometryUberShader {
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& /*frustum*/) const;
+ Frustum const& /*frustum*/,
+ std::size_t /*viewid*/) const;
/*virtual*/ void draw (RenderContext const& ctx,
std::string const& ksfile_name,
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& /*frustum*/) const;
+ Frustum const& /*frustum*/,
+ std::size_t /*viewid*/) const;
/*virtual*/ void postdraw (RenderContext const& ctx,
std::string const& ksfile_name,
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& /*frustum*/) const;
+ Frustum const& /*frustum*/,
+ std::size_t /*viewid*/) const;
/*virtual*/ void postframe(RenderContext const& ctx) const;
diff --git a/include/gua/renderer/Pass.hpp b/include/gua/renderer/Pass.hpp
index 7d6315107..faee2ca3f 100644
--- a/include/gua/renderer/Pass.hpp
+++ b/include/gua/renderer/Pass.hpp
@@ -66,7 +66,8 @@ class Pass {
virtual void render_scene(Camera const& camera,
SceneGraph const& current_graph,
- RenderContext const& ctx) = 0;
+ RenderContext const& ctx,
+ std::size_t unique_view_id) = 0;
// not strictly necessary to call, but recommend
// to avoid crashes on shader compilation
diff --git a/include/gua/renderer/Pipeline.hpp b/include/gua/renderer/Pipeline.hpp
index 104476015..9c9ac45d2 100644
--- a/include/gua/renderer/Pipeline.hpp
+++ b/include/gua/renderer/Pipeline.hpp
@@ -185,6 +185,10 @@ class GUA_DLL Pipeline {
SerializedScene const& get_current_scene(CameraMode mode) const;
+ inline std::size_t uuid() const {
+ return reinterpret_cast(this);
+ }
+
friend class Renderer;
private:
diff --git a/include/gua/renderer/PostFXPass.hpp b/include/gua/renderer/PostFXPass.hpp
index 0cb40f30f..e36d1a599 100644
--- a/include/gua/renderer/PostFXPass.hpp
+++ b/include/gua/renderer/PostFXPass.hpp
@@ -56,7 +56,7 @@ class PostFXPass : public Pass {
virtual void cleanup(RenderContext const& ctx);
- void render_scene(Camera const& camera, SceneGraph const&, RenderContext const& ctx);
+ void render_scene(Camera const& camera, SceneGraph const&, RenderContext const& ctx, std::size_t viewid);
/* virtual */ LayerMapping const* get_gbuffer_mapping() const;
diff --git a/include/gua/renderer/ShadowMap.hpp b/include/gua/renderer/ShadowMap.hpp
index 846ca260d..2b5238e15 100644
--- a/include/gua/renderer/ShadowMap.hpp
+++ b/include/gua/renderer/ShadowMap.hpp
@@ -82,6 +82,8 @@ class ShadowMap {
virtual void cleanup(RenderContext const& context);
+ inline std::size_t const uuid() const { return reinterpret_cast(buffer_); }
+
private:
void update_members(RenderContext const& ctx, unsigned map_size);
diff --git a/include/gua/renderer/TriMeshUberShader.hpp b/include/gua/renderer/TriMeshUberShader.hpp
index 935cf2cd7..bed35daec 100644
--- a/include/gua/renderer/TriMeshUberShader.hpp
+++ b/include/gua/renderer/TriMeshUberShader.hpp
@@ -42,21 +42,24 @@ class TriMeshUberShader : public GeometryUberShader {
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& /*frustum*/) const;
+ Frustum const& /*frustum*/,
+ std::size_t /*viewid*/) const;
/*virtual*/ void draw (RenderContext const& ctx,
std::string const& filename,
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& /*frustum*/) const;
+ Frustum const& /*frustum*/,
+ std::size_t /*viewid*/) const;
/*virtual*/ void postdraw (RenderContext const& ctx,
std::string const& filename,
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& /*frustum*/) const;
+ Frustum const& /*frustum*/,
+ std::size_t /*viewid*/) const;
/*virtual*/ void postframe (RenderContext const& context) const;
};
diff --git a/include/gua/renderer/Video3DUberShader.hpp b/include/gua/renderer/Video3DUberShader.hpp
index 688e67bdb..8b7d193fb 100644
--- a/include/gua/renderer/Video3DUberShader.hpp
+++ b/include/gua/renderer/Video3DUberShader.hpp
@@ -58,21 +58,24 @@ class GUA_DLL Video3DUberShader : public GeometryUberShader {
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& frustum) const;
+ Frustum const& frustum,
+ std::size_t viewid) const;
/*virtual*/ void draw (RenderContext const& context,
std::string const& ksfile_name,
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& frustum) const;
+ Frustum const& frustum,
+ std::size_t viewid) const;
/*virtual*/ void postdraw(RenderContext const& context,
std::string const& ksfile_name,
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& frustum) const;
+ Frustum const& frustum,
+ std::size_t viewid) const;
/*virtual*/ void postframe(RenderContext const& context) const;
@@ -100,6 +103,7 @@ class GUA_DLL Video3DUberShader : public GeometryUberShader {
mutable std::vector warp_color_result_;
mutable std::vector warp_result_fbo_;
+ mutable std::vector no_bfc_rasterizer_state_;
mutable std::vector nearest_sampler_state_;
mutable std::vector linear_sampler_state_;
diff --git a/include/gua/scenegraph/GeometryNode.hpp b/include/gua/scenegraph/GeometryNode.hpp
index b4c0dc9c7..8812c7aa1 100644
--- a/include/gua/scenegraph/GeometryNode.hpp
+++ b/include/gua/scenegraph/GeometryNode.hpp
@@ -99,6 +99,8 @@ class GUA_DLL GeometryNode : public Node {
*/
virtual void update_bounding_box() const;
+ inline virtual void update_cache() { Node::update_cache(); }
+
/**
* Accepts a visitor and calls concrete visit method.
*
@@ -112,13 +114,12 @@ class GUA_DLL GeometryNode : public Node {
virtual std::shared_ptr copy() const = 0;
- virtual void cache_material() const;
-
std::string filename_;
std::string material_;
ShadowMode shadow_mode_;
- bool filename_changed_; bool material_changed_;
+ bool filename_changed_;
+ bool material_changed_;
};
}
diff --git a/include/gua/scenegraph/NURBSNode.hpp b/include/gua/scenegraph/NURBSNode.hpp
index a1c14c591..4f9f67e35 100644
--- a/include/gua/scenegraph/NURBSNode.hpp
+++ b/include/gua/scenegraph/NURBSNode.hpp
@@ -48,9 +48,12 @@ public : // member
PickResult::Options options,
Mask const& mask,
std::set& hits);
+
+ /* virtual */ void update_cache();
+
protected:
- /*virtual*/ std::shared_ptr copy() const;
+ /* virtual */ std::shared_ptr copy() const;
private : // attributes e.g. special attributes for drawing
diff --git a/include/gua/scenegraph/Video3DNode.hpp b/include/gua/scenegraph/Video3DNode.hpp
index add44393d..67367c968 100644
--- a/include/gua/scenegraph/Video3DNode.hpp
+++ b/include/gua/scenegraph/Video3DNode.hpp
@@ -51,6 +51,8 @@ class GUA_DLL Video3DNode : public GeometryNode {
Mask const& mask,
std::set& hits);
+ /* virtual */ void update_cache();
+
protected:
/*virtual*/ std::shared_ptr copy() const;
diff --git a/src/gua/databases/MaterialDatabase.cpp b/src/gua/databases/MaterialDatabase.cpp
index b282d357d..74922f4d8 100644
--- a/src/gua/databases/MaterialDatabase.cpp
+++ b/src/gua/databases/MaterialDatabase.cpp
@@ -54,10 +54,7 @@ void MaterialDatabase::load_material(std::string const& filename) {
if (!instance()->is_supported(filename)) {
auto mat = std::make_shared(filename, filename);
instance()->add(filename, mat);
- std::cout << "MaterialDatabase::load_material() : loading " << filename << std::endl;
- }
- else {
- std::cout << "MaterialDatabase::load_material() : material not supported " << filename << std::endl;
+ Logger::LOG_MESSAGE << "MaterialDatabase::load_material() : loading " << filename << std::endl;
}
}
diff --git a/src/gua/renderer/CompositePass.cpp b/src/gua/renderer/CompositePass.cpp
index fc756966e..52047496b 100644
--- a/src/gua/renderer/CompositePass.cpp
+++ b/src/gua/renderer/CompositePass.cpp
@@ -1,281 +1,282 @@
-/******************************************************************************
- * guacamole - delicious VR *
- * *
- * Copyright: (c) 2011-2013 Bauhaus-Universität Weimar *
- * Contact: felix.lauer@uni-weimar.de / simon.schneegans@uni-weimar.de *
- * *
- * This program 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 3 of the License, or (at your option) *
- * any later version. *
- * *
- * This program 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 this program. If not, see . *
- * *
- ******************************************************************************/
-
-// class header
-#include
-
-// guacamole headers
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-namespace gua {
-
-////////////////////////////////////////////////////////////////////////////////
-
-CompositePass::CompositePass(Pipeline* pipeline) :
- Pass(pipeline),
- composite_shader_(new ShaderProgram),
- ray_generation_shader_(new ShaderProgram),
- volume_raygeneration_buffer_(nullptr)
-{
- std::string vertex_shader (Resources::lookup_shader(Resources::shaders_uber_shaders_composite_compose_vert));
- std::string fragment_shader(Resources::lookup_shader(Resources::shaders_uber_shaders_composite_compose_frag));
-
- composite_shader_->create_from_sources(vertex_shader, fragment_shader);
-
- std::string ray_generation_vertex_shader(Resources::lookup_shader(Resources::shaders_uber_shaders_composite_ray_generation_vert));
- std::string ray_generation_fragment_shader(Resources::lookup_shader(Resources::shaders_uber_shaders_composite_ray_generation_frag));
-
- ray_generation_shader_->create_from_sources(ray_generation_vertex_shader, ray_generation_fragment_shader);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-CompositePass::~CompositePass() {
-
- if (composite_shader_) {
- delete composite_shader_;
- }
-
- if (volume_raygeneration_buffer_) {
- delete volume_raygeneration_buffer_;
- }
-
- if (ray_generation_shader_) {
- delete ray_generation_shader_;
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void CompositePass::create(RenderContext const& ctx, std::vector> const& layers) {
-
- // reuse gbuffer from shading-pass
- gbuffer_ = inputs_[Pipeline::PipelineStage::shading];
- /*scm::gl::sampler_state_desc tmp(scm::gl::FILTER_MIN_MAG_LINEAR,
- scm::gl::WRAP_CLAMP_TO_EDGE,
- scm::gl::WRAP_CLAMP_TO_EDGE);
- Pass::create(ctx, config, { { BufferComponent::F3, tmp } });*/
-
-
- if (volume_raygeneration_buffer_) {
- volume_raygeneration_buffer_->remove_buffers(ctx);
- delete volume_raygeneration_buffer_;
- }
-
- scm::gl::sampler_state_desc state(scm::gl::FILTER_MIN_MAG_LINEAR,
- scm::gl::WRAP_CLAMP_TO_EDGE,
- scm::gl::WRAP_CLAMP_TO_EDGE);
-
- std::vector> layer_3f_desc;
- layer_3f_desc.push_back(std::make_pair(BufferComponent::F3, state));
-
- volume_raygeneration_buffer_ = new GBuffer(layer_3f_desc,
- pipeline_->config.get_left_resolution()[0],
- pipeline_->config.get_left_resolution()[1]);
- volume_raygeneration_buffer_->create(ctx);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-/* virtual */ void CompositePass::rendering(SerializedScene const& scene,
- RenderContext const& ctx,
- CameraMode eye,
- Camera const& camera,
- FrameBufferObject* target)
-{
- init_resources(ctx);
-
- ctx.render_context->set_depth_stencil_state(depth_stencil_state_);
-
- // 1. render proxy geometry into fbo
- volume_raygeneration_buffer_->bind(ctx);
- {
- scm::math::vec2f resolution(volume_raygeneration_buffer_->width(), volume_raygeneration_buffer_->height());
- ctx.render_context->set_viewport(scm::gl::viewport(math::vec2(0, 0), resolution));
-
- volume_raygeneration_buffer_->clear_color_buffers(ctx, gua::utils::Color3f(0.0f, 0.0f, 0.0f));
- volume_raygeneration_buffer_->clear_depth_stencil_buffer(ctx);
-
- ///TODO: Toplevel
- if (!scene.volumenodes_.empty())
- {
- // gather input textures and set uniforms
- Pass::set_camera_matrices(*ray_generation_shader_, camera, pipeline_->get_current_scene(eye), eye, ctx);
-
- ray_generation_shader_->set_uniform(ctx, 1.f / gbuffer_->get_eye_buffers()[eye == CameraMode::RIGHT ? 1 : 0]->width(), "gua_texel_width");
- ray_generation_shader_->set_uniform(ctx, 1.f / gbuffer_->get_eye_buffers()[eye == CameraMode::RIGHT ? 1 : 0]->height(), "gua_texel_height");
-
-
- volume_raygeneration_buffer_->clear_color_buffers(ctx, gua::utils::Color3f(0.0f, 0.0f, 0.0f));
- volume_raygeneration_buffer_->clear_depth_stencil_buffer(ctx);
-
- for (auto const& node : scene.volumenodes_) {
-
- auto volume =
- std::static_pointer_cast(GeometryDatabase::instance()->lookup(node->data.get_volume()));
-
- if (volume) {
- ray_generation_shader_->set_uniform(
- ctx, node->get_world_transform(), "gua_model_matrix");
-
- ray_generation_shader_->set_uniform(
- ctx, 0, "volume_frag_id");
-
- ray_generation_shader_->use(ctx);
- {
- volume->draw_proxy(ctx);
- }
- ray_generation_shader_->unuse(ctx);
- }
- }
- }
- }
- volume_raygeneration_buffer_->unbind(ctx);
-
- scm::gl::context_all_guard cug(ctx.render_context);
-
- // 2. render fullscreen quad for compositing and volume ray castinG
- Pass::set_camera_matrices(*composite_shader_, camera, pipeline_->get_current_scene(eye), eye, ctx);
-
- auto input_tex(inputs_[Pipeline::shading]->get_eye_buffers()[eye == CameraMode::RIGHT ? 1 : 0]->get_color_buffers(TYPE_FLOAT)[0]);
- auto normal_tex(inputs_[Pipeline::geometry]->get_eye_buffers()[eye == CameraMode::RIGHT ? 1 : 0]->get_color_buffers(TYPE_FLOAT)[0]);
- auto depth_tex(inputs_[Pipeline::geometry]->get_eye_buffers()[eye == CameraMode::RIGHT ? 1 : 0]->get_depth_buffer());
-
- auto raygen_tex(volume_raygeneration_buffer_->get_color_buffers(TYPE_FLOAT)[0]);
-
- composite_shader_->set_uniform(ctx, input_tex, "gua_color_gbuffer_in");
- composite_shader_->set_uniform(ctx, normal_tex, "gua_normal_gbuffer_in");
- composite_shader_->set_uniform(ctx, depth_tex, "gua_depth_gbuffer_in");
- composite_shader_->set_uniform(ctx, raygen_tex, "gua_ray_entry_in");
-
- composite_shader_->set_uniform(ctx, 1.f / gbuffer_->get_eye_buffers()[eye == CameraMode::RIGHT ? 1 : 0]->width(), "gua_texel_width");
- composite_shader_->set_uniform(ctx, 1.f / gbuffer_->get_eye_buffers()[eye == CameraMode::RIGHT ? 1 : 0]->height(), "gua_texel_height");
-
- // bind target fbo and set viewport
- target->bind(ctx);
- ctx.render_context->set_viewport(scm::gl::viewport(
- math::vec2(0, 0),
- ::scm::math::vec2f(target->width(), target->height())));
-
- if (!scene.volumenodes_.empty()){
-
- for (auto const& node : scene.volumenodes_) {
-
- auto volume =
- std::static_pointer_cast(GeometryDatabase::instance()->lookup(node->data.get_volume()));
-
- if (volume) {
- composite_shader_->set_uniform(
- ctx, node->get_world_transform(), "gua_model_matrix");
-
- volume->set_uniforms(ctx, composite_shader_);
-
- composite_shader_->use(ctx);
- {
- fullscreen_quad_->draw(ctx.render_context);
- }
- composite_shader_->unuse(ctx);
- }
- }
-
- }
-
- target->unbind(ctx);
-
- ctx.render_context->reset_state_objects();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void CompositePass::init_resources(RenderContext const& ctx) {
- if (!initialized_) {
- if (!depth_stencil_state_) {
- depth_stencil_state_ = ctx.render_device->create_depth_stencil_state(false, false, scm::gl::COMPARISON_NEVER);
- }
-
- if (!fullscreen_quad_) {
- fullscreen_quad_ = scm::gl::quad_geometry_ptr(new scm::gl::quad_geometry(ctx.render_device, math::vec2(-1.f, -1.f), math::vec2(1.f, 1.f)));
- }
- initialized_ = true;
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-/* virtual */ LayerMapping const* CompositePass::get_gbuffer_mapping() const {
- throw std::runtime_error("no gbuffer mapping available for composite pass");
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void CompositePass::print_shaders(std::string const& directory,
- std::string const& name) const {
- composite_shader_->save_to_file(directory, name + "/composite_shader");
- ray_generation_shader_->save_to_file(directory, name + "/ray_generation_shader");
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-bool CompositePass::pre_compile_shaders(RenderContext const& ctx) {
-
- if (composite_shader_) return composite_shader_->upload_to(ctx);
- if (ray_generation_shader_) return ray_generation_shader_->upload_to(ctx);
-
- return false;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void CompositePass::render_scene(Camera const& camera,
- SceneGraph const&,
- RenderContext const& ctx) {
-
- for (int i(0); i < gbuffer_->get_eye_buffers().size(); ++i) {
-
- FrameBufferObject* fbo(gbuffer_->get_eye_buffers()[i]);
-
- CameraMode eye(CameraMode::CENTER);
- if (gbuffer_->get_eye_buffers().size() > 1 && i == 0)
- eye = CameraMode::LEFT;
- if (gbuffer_->get_eye_buffers().size() > 1 && i == 1)
- eye = CameraMode::RIGHT;
-
- fbo->bind(ctx);
-
- ctx.render_context->set_viewport(scm::gl::viewport(
- math::vec2(0, 0), ::scm::math::vec2f(fbo->width(), fbo->height())));
-
- rendering(pipeline_->get_current_scene(eye), ctx, eye, camera, fbo);
-
- fbo->unbind(ctx);
- }
-}
-
-}
+/******************************************************************************
+ * guacamole - delicious VR *
+ * *
+ * Copyright: (c) 2011-2013 Bauhaus-Universität Weimar *
+ * Contact: felix.lauer@uni-weimar.de / simon.schneegans@uni-weimar.de *
+ * *
+ * This program 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 3 of the License, or (at your option) *
+ * any later version. *
+ * *
+ * This program 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 this program. If not, see . *
+ * *
+ ******************************************************************************/
+
+// class header
+#include
+
+// guacamole headers
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+namespace gua {
+
+////////////////////////////////////////////////////////////////////////////////
+
+CompositePass::CompositePass(Pipeline* pipeline) :
+ Pass(pipeline),
+ composite_shader_(new ShaderProgram),
+ ray_generation_shader_(new ShaderProgram),
+ volume_raygeneration_buffer_(nullptr)
+{
+ std::string vertex_shader (Resources::lookup_shader(Resources::shaders_uber_shaders_composite_compose_vert));
+ std::string fragment_shader(Resources::lookup_shader(Resources::shaders_uber_shaders_composite_compose_frag));
+
+ composite_shader_->create_from_sources(vertex_shader, fragment_shader);
+
+ std::string ray_generation_vertex_shader(Resources::lookup_shader(Resources::shaders_uber_shaders_composite_ray_generation_vert));
+ std::string ray_generation_fragment_shader(Resources::lookup_shader(Resources::shaders_uber_shaders_composite_ray_generation_frag));
+
+ ray_generation_shader_->create_from_sources(ray_generation_vertex_shader, ray_generation_fragment_shader);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+CompositePass::~CompositePass() {
+
+ if (composite_shader_) {
+ delete composite_shader_;
+ }
+
+ if (volume_raygeneration_buffer_) {
+ delete volume_raygeneration_buffer_;
+ }
+
+ if (ray_generation_shader_) {
+ delete ray_generation_shader_;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void CompositePass::create(RenderContext const& ctx, std::vector> const& layers) {
+
+ // reuse gbuffer from shading-pass
+ gbuffer_ = inputs_[Pipeline::PipelineStage::shading];
+ /*scm::gl::sampler_state_desc tmp(scm::gl::FILTER_MIN_MAG_LINEAR,
+ scm::gl::WRAP_CLAMP_TO_EDGE,
+ scm::gl::WRAP_CLAMP_TO_EDGE);
+ Pass::create(ctx, config, { { BufferComponent::F3, tmp } });*/
+
+
+ if (volume_raygeneration_buffer_) {
+ volume_raygeneration_buffer_->remove_buffers(ctx);
+ delete volume_raygeneration_buffer_;
+ }
+
+ scm::gl::sampler_state_desc state(scm::gl::FILTER_MIN_MAG_LINEAR,
+ scm::gl::WRAP_CLAMP_TO_EDGE,
+ scm::gl::WRAP_CLAMP_TO_EDGE);
+
+ std::vector> layer_3f_desc;
+ layer_3f_desc.push_back(std::make_pair(BufferComponent::F3, state));
+
+ volume_raygeneration_buffer_ = new GBuffer(layer_3f_desc,
+ pipeline_->config.get_left_resolution()[0],
+ pipeline_->config.get_left_resolution()[1]);
+ volume_raygeneration_buffer_->create(ctx);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/* virtual */ void CompositePass::rendering(SerializedScene const& scene,
+ RenderContext const& ctx,
+ CameraMode eye,
+ Camera const& camera,
+ FrameBufferObject* target)
+{
+ init_resources(ctx);
+
+ ctx.render_context->set_depth_stencil_state(depth_stencil_state_);
+
+ // 1. render proxy geometry into fbo
+ volume_raygeneration_buffer_->bind(ctx);
+ {
+ scm::math::vec2f resolution(volume_raygeneration_buffer_->width(), volume_raygeneration_buffer_->height());
+ ctx.render_context->set_viewport(scm::gl::viewport(math::vec2(0, 0), resolution));
+
+ volume_raygeneration_buffer_->clear_color_buffers(ctx, gua::utils::Color3f(0.0f, 0.0f, 0.0f));
+ volume_raygeneration_buffer_->clear_depth_stencil_buffer(ctx);
+
+ ///TODO: Toplevel
+ if (!scene.volumenodes_.empty())
+ {
+ // gather input textures and set uniforms
+ Pass::set_camera_matrices(*ray_generation_shader_, camera, pipeline_->get_current_scene(eye), eye, ctx);
+
+ ray_generation_shader_->set_uniform(ctx, 1.f / gbuffer_->get_eye_buffers()[eye == CameraMode::RIGHT ? 1 : 0]->width(), "gua_texel_width");
+ ray_generation_shader_->set_uniform(ctx, 1.f / gbuffer_->get_eye_buffers()[eye == CameraMode::RIGHT ? 1 : 0]->height(), "gua_texel_height");
+
+
+ volume_raygeneration_buffer_->clear_color_buffers(ctx, gua::utils::Color3f(0.0f, 0.0f, 0.0f));
+ volume_raygeneration_buffer_->clear_depth_stencil_buffer(ctx);
+
+ for (auto const& node : scene.volumenodes_) {
+
+ auto volume =
+ std::static_pointer_cast(GeometryDatabase::instance()->lookup(node->data.get_volume()));
+
+ if (volume) {
+ ray_generation_shader_->set_uniform(
+ ctx, node->get_world_transform(), "gua_model_matrix");
+
+ ray_generation_shader_->set_uniform(
+ ctx, 0, "volume_frag_id");
+
+ ray_generation_shader_->use(ctx);
+ {
+ volume->draw_proxy(ctx);
+ }
+ ray_generation_shader_->unuse(ctx);
+ }
+ }
+ }
+ }
+ volume_raygeneration_buffer_->unbind(ctx);
+
+ scm::gl::context_all_guard cug(ctx.render_context);
+
+ // 2. render fullscreen quad for compositing and volume ray castinG
+ Pass::set_camera_matrices(*composite_shader_, camera, pipeline_->get_current_scene(eye), eye, ctx);
+
+ auto input_tex(inputs_[Pipeline::shading]->get_eye_buffers()[eye == CameraMode::RIGHT ? 1 : 0]->get_color_buffers(TYPE_FLOAT)[0]);
+ auto normal_tex(inputs_[Pipeline::geometry]->get_eye_buffers()[eye == CameraMode::RIGHT ? 1 : 0]->get_color_buffers(TYPE_FLOAT)[0]);
+ auto depth_tex(inputs_[Pipeline::geometry]->get_eye_buffers()[eye == CameraMode::RIGHT ? 1 : 0]->get_depth_buffer());
+
+ auto raygen_tex(volume_raygeneration_buffer_->get_color_buffers(TYPE_FLOAT)[0]);
+
+ composite_shader_->set_uniform(ctx, input_tex, "gua_color_gbuffer_in");
+ composite_shader_->set_uniform(ctx, normal_tex, "gua_normal_gbuffer_in");
+ composite_shader_->set_uniform(ctx, depth_tex, "gua_depth_gbuffer_in");
+ composite_shader_->set_uniform(ctx, raygen_tex, "gua_ray_entry_in");
+
+ composite_shader_->set_uniform(ctx, 1.f / gbuffer_->get_eye_buffers()[eye == CameraMode::RIGHT ? 1 : 0]->width(), "gua_texel_width");
+ composite_shader_->set_uniform(ctx, 1.f / gbuffer_->get_eye_buffers()[eye == CameraMode::RIGHT ? 1 : 0]->height(), "gua_texel_height");
+
+ // bind target fbo and set viewport
+ target->bind(ctx);
+ ctx.render_context->set_viewport(scm::gl::viewport(
+ math::vec2(0, 0),
+ ::scm::math::vec2f(target->width(), target->height())));
+
+ if (!scene.volumenodes_.empty()){
+
+ for (auto const& node : scene.volumenodes_) {
+
+ auto volume =
+ std::static_pointer_cast(GeometryDatabase::instance()->lookup(node->data.get_volume()));
+
+ if (volume) {
+ composite_shader_->set_uniform(
+ ctx, node->get_world_transform(), "gua_model_matrix");
+
+ volume->set_uniforms(ctx, composite_shader_);
+
+ composite_shader_->use(ctx);
+ {
+ fullscreen_quad_->draw(ctx.render_context);
+ }
+ composite_shader_->unuse(ctx);
+ }
+ }
+
+ }
+
+ target->unbind(ctx);
+
+ ctx.render_context->reset_state_objects();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void CompositePass::init_resources(RenderContext const& ctx) {
+ if (!initialized_) {
+ if (!depth_stencil_state_) {
+ depth_stencil_state_ = ctx.render_device->create_depth_stencil_state(false, false, scm::gl::COMPARISON_NEVER);
+ }
+
+ if (!fullscreen_quad_) {
+ fullscreen_quad_ = scm::gl::quad_geometry_ptr(new scm::gl::quad_geometry(ctx.render_device, math::vec2(-1.f, -1.f), math::vec2(1.f, 1.f)));
+ }
+ initialized_ = true;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/* virtual */ LayerMapping const* CompositePass::get_gbuffer_mapping() const {
+ throw std::runtime_error("no gbuffer mapping available for composite pass");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void CompositePass::print_shaders(std::string const& directory,
+ std::string const& name) const {
+ composite_shader_->save_to_file(directory, name + "/composite_shader");
+ ray_generation_shader_->save_to_file(directory, name + "/ray_generation_shader");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool CompositePass::pre_compile_shaders(RenderContext const& ctx) {
+
+ if (composite_shader_) return composite_shader_->upload_to(ctx);
+ if (ray_generation_shader_) return ray_generation_shader_->upload_to(ctx);
+
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void CompositePass::render_scene(Camera const& camera,
+ SceneGraph const&,
+ RenderContext const& ctx,
+ std::size_t viewid) {
+
+ for (int i(0); i < gbuffer_->get_eye_buffers().size(); ++i) {
+
+ FrameBufferObject* fbo(gbuffer_->get_eye_buffers()[i]);
+
+ CameraMode eye(CameraMode::CENTER);
+ if (gbuffer_->get_eye_buffers().size() > 1 && i == 0)
+ eye = CameraMode::LEFT;
+ if (gbuffer_->get_eye_buffers().size() > 1 && i == 1)
+ eye = CameraMode::RIGHT;
+
+ fbo->bind(ctx);
+
+ ctx.render_context->set_viewport(scm::gl::viewport(
+ math::vec2(0, 0), ::scm::math::vec2f(fbo->width(), fbo->height())));
+
+ rendering(pipeline_->get_current_scene(eye), ctx, eye, camera, fbo);
+
+ fbo->unbind(ctx);
+ }
+}
+
+}
diff --git a/src/gua/renderer/FullscreenPass.cpp b/src/gua/renderer/FullscreenPass.cpp
index 164047169..9a7980530 100644
--- a/src/gua/renderer/FullscreenPass.cpp
+++ b/src/gua/renderer/FullscreenPass.cpp
@@ -1,88 +1,89 @@
-/******************************************************************************
- * guacamole - delicious VR *
- * *
- * Copyright: (c) 2011-2013 Bauhaus-Universität Weimar *
- * Contact: felix.lauer@uni-weimar.de / simon.schneegans@uni-weimar.de *
- * *
- * This program 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 3 of the License, or (at your option) *
- * any later version. *
- * *
- * This program 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 this program. If not, see . *
- * *
- ******************************************************************************/
-
-// class header
-#include
-
-// guacamole headers
-#include
-#include
-#include
-#include
-#include
-
-namespace gua {
-
-////////////////////////////////////////////////////////////////////////////////
-
-FullscreenPass::FullscreenPass(Pipeline* pipeline)
- : Pass(pipeline), fullscreen_quad_(), depth_stencil_state_() {}
-
-////////////////////////////////////////////////////////////////////////////////
-
-FullscreenPass::~FullscreenPass() {}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void FullscreenPass::render_scene(Camera const& camera,
- SceneGraph const&,
- RenderContext const& ctx) {
-
- if (!depth_stencil_state_)
- depth_stencil_state_ = ctx.render_device
- ->create_depth_stencil_state(false, false, scm::gl::COMPARISON_NEVER);
-
- if (!fullscreen_quad_)
- fullscreen_quad_ = scm::gl::quad_geometry_ptr(new scm::gl::quad_geometry(
- ctx.render_device, math::vec2(-1.f, -1.f), math::vec2(1.f, 1.f)));
- set_uniforms(pipeline_->get_current_scene(CameraMode::CENTER), ctx);
-
- for (int i(0); i < gbuffer_->get_eye_buffers().size(); ++i) {
- CameraMode eye(CameraMode::CENTER);
-
- if (gbuffer_->get_eye_buffers().size() > 1 && i == 0)
- eye = CameraMode::LEFT;
- if (gbuffer_->get_eye_buffers().size() > 1 && i == 1)
- eye = CameraMode::RIGHT;
-
- pre_rendering(camera, pipeline_->get_current_scene(eye), eye, ctx);
-
- FrameBufferObject* fbo(gbuffer_->get_eye_buffers()[i]);
- fbo->bind(ctx);
-
- ctx.render_context->set_viewport(scm::gl::viewport(
- math::vec2(0, 0), math::vec2(float(fbo->width()), float(fbo->height()))));
- ctx.render_context->set_depth_stencil_state(depth_stencil_state_);
-
- rendering(camera, pipeline_->get_current_scene(eye), eye, ctx);
-
- ctx.render_context->reset_state_objects();
-
- fbo->unbind(ctx);
-
- post_rendering(camera, pipeline_->get_current_scene(eye), eye, ctx);
- }
-
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-}
+/******************************************************************************
+ * guacamole - delicious VR *
+ * *
+ * Copyright: (c) 2011-2013 Bauhaus-Universität Weimar *
+ * Contact: felix.lauer@uni-weimar.de / simon.schneegans@uni-weimar.de *
+ * *
+ * This program 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 3 of the License, or (at your option) *
+ * any later version. *
+ * *
+ * This program 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 this program. If not, see . *
+ * *
+ ******************************************************************************/
+
+// class header
+#include
+
+// guacamole headers
+#include
+#include
+#include
+#include
+#include
+
+namespace gua {
+
+////////////////////////////////////////////////////////////////////////////////
+
+FullscreenPass::FullscreenPass(Pipeline* pipeline)
+ : Pass(pipeline), fullscreen_quad_(), depth_stencil_state_() {}
+
+////////////////////////////////////////////////////////////////////////////////
+
+FullscreenPass::~FullscreenPass() {}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void FullscreenPass::render_scene(Camera const& camera,
+ SceneGraph const&,
+ RenderContext const& ctx,
+ std::size_t viewid) {
+
+ if (!depth_stencil_state_)
+ depth_stencil_state_ = ctx.render_device
+ ->create_depth_stencil_state(false, false, scm::gl::COMPARISON_NEVER);
+
+ if (!fullscreen_quad_)
+ fullscreen_quad_ = scm::gl::quad_geometry_ptr(new scm::gl::quad_geometry(
+ ctx.render_device, math::vec2(-1.f, -1.f), math::vec2(1.f, 1.f)));
+ set_uniforms(pipeline_->get_current_scene(CameraMode::CENTER), ctx);
+
+ for (int i(0); i < gbuffer_->get_eye_buffers().size(); ++i) {
+ CameraMode eye(CameraMode::CENTER);
+
+ if (gbuffer_->get_eye_buffers().size() > 1 && i == 0)
+ eye = CameraMode::LEFT;
+ if (gbuffer_->get_eye_buffers().size() > 1 && i == 1)
+ eye = CameraMode::RIGHT;
+
+ pre_rendering(camera, pipeline_->get_current_scene(eye), eye, ctx);
+
+ FrameBufferObject* fbo(gbuffer_->get_eye_buffers()[i]);
+ fbo->bind(ctx);
+
+ ctx.render_context->set_viewport(scm::gl::viewport(
+ math::vec2(0, 0), math::vec2(float(fbo->width()), float(fbo->height()))));
+ ctx.render_context->set_depth_stencil_state(depth_stencil_state_);
+
+ rendering(camera, pipeline_->get_current_scene(eye), eye, ctx);
+
+ ctx.render_context->reset_state_objects();
+
+ fbo->unbind(ctx);
+
+ post_rendering(camera, pipeline_->get_current_scene(eye), eye, ctx);
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+}
diff --git a/src/gua/renderer/GBufferPass.cpp b/src/gua/renderer/GBufferPass.cpp
index 72cf565b4..fa46db437 100644
--- a/src/gua/renderer/GBufferPass.cpp
+++ b/src/gua/renderer/GBufferPass.cpp
@@ -45,28 +45,26 @@ namespace gua {
////////////////////////////////////////////////////////////////////////////////
GBufferPass::GBufferPass(Pipeline* pipeline)
- : GeometryPass(pipeline),
- bfc_rasterizer_state_(),
- no_bfc_rasterizer_state_(),
- bbox_rasterizer_state_(),
- depth_stencil_state_()
-{}
+ : GeometryPass(pipeline),
+ bfc_rasterizer_state_(),
+ no_bfc_rasterizer_state_(),
+ bbox_rasterizer_state_(),
+ depth_stencil_state_() {}
////////////////////////////////////////////////////////////////////////////////
-GBufferPass::~GBufferPass()
-{}
+GBufferPass::~GBufferPass() {}
////////////////////////////////////////////////////////////////////////////////
void GBufferPass::create(
- RenderContext const& ctx,
- std::vector > const&
- layers) {
+ RenderContext const& ctx,
+ std::vector > const&
+ layers) {
scm::gl::sampler_state_desc state(scm::gl::FILTER_MIN_MAG_MIP_NEAREST,
- scm::gl::WRAP_MIRRORED_REPEAT,
- scm::gl::WRAP_MIRRORED_REPEAT);
+ scm::gl::WRAP_MIRRORED_REPEAT,
+ scm::gl::WRAP_MIRRORED_REPEAT);
auto tmp(layers);
tmp.insert(tmp.begin(), std::make_pair(BufferComponent::DEPTH_24, state));
@@ -74,17 +72,14 @@ void GBufferPass::create(
Pass::create(ctx, tmp);
}
-
////////////////////////////////////////////////////////////////////////////////
-void GBufferPass::cleanup(RenderContext const& ctx) {
- Pass::cleanup(ctx);
-}
+void GBufferPass::cleanup(RenderContext const& ctx) { Pass::cleanup(ctx); }
////////////////////////////////////////////////////////////////////////////////
-bool GBufferPass::pre_compile_shaders(const gua::RenderContext & ctx) {
- bool success {true};
+bool GBufferPass::pre_compile_shaders(const gua::RenderContext& ctx) {
+ bool success{true};
for (auto const& shader : ubershaders_) {
success &= shader.second->upload_to(ctx);
@@ -96,22 +91,21 @@ bool GBufferPass::pre_compile_shaders(const gua::RenderContext & ctx) {
////////////////////////////////////////////////////////////////////////////////
void GBufferPass::rendering(SerializedScene const& scene,
- SceneGraph const& graph,
- RenderContext const& ctx,
- CameraMode eye,
- Camera const& camera,
- FrameBufferObject* target) {
-
- if (!depth_stencil_state_ ||
- !bfc_rasterizer_state_ ||
- !no_bfc_rasterizer_state_ ||
+ SceneGraph const& graph,
+ RenderContext const& ctx,
+ CameraMode eye,
+ Camera const& camera,
+ FrameBufferObject* target,
+ std::size_t viewid) {
+
+ if (!depth_stencil_state_ || !bfc_rasterizer_state_ ||
!no_bfc_rasterizer_state_) {
initialize_state_objects(ctx);
}
ctx.render_context->set_rasterizer_state(
- pipeline_->config.enable_backface_culling() ? bfc_rasterizer_state_
- : no_bfc_rasterizer_state_);
+ pipeline_->config.enable_backface_culling() ? bfc_rasterizer_state_
+ : no_bfc_rasterizer_state_);
ctx.render_context->set_depth_stencil_state(depth_stencil_state_);
@@ -125,20 +119,22 @@ void GBufferPass::rendering(SerializedScene const& scene,
auto ubershader = ubershaders_.at(type);
// set frame-consistent per-ubershader uniforms
- ubershader->set_material_uniforms(scene.materials_, ShadingModel::GBUFFER_VERTEX_STAGE, ctx);
- ubershader->set_material_uniforms(scene.materials_, ShadingModel::GBUFFER_FRAGMENT_STAGE, ctx);
-
- ubershader->set_uniform(ctx, scene.enable_global_clipping_plane, "gua_enable_global_clipping_plane");
- ubershader->set_uniform(ctx, scene.global_clipping_plane, "gua_global_clipping_plane");
+ ubershader->set_material_uniforms(
+ scene.materials_, ShadingModel::GBUFFER_VERTEX_STAGE, ctx);
+ ubershader->set_material_uniforms(
+ scene.materials_, ShadingModel::GBUFFER_FRAGMENT_STAGE, ctx);
+
+ ubershader->set_uniform(ctx,
+ scene.enable_global_clipping_plane,
+ "gua_enable_global_clipping_plane");
+ ubershader->set_uniform(
+ ctx, scene.global_clipping_plane, "gua_global_clipping_plane");
ubershader->set_uniform(ctx, false, "gua_render_shadow_map");
for (auto const& program : ubershader->programs()) {
Pass::bind_inputs(*program, eye, ctx);
- Pass::set_camera_matrices(*program,
- camera,
- pipeline_->get_current_scene(eye),
- eye,
- ctx);
+ Pass::set_camera_matrices(
+ *program, camera, pipeline_->get_current_scene(eye), eye, ctx);
}
// 1. call preframe callback if available for type
@@ -146,53 +142,101 @@ void GBufferPass::rendering(SerializedScene const& scene,
ubershader->preframe(ctx);
}
- // 2. iterate all drawables of current type and call predraw of current ubershader
+ // 2. iterate all drawables of current type and call predraw of current
+ // ubershader
if (ubershader->get_stage_mask() & GeometryUberShader::PRE_DRAW_STAGE) {
for (auto const& node : ressource_container) {
- auto const& ressource = GeometryDatabase::instance()->lookup(node->get_filename());
- auto const& material = MaterialDatabase::instance()->lookup(node->get_material());
+ auto const& ressource =
+ GeometryDatabase::instance()->lookup(node->get_filename());
+ auto const& material =
+ MaterialDatabase::instance()->lookup(node->get_material());
if (ressource && material) {
ubershader->predraw(ctx,
- node->get_filename(),
- node->get_material(),
- node->get_cached_world_transform(),
- scm::math::transpose(scm::math::inverse(node->get_cached_world_transform())),
- scene.frustum);
+ node->get_filename(),
+ node->get_material(),
+ node->get_cached_world_transform(),
+ scm::math::transpose(scm::math::inverse(
+ node->get_cached_world_transform())),
+ scene.frustum,
+ viewid);
+ } else {
+ if (!material) {
+ Logger::LOG_WARNING
+ << "GBufferPass::rendering() Cannot find material. " << material
+ << std::endl;
+ }
+ if (!ressource) {
+ Logger::LOG_WARNING
+ << "GBufferPass::rendering() Cannot find geometry ressource."
+ << ressource << std::endl;
+ }
}
}
}
- // 3. iterate all drawables of current type and call draw of current ubershader
+ // 3. iterate all drawables of current type and call draw of current
+ // ubershader
if (ubershader->get_stage_mask() & GeometryUberShader::DRAW_STAGE) {
for (auto const& node : ressource_container) {
- auto const& ressource = GeometryDatabase::instance()->lookup(node->get_filename());
- auto const& material = MaterialDatabase::instance()->lookup(node->get_material());
+ auto const& ressource =
+ GeometryDatabase::instance()->lookup(node->get_filename());
+ auto const& material =
+ MaterialDatabase::instance()->lookup(node->get_material());
if (ressource && material) {
ubershader->draw(ctx,
- node->get_filename(),
- node->get_material(),
- node->get_cached_world_transform(),
- scm::math::transpose(scm::math::inverse(node->get_cached_world_transform())),
- scene.frustum);
+ node->get_filename(),
+ node->get_material(),
+ node->get_cached_world_transform(),
+ scm::math::transpose(scm::math::inverse(
+ node->get_cached_world_transform())),
+ scene.frustum,
+ viewid);
+ } else {
+ if (!material) {
+ Logger::LOG_WARNING
+ << "GBufferPass::rendering() Cannot find material. " << material
+ << std::endl;
+ }
+ if (!ressource) {
+ Logger::LOG_WARNING
+ << "GBufferPass::rendering() Cannot find geometry ressource."
+ << ressource << std::endl;
+ }
}
}
}
- // 4. iterate all drawables of current type and call postdraw of current ubershader
+ // 4. iterate all drawables of current type and call postdraw of current
+ // ubershader
if (ubershader->get_stage_mask() & GeometryUberShader::POST_DRAW_STAGE) {
for (auto const& node : ressource_container) {
- auto const& ressource = GeometryDatabase::instance()->lookup(node->get_filename());
- auto const& material = MaterialDatabase::instance()->lookup(node->get_material());
+ auto const& ressource =
+ GeometryDatabase::instance()->lookup(node->get_filename());
+ auto const& material =
+ MaterialDatabase::instance()->lookup(node->get_material());
if (ressource && material) {
ubershader->postdraw(ctx,
- node->get_filename(),
- node->get_material(),
- node->get_cached_world_transform(),
- scm::math::transpose(scm::math::inverse(node->get_cached_world_transform())),
- scene.frustum);
+ node->get_filename(),
+ node->get_material(),
+ node->get_cached_world_transform(),
+ scm::math::transpose(scm::math::inverse(
+ node->get_cached_world_transform())),
+ scene.frustum,
+ viewid);
+ } else {
+ if (!material) {
+ Logger::LOG_WARNING
+ << "GBufferPass::rendering() Cannot find material. " << material
+ << std::endl;
+ }
+ if (!ressource) {
+ Logger::LOG_WARNING
+ << "GBufferPass::rendering() Cannot find geometry ressource."
+ << ressource << std::endl;
+ }
}
}
}
@@ -206,29 +250,29 @@ void GBufferPass::rendering(SerializedScene const& scene,
///////////////////////////////////////////////////////////////
// draw debug and helper information
///////////////////////////////////////////////////////////////
- display_quads(ctx, scene, eye);
+ display_quads(ctx, scene, eye, viewid);
ctx.render_context->set_rasterizer_state(bbox_rasterizer_state_);
- display_bboxes(ctx, scene);
- display_rays(ctx, scene);
+ display_bboxes(ctx, scene, viewid);
+ display_rays(ctx, scene, viewid);
ctx.render_context->reset_state_objects();
}
////////////////////////////////////////////////////////////////////////////////
-void GBufferPass::display_bboxes(RenderContext const& ctx, SerializedScene const& scene)
-{
+void GBufferPass::display_bboxes(RenderContext const& ctx,
+ SerializedScene const& scene,
+ std::size_t viewid) {
auto meshubershader = Singleton::instance();
- if (pipeline_->config.enable_bbox_display())
- {
+ if (pipeline_->config.enable_bbox_display()) {
meshubershader->get_program()->use(ctx);
- for (auto const& bbox : scene.bounding_boxes_)
- {
+ for (auto const& bbox : scene.bounding_boxes_) {
auto scale(scm::math::make_scale((bbox.max - bbox.min) * 1.001f));
- auto translation(scm::math::make_translation((bbox.max + bbox.min) / 2.f));
+ auto translation(
+ scm::math::make_translation((bbox.max + bbox.min) / 2.f));
scm::math::mat4 bbox_transform;
scm::math::set_identity(bbox_transform);
@@ -236,35 +280,43 @@ void GBufferPass::display_bboxes(RenderContext const& ctx, SerializedScene const
bbox_transform *= translation;
bbox_transform *= scale;
- meshubershader->draw(ctx,
- "gua_bounding_box_geometry",
- "gua_bounding_box",
- bbox_transform,
- scm::math::transpose(scm::math::inverse(bbox_transform)),
- scene.frustum);
+ bbox_transform *= translation;
+ bbox_transform *= scale;
+
+ meshubershader->draw(
+ ctx,
+ "gua_bounding_box_geometry",
+ "gua_bounding_box",
+ bbox_transform,
+ scm::math::transpose(scm::math::inverse(bbox_transform)),
+ scene.frustum,
+ viewid);
}
meshubershader->get_program()->unuse(ctx);
}
}
-
////////////////////////////////////////////////////////////////////////////////
-void GBufferPass::display_rays(RenderContext const& ctx, SerializedScene const& scene)
-{
- auto meshubershader = Singleton::instance();
+void GBufferPass::display_rays(RenderContext const& ctx,
+ SerializedScene const& scene,
+ std::size_t viewid) {
+ auto meshubershader = Singleton::instance();
- if (pipeline_->config.enable_ray_display())
- {
+ if (pipeline_->config.enable_ray_display()) {
meshubershader->get_program()->use(ctx);
- for (auto const& ray : scene.rays_)
- {
- meshubershader->draw(ctx,
- "gua_plane_geometry",
- "gua_bounding_box",
- ray->get_cached_world_transform(),
- scm::math::inverse(ray->get_cached_world_transform()),
- scene.frustum);
+ for (auto const& ray : scene.rays_) {
+ meshubershader->get_program()->use(ctx);
+ for (auto const& ray : scene.rays_) {
+ meshubershader->draw(
+ ctx,
+ "gua_plane_geometry",
+ "gua_bounding_box",
+ ray->get_cached_world_transform(),
+ scm::math::inverse(ray->get_cached_world_transform()),
+ scene.frustum,
+ viewid);
+ }
}
meshubershader->get_program()->unuse(ctx);
}
@@ -272,71 +324,78 @@ void GBufferPass::display_rays(RenderContext const& ctx, SerializedScene const&
////////////////////////////////////////////////////////////////////////////////
-void GBufferPass::display_quads(RenderContext const& ctx, SerializedScene const& scene, CameraMode eye)
-{
+void GBufferPass::display_quads(RenderContext const& ctx,
+ SerializedScene const& scene,
+ CameraMode eye,
+ std::size_t viewid) {
auto meshubershader = Singleton::instance();
if (!scene.textured_quads_.empty()) {
meshubershader->get_program()->use(ctx);
{
- for (auto const& node : scene.textured_quads_)
- {
+ for (auto const& node : scene.textured_quads_) {
std::string texture_name(node->get_texture());
if (node->is_stereo_texture()) {
if (eye == CameraMode::LEFT) {
texture_name += "_left";
- }
- else if (eye == CameraMode::RIGHT) {
+ } else if (eye == CameraMode::RIGHT) {
texture_name += "_right";
}
}
- if (TextureDatabase::instance()->is_supported(texture_name))
- {
+ if (TextureDatabase::instance()->is_supported(texture_name)) {
auto texture = TextureDatabase::instance()->lookup(texture_name);
- auto mapped_texture(meshubershader->get_uniform_mapping()->get_mapping("gua_textured_quad", "texture"));
-
- meshubershader->set_uniform(ctx, texture, mapped_texture.first, mapped_texture.second);
-
- auto mapped_flip_x(meshubershader->get_uniform_mapping()->get_mapping("gua_textured_quad", "flip_x"));
- meshubershader->set_uniform(ctx, node->flip_x(), mapped_flip_x.first, mapped_flip_x.second);
-
- auto mapped_flip_y(meshubershader->get_uniform_mapping()->get_mapping("gua_textured_quad", "flip_y"));
- meshubershader->set_uniform(ctx, node->flip_y(), mapped_flip_y.first, mapped_flip_y.second);
+ auto mapped_texture(
+ meshubershader->get_uniform_mapping()->get_mapping(
+ "gua_textured_quad", "texture"));
+
+ meshubershader->set_uniform(
+ ctx, texture, mapped_texture.first, mapped_texture.second);
+
+ auto mapped_flip_x(meshubershader->get_uniform_mapping()->get_mapping(
+ "gua_textured_quad", "flip_x"));
+ meshubershader->set_uniform(
+ ctx, node->flip_x(), mapped_flip_x.first, mapped_flip_x.second);
+
+ auto mapped_flip_y(meshubershader->get_uniform_mapping()->get_mapping(
+ "gua_textured_quad", "flip_y"));
+ meshubershader->set_uniform(
+ ctx, node->flip_y(), mapped_flip_y.first, mapped_flip_y.second);
}
- meshubershader->draw(ctx,
- "gua_plane_geometry",
- "gua_textured_quad",
- node->get_scaled_world_transform(),
- scm::math::inverse(node->get_scaled_world_transform()),
- scene.frustum);
+ meshubershader->draw(
+ ctx,
+ "gua_plane_geometry",
+ "gua_textured_quad",
+ node->get_scaled_world_transform(),
+ scm::math::inverse(node->get_scaled_world_transform()),
+ scene.frustum,
+ viewid);
}
}
meshubershader->get_program()->unuse(ctx);
}
}
-
////////////////////////////////////////////////////////////////////////////////
-void GBufferPass::update_ubershader_from_scene(SerializedScene const& scene, SceneGraph const& graph)
-{
+void GBufferPass::update_ubershader_from_scene(SerializedScene const& scene,
+ SceneGraph const& graph) {
bool ubershader_available = true;
- for (auto const& geometry_pair : scene.geometrynodes_)
- {
- ubershader_available = ubershader_available && ubershaders_.count(geometry_pair.first);
+ for (auto const& geometry_pair : scene.geometrynodes_) {
+ ubershader_available =
+ ubershader_available && ubershaders_.count(geometry_pair.first);
}
- if (!ubershader_available)
- {
- auto get_ubershader = [&] (Node* n) {
+ if (!ubershader_available) {
+ auto get_ubershader = [&](Node * n) {
GeometryNode* geode = dynamic_cast(n);
if (geode) {
std::type_index type(typeid(*geode));
if (!ubershaders_.count(type)) {
- auto const& ressource = GeometryDatabase::instance()->lookup(geode->get_filename());
+ auto const& ressource =
+ GeometryDatabase::instance()->lookup(geode->get_filename());
if (ressource) {
auto ubershader = ressource->get_ubershader();
ubershader->create(materials_);
@@ -344,54 +403,50 @@ void GBufferPass::update_ubershader_from_scene(SerializedScene const& scene, Sce
}
}
}
- };
+ }
+ ;
gua::dfs_traverse(graph.get_root().get(), get_ubershader);
}
}
////////////////////////////////////////////////////////////////////////////////
-void GBufferPass::initialize_state_objects(RenderContext const& ctx)
-{
+void GBufferPass::initialize_state_objects(RenderContext const& ctx) {
if (!depth_stencil_state_)
depth_stencil_state_ =
- ctx.render_device->create_depth_stencil_state(true, true);
+ ctx.render_device->create_depth_stencil_state(true, true);
if (!bfc_rasterizer_state_)
bfc_rasterizer_state_ = ctx.render_device->create_rasterizer_state(
- pipeline_->config.enable_wireframe() ? scm::gl::FILL_WIREFRAME
- : scm::gl::FILL_SOLID,
- scm::gl::CULL_BACK,
- scm::gl::ORIENT_CCW,
- false);
+ pipeline_->config.enable_wireframe() ? scm::gl::FILL_WIREFRAME
+ : scm::gl::FILL_SOLID,
+ scm::gl::CULL_BACK,
+ scm::gl::ORIENT_CCW,
+ false);
if (!no_bfc_rasterizer_state_)
no_bfc_rasterizer_state_ = ctx.render_device->create_rasterizer_state(
- pipeline_->config.enable_wireframe() ? scm::gl::FILL_WIREFRAME
- : scm::gl::FILL_SOLID,
- scm::gl::CULL_NONE);
+ pipeline_->config.enable_wireframe() ? scm::gl::FILL_WIREFRAME
+ : scm::gl::FILL_SOLID,
+ scm::gl::CULL_NONE);
if (!bbox_rasterizer_state_)
bbox_rasterizer_state_ = ctx.render_device
- ->create_rasterizer_state(scm::gl::FILL_SOLID, scm::gl::CULL_NONE);
+ ->create_rasterizer_state(scm::gl::FILL_SOLID, scm::gl::CULL_NONE);
}
-
////////////////////////////////////////////////////////////////////////////////
-void GBufferPass::apply_material_mapping(std::set const& materials)
-{
+void GBufferPass::apply_material_mapping(
+ std::set const& materials) {
materials_ = materials;
Singleton::instance()->create(materials_);
}
-
////////////////////////////////////////////////////////////////////////////////
LayerMapping const* GBufferPass::get_gbuffer_mapping() const {
return Singleton::instance()->get_gbuffer_mapping();
}
-
}
-
diff --git a/src/gua/renderer/GeometryPass.cpp b/src/gua/renderer/GeometryPass.cpp
index fa765a2f8..375670468 100644
--- a/src/gua/renderer/GeometryPass.cpp
+++ b/src/gua/renderer/GeometryPass.cpp
@@ -1,69 +1,70 @@
-/******************************************************************************
- * guacamole - delicious VR *
- * *
- * Copyright: (c) 2011-2013 Bauhaus-Universität Weimar *
- * Contact: felix.lauer@uni-weimar.de / simon.schneegans@uni-weimar.de *
- * *
- * This program 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 3 of the License, or (at your option) *
- * any later version. *
- * *
- * This program 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 this program. If not, see . *
- * *
- ******************************************************************************/
-
-// class header
-#include
-
-// guacamole headers
-#include
-#include
-#include
-#include
-#include
-
-namespace gua {
-
-////////////////////////////////////////////////////////////////////////////////
-
-GeometryPass::GeometryPass(Pipeline* pipeline) : Pass(pipeline) {}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void GeometryPass::render_scene(Camera const& camera,
- SceneGraph const& current_graph,
- RenderContext const& ctx) {
-
- gbuffer_->clear(ctx);
-
- for (int i(0); i < gbuffer_->get_eye_buffers().size(); ++i) {
-
- FrameBufferObject* fbo(gbuffer_->get_eye_buffers()[i]);
-
- CameraMode eye(CameraMode::CENTER);
- if (gbuffer_->get_eye_buffers().size() > 1 && i == 0)
- eye = CameraMode::LEFT;
- if (gbuffer_->get_eye_buffers().size() > 1 && i == 1)
- eye = CameraMode::RIGHT;
-
- fbo->bind(ctx);
-
- ctx.render_context->set_viewport(scm::gl::viewport(
- math::vec2(0, 0), ::scm::math::vec2f(fbo->width(), fbo->height())));
-
- rendering(pipeline_->get_current_scene(eye), current_graph, ctx, eye, camera, fbo);
-
- fbo->unbind(ctx);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-}
+/******************************************************************************
+ * guacamole - delicious VR *
+ * *
+ * Copyright: (c) 2011-2013 Bauhaus-Universität Weimar *
+ * Contact: felix.lauer@uni-weimar.de / simon.schneegans@uni-weimar.de *
+ * *
+ * This program 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 3 of the License, or (at your option) *
+ * any later version. *
+ * *
+ * This program 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 this program. If not, see . *
+ * *
+ ******************************************************************************/
+
+// class header
+#include
+
+// guacamole headers
+#include
+#include
+#include
+#include
+#include
+
+namespace gua {
+
+////////////////////////////////////////////////////////////////////////////////
+
+GeometryPass::GeometryPass(Pipeline* pipeline) : Pass(pipeline) {}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GeometryPass::render_scene(Camera const& camera,
+ SceneGraph const& current_graph,
+ RenderContext const& ctx,
+ std::size_t viewid) {
+
+ gbuffer_->clear(ctx);
+
+ for (int i(0); i < gbuffer_->get_eye_buffers().size(); ++i) {
+
+ FrameBufferObject* fbo(gbuffer_->get_eye_buffers()[i]);
+
+ CameraMode eye(CameraMode::CENTER);
+ if (gbuffer_->get_eye_buffers().size() > 1 && i == 0)
+ eye = CameraMode::LEFT;
+ if (gbuffer_->get_eye_buffers().size() > 1 && i == 1)
+ eye = CameraMode::RIGHT;
+
+ fbo->bind(ctx);
+
+ ctx.render_context->set_viewport(scm::gl::viewport(
+ math::vec2(0, 0), ::scm::math::vec2f(fbo->width(), fbo->height())));
+
+ rendering(pipeline_->get_current_scene(eye), current_graph, ctx, eye, camera, fbo, viewid);
+
+ fbo->unbind(ctx);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+}
diff --git a/src/gua/renderer/LightingPass.cpp b/src/gua/renderer/LightingPass.cpp
index 89e0576a0..62c294356 100644
--- a/src/gua/renderer/LightingPass.cpp
+++ b/src/gua/renderer/LightingPass.cpp
@@ -132,7 +132,8 @@ void LightingPass::rendering(SerializedScene const& scene,
RenderContext const& ctx,
CameraMode eye,
Camera const& camera,
- FrameBufferObject* target) {
+ FrameBufferObject* target,
+ std::size_t viewid) {
init_resources(ctx);
ctx.render_context->set_depth_stencil_state(depth_stencil_state_);
diff --git a/src/gua/renderer/NURBSLoader.cpp b/src/gua/renderer/NURBSLoader.cpp
index 88a744415..54ec52cb2 100644
--- a/src/gua/renderer/NURBSLoader.cpp
+++ b/src/gua/renderer/NURBSLoader.cpp
@@ -57,21 +57,22 @@ std::shared_ptr NURBSLoader::create_geometry_from_file(std::string const&
throw std::runtime_error(std::string("Unsupported filetype: ") + filename);
}
else {
+
igs_loader igsloader;
TrimmedSurfaceConverter surface_converter;
- std::shared_ptr nurbs_object(
- new TrimmedNurbsSurfaceObject);
- std::shared_ptr bezier_object(
- new TrimmedBezierSurfaceObject);
+ auto nurbs_object = std::make_shared();
+ auto bezier_object = std::make_shared();
igsloader.load(filename, nurbs_object);
surface_converter.convert(nurbs_object, bezier_object);
auto ressource = std::make_shared(bezier_object);
- GeometryDatabase::instance()->add(filename, ressource);
- auto node = std::make_shared(nodename, filename, material);
+ std::string mesh_name("type=file&file=" + filename + "&flags=" + string_utils::to_string(flags));
+ GeometryDatabase::instance()->add(mesh_name, ressource);
+
+ auto node = std::make_shared(nodename, mesh_name, material);
node->update_cache();
return node;
diff --git a/src/gua/renderer/NURBSRessource.cpp b/src/gua/renderer/NURBSRessource.cpp
index a2fd6d573..5d7665699 100644
--- a/src/gua/renderer/NURBSRessource.cpp
+++ b/src/gua/renderer/NURBSRessource.cpp
@@ -47,7 +47,6 @@ NURBSRessource::NURBSRessource(std::shared_ptr const
object->bbox().min[0], object->bbox().min[1], object->bbox().min[2]),
math::vec3(
object->bbox().max[0], object->bbox().max[1], object->bbox().max[2]));
- std::cout << object->bbox() << std::endl;
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gua/renderer/NURBSUberShader.cpp b/src/gua/renderer/NURBSUberShader.cpp
index f3946efb0..3f3c5d527 100644
--- a/src/gua/renderer/NURBSUberShader.cpp
+++ b/src/gua/renderer/NURBSUberShader.cpp
@@ -731,30 +731,31 @@ std::string const NURBSUberShader::_final_geometry_shader () const
geom_shader << method.second << std::endl;
}
- geom_shader << std::string(" \n\
- void main() \n\
- { \n\
- for ( int i = 0; i != 3; ++i ) \n\
- { \n\
- gIndex = teIndex[i]; \n\
- gTessCoord = teTessCoord[i]; \n\
- \n\
- // write built-in input for material \n\
- /////////////////////////////////////////////////////// \n\
- gua_texcoords = gTessCoord; \n\
- \n\
- gua_position_varying = (gua_model_matrix * tePosition[i]).xyz; \n\
- gua_object_normal = teNormal[i].xyz; \n\
- gua_object_tangent = teTangent[i].xyz; \n\
- gua_object_bitangent = teBitangent[i].xyz; \n\
- gua_object_position = tePosition[i].xyz; \n\
- \n\
- gua_world_normal = normalize ( gua_normal_matrix * vec4 (teNormal[i].xyz, 0.0) ).xyz; \n\
- gua_world_tangent = normalize ( gua_normal_matrix * vec4 (teTangent[i].xyz, 0.0) ).xyz; \n\
- gua_world_bitangent = normalize ( gua_normal_matrix * vec4 (teBitangent[i].xyz, 0.0) ).xyz; \n\
- gua_world_position = (gua_model_matrix * tePosition[i]).xyz; \n\
- /////////////////////////////////////////////////////// \n\
- ");
+ geom_shader << R"(
+ void main()
+ {
+ for ( int i = 0; i != 3; ++i )
+ {
+ gIndex = teIndex[i];
+ gTessCoord = teTessCoord[i];
+
+ // write built-in input for material
+ ///////////////////////////////////////////////////////
+ gua_texcoords = gTessCoord;
+
+ gua_position_varying = (gua_model_matrix * tePosition[i]).xyz;
+ gua_object_normal = teNormal[i].xyz;
+ gua_object_tangent = teTangent[i].xyz;
+ gua_object_bitangent = teBitangent[i].xyz;
+ gua_object_position = tePosition[i].xyz;
+
+ vec4 world_normal = gua_normal_matrix * vec4 (teNormal[i].xyz, 0.0);
+ gua_world_normal = normalize ( world_normal.xyz );
+ gua_world_tangent = normalize ( gua_normal_matrix * vec4 (teTangent[i].xyz, 0.0) ).xyz;
+ gua_world_bitangent = normalize ( gua_normal_matrix * vec4 (teBitangent[i].xyz, 0.0) ).xyz;
+ gua_world_position = (gua_model_matrix * tePosition[i]).xyz;
+ ///////////////////////////////////////////////////////
+ )";
// generated code
auto main_calls(vshader_factory_->get_main_calls());
@@ -948,7 +949,8 @@ std::string const NURBSUberShader::_final_fragment_shader () const
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& /*frustum*/) const
+ Frustum const& /*frustum*/,
+ std::size_t viewid) const
{
throw std::runtime_error("NURBSUberShader::predraw(): not implemented");
}
@@ -961,31 +963,30 @@ void NURBSUberShader::draw(RenderContext const& ctx,
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& /*frustum*/) const
+ Frustum const& /*frustum*/,
+ std::size_t /*viewid*/) const
{
auto geometry = std::static_pointer_cast(GeometryDatabase::instance()->lookup(filename));
auto material = MaterialDatabase::instance()->lookup(material_name);
- if ( geometry && material )
- {
- set_uniform(ctx, 128, "gua_max_tesselation");
- set_uniform(ctx, material->get_id(), "gua_material_id");
- set_uniform(ctx, model_matrix, "gua_model_matrix");
- set_uniform(ctx, normal_matrix, "gua_normal_matrix");
+ set_uniform(ctx, 128, "gua_max_tesselation");
+ set_uniform(ctx, material->get_id(), "gua_material_id");
+ set_uniform(ctx, model_matrix, "gua_model_matrix");
+ set_uniform(ctx, normal_matrix, "gua_normal_matrix");
#ifdef DEBUG_XFB_OUTPUT
scm::gl::transform_feedback_statistics_query_ptr q = ctx
.render_device->create_transform_feedback_statistics_query(0);
ctx.render_context->begin_query(q);
- #endif
+#endif
- // pre-tesselate if necessary
- get_program(transform_feedback_pass)->use(ctx);
- {
- ctx.render_context->apply();
- geometry->predraw(ctx);
- }
- get_program(transform_feedback_pass)->unuse(ctx);
+ // pre-tesselate if necessary
+ get_program(transform_feedback_pass)->use(ctx);
+ {
+ ctx.render_context->apply();
+ geometry->predraw(ctx);
+ }
+ get_program(transform_feedback_pass)->unuse(ctx);
#ifdef DEBUG_XFB_OUTPUT
ctx.render_context->end_query(q);
@@ -994,14 +995,14 @@ void NURBSUberShader::draw(RenderContext const& ctx,
<< q->result()._primitives_written << std::endl;
#endif
- // invoke tesselation/trim shader for adaptive nurbs rendering
- get_program(final_pass)->use(ctx);
- {
- ctx.render_context->apply();
- geometry->draw(ctx);
- }
- get_program(final_pass)->unuse(ctx);
+ // invoke tesselation/trim shader for adaptive nurbs rendering
+ get_program(final_pass)->use(ctx);
+ {
+ ctx.render_context->apply();
+ geometry->draw(ctx);
}
+ get_program(final_pass)->unuse(ctx);
+
}
////////////////////////////////////////////////////////////////////////////////
@@ -1011,7 +1012,8 @@ void NURBSUberShader::draw(RenderContext const& ctx,
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& /*frustum*/) const
+ Frustum const& /*frustum*/,
+ std::size_t /*viewid*/) const
{
throw std::runtime_error("NURBSUberShader::postdraw(): not implemented");
}
diff --git a/src/gua/renderer/Pipeline.cpp b/src/gua/renderer/Pipeline.cpp
index e8758d945..934cdc531 100644
--- a/src/gua/renderer/Pipeline.cpp
+++ b/src/gua/renderer/Pipeline.cpp
@@ -275,7 +275,7 @@ void Pipeline::process(std::vector> const& sce
}
for (auto pass : passes_) {
- pass->render_scene(config.camera(), *current_graph, *context_);
+ pass->render_scene(config.camera(), *current_graph, *context_, uuid());
}
if (window_) {
diff --git a/src/gua/renderer/PostFXPass.cpp b/src/gua/renderer/PostFXPass.cpp
index c6ff54cdb..3cd4a320f 100644
--- a/src/gua/renderer/PostFXPass.cpp
+++ b/src/gua/renderer/PostFXPass.cpp
@@ -284,9 +284,12 @@ void PostFXPass::init_resources(RenderContext const& ctx) {
}
}
+////////////////////////////////////////////////////////////////////////////////
+
void PostFXPass::render_scene(Camera const& camera,
SceneGraph const&,
- RenderContext const& ctx) {
+ RenderContext const& ctx,
+ std::size_t viewid) {
init_resources(ctx);
ctx.render_context->set_depth_stencil_state(depth_stencil_state_);
diff --git a/src/gua/renderer/ShadowMap.cpp b/src/gua/renderer/ShadowMap.cpp
index ca9328907..d2da73eae 100644
--- a/src/gua/renderer/ShadowMap.cpp
+++ b/src/gua/renderer/ShadowMap.cpp
@@ -177,7 +177,8 @@ void ShadowMap::render_geometry(RenderContext const & ctx,
node->get_material(),
node->get_cached_world_transform(),
scm::math::transpose(scm::math::inverse(node->get_cached_world_transform())),
- scene.frustum);
+ scene.frustum,
+ uuid());
}
} else {
Logger::LOG_WARNING << "ShadowMap::render_geometry(): UberShader missing." << std::endl;
diff --git a/src/gua/renderer/TriMeshLoader.cpp b/src/gua/renderer/TriMeshLoader.cpp
index ddea8c552..048ae5a0e 100644
--- a/src/gua/renderer/TriMeshLoader.cpp
+++ b/src/gua/renderer/TriMeshLoader.cpp
@@ -307,6 +307,7 @@ void TriMeshLoader::apply_fallback_material(std::shared_ptr const& root,
if (g_node) {
if (g_node->get_material().empty()) {
g_node->set_material(fallback_material);
+ g_node->update_cache();
}
}
@@ -314,6 +315,7 @@ void TriMeshLoader::apply_fallback_material(std::shared_ptr const& root,
apply_fallback_material(child, fallback_material);
}
+
}
}
diff --git a/src/gua/renderer/TriMeshUberShader.cpp b/src/gua/renderer/TriMeshUberShader.cpp
index a12289b12..24395dce9 100644
--- a/src/gua/renderer/TriMeshUberShader.cpp
+++ b/src/gua/renderer/TriMeshUberShader.cpp
@@ -110,7 +110,8 @@ namespace gua {
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& /*frustum*/) const
+ Frustum const& /*frustum*/,
+ std::size_t /*viewid*/) const
{
throw std::runtime_error("TriMeshUberShader::predraw(): not implemented");
}
@@ -122,21 +123,19 @@ namespace gua {
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& /*frustum*/) const
+ Frustum const& /*frustum*/,
+ std::size_t /*viewid*/) const
{
auto geometry = std::static_pointer_cast(GeometryDatabase::instance()->lookup(filename));
auto material = MaterialDatabase::instance()->lookup(material_name);
get_program()->use(ctx);
{
- if (material && geometry)
- {
- set_uniform(ctx, material->get_id(), "gua_material_id");
- set_uniform(ctx, model_matrix, "gua_model_matrix");
- set_uniform(ctx, normal_matrix, "gua_normal_matrix");
-
- geometry->draw(ctx);
- }
+ set_uniform(ctx, material->get_id(), "gua_material_id");
+ set_uniform(ctx, model_matrix, "gua_model_matrix");
+ set_uniform(ctx, normal_matrix, "gua_normal_matrix");
+
+ geometry->draw(ctx);
}
get_program()->unuse(ctx);
}
@@ -148,7 +147,8 @@ namespace gua {
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& /*frustum*/) const
+ Frustum const& /*frustum*/,
+ std::size_t /*viewid*/) const
{
throw std::runtime_error("TriMeshUberShader::postdraw(): not implemented");
}
diff --git a/src/gua/renderer/Video3DUberShader.cpp b/src/gua/renderer/Video3DUberShader.cpp
index 8279e1850..309ac762f 100644
--- a/src/gua/renderer/Video3DUberShader.cpp
+++ b/src/gua/renderer/Video3DUberShader.cpp
@@ -235,14 +235,19 @@ bool Video3DUberShader::upload_to (RenderContext const& context) const
if (context.id >= depth_stencil_state_warp_pass_.size()) {
depth_stencil_state_warp_pass_.resize(context.id + 1);
- depth_stencil_state_warp_pass_[context.id] = context.render_device->create_depth_stencil_state(false, true, scm::gl::COMPARISON_NEVER);
+ depth_stencil_state_warp_pass_[context.id] = context.render_device->create_depth_stencil_state(true, true, scm::gl::COMPARISON_LESS);
}
if (context.id >= depth_stencil_state_blend_pass_.size()) {
depth_stencil_state_blend_pass_.resize(context.id + 1);
- depth_stencil_state_blend_pass_[context.id] = context.render_device->create_depth_stencil_state(false, true, scm::gl::COMPARISON_NEVER);
+ depth_stencil_state_blend_pass_[context.id] = context.render_device->create_depth_stencil_state(true, true, scm::gl::COMPARISON_LESS);
}
-
+ if (context.id >= no_bfc_rasterizer_state_.size())
+ {
+ no_bfc_rasterizer_state_.resize(context.id + 1);
+ no_bfc_rasterizer_state_[context.id] = context.render_device->create_rasterizer_state(scm::gl::FILL_SOLID, scm::gl::CULL_NONE);
+ }
+
return upload_succeeded;
}
@@ -267,7 +272,8 @@ bool Video3DUberShader::upload_to (RenderContext const& context) const
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& /*frustum*/) const
+ Frustum const& /*frustum*/,
+ std::size_t viewid) const
{
throw std::runtime_error("not implemented");
}
@@ -280,7 +286,8 @@ void Video3DUberShader::draw(RenderContext const& ctx,
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& /*frustum*/) const
+ Frustum const& /*frustum*/,
+ std::size_t viewid) const
{
if (!GeometryDatabase::instance()->is_supported(ksfile_name) ||
!MaterialDatabase::instance()->is_supported(material_name)) {
@@ -305,12 +312,13 @@ void Video3DUberShader::draw(RenderContext const& ctx,
// single texture only
scm::gl::context_all_guard guard(ctx.render_context);
+ ctx.render_context->set_rasterizer_state(no_bfc_rasterizer_state_[ctx.id]);
+ ctx.render_context->set_depth_stencil_state(depth_stencil_state_warp_pass_[ctx.id]);
+
+ // set uniforms
ctx.render_context->bind_texture(video3d_ressource->depth_array(ctx), nearest_sampler_state_[ctx.id], 0);
get_program(warp_pass)->get_program(ctx)->uniform_sampler("depth_video3d_texture", 0);
- auto ds_state = ctx.render_device->create_depth_stencil_state(true, true, scm::gl::COMPARISON_LESS);
- ctx.render_context->set_depth_stencil_state(ds_state);
-
scm::math::vec4f norm_vec (0.0f, 1.0f, 0.0f, 0.0f);
auto trans_vec = model_matrix * norm_vec;
@@ -371,6 +379,8 @@ void Video3DUberShader::draw(RenderContext const& ctx,
// single texture only
scm::gl::context_all_guard guard(ctx.render_context);
+ ctx.render_context->set_depth_stencil_state(depth_stencil_state_warp_pass_[ctx.id]);
+
// second pass
get_program(blend_pass)->use(ctx);
{
@@ -409,7 +419,8 @@ void Video3DUberShader::draw(RenderContext const& ctx,
std::string const& material_name,
scm::math::mat4 const& model_matrix,
scm::math::mat4 const& normal_matrix,
- Frustum const& /*frustum*/) const
+ Frustum const& /*frustum*/,
+ std::size_t viewid) const
{
throw std::runtime_error("not implemented");
}
diff --git a/src/gua/scenegraph/GeometryNode.cpp b/src/gua/scenegraph/GeometryNode.cpp
index b0cfb53f0..6874734a0 100644
--- a/src/gua/scenegraph/GeometryNode.cpp
+++ b/src/gua/scenegraph/GeometryNode.cpp
@@ -43,11 +43,9 @@ namespace gua {
filename_(filename),
material_(material),
shadow_mode_(shadow_mode),
- filename_changed_(false),
- material_changed_(false)
- {
- cache_material();
- }
+ filename_changed_(true),
+ material_changed_(true)
+ {}
////////////////////////////////////////////////////////////////////////////////
std::string const& GeometryNode::get_filename() const {
@@ -74,7 +72,6 @@ namespace gua {
void GeometryNode::set_material(std::string const& v) {
material_ = v;
material_changed_ = self_dirty_ = true;
- cache_material();
}
////////////////////////////////////////////////////////////////////////////////
@@ -92,16 +89,4 @@ namespace gua {
Node::update_bounding_box();
}
}
-
- ////////////////////////////////////////////////////////////////////////////////
- void GeometryNode::cache_material() const
- {
- if (!material_.empty())
- {
- if (!MaterialDatabase::instance()->is_supported(material_))
- {
- MaterialDatabase::instance()->load_material(material_);
- }
- }
- }
}
diff --git a/src/gua/scenegraph/NURBSNode.cpp b/src/gua/scenegraph/NURBSNode.cpp
index 221459a33..5968473af 100644
--- a/src/gua/scenegraph/NURBSNode.cpp
+++ b/src/gua/scenegraph/NURBSNode.cpp
@@ -25,7 +25,7 @@
#include
#include
#include
-#include
+#include
// guacamole headers
@@ -49,6 +49,81 @@ namespace gua {
Logger::LOG_WARNING << "NURBSNode::ray_test_impl() : Ray test not implemented yet for NURBS" << std::endl;
}
+ ////////////////////////////////////////////////////////////////////////////////
+
+ void NURBSNode::update_cache() {
+
+ // The code below auto-loads a geometry if it's not already supported by
+ // the GeometryDatabase. It expects a geometry name like
+ //
+ // "type='file'&file='data/objects/monkey.obj'&id=0&flags=0"
+
+ if (filename_changed_)
+ {
+ if (filename_ != "")
+ {
+ if (!GeometryDatabase::instance()->is_supported(filename_))
+ {
+ auto params(string_utils::split(filename_, '&'));
+
+ if (params.size() == 4)
+ {
+ if (params[0] == "type=file")
+ {
+ auto tmp_filename(string_utils::split(params[1], '='));
+ auto tmp_flags(string_utils::split(params[2], '='));
+
+ if (tmp_filename.size() == 2 && tmp_flags.size() == 2)
+ {
+ std::string filename(tmp_filename[1]);
+ std::string flags_string(tmp_flags[1]);
+ unsigned flags(0);
+ std::stringstream sstr(flags_string);
+ sstr >> flags;
+
+ NURBSLoader loader;
+
+ // node is deleted directly after initialization, but ressources remain in database
+ loader.create_geometry_from_file("dummy", filename, material_, flags);
+ }
+ else {
+ Logger::LOG_WARNING << "Failed to auto-load geometry " << filename_ << ": Failed to extract filename and/or loading flags!" << std::endl;
+ }
+ }
+ else {
+ Logger::LOG_WARNING << "Failed to auto-load geometry " << filename_ << ": Type is not supported!" << std::endl;
+ }
+ }
+ else {
+ Logger::LOG_WARNING << "Failed to auto-load geometry " << filename_ << ": The name does not contain a type, file, id and flag parameter!" << std::endl;
+ }
+ }
+ }
+
+ filename_changed_ = false;
+ }
+
+ // The code below auto-loads a material if it's not already supported by
+ // the MaterialDatabase. It expects a material name like
+ //
+ // data/materials/Stones.gmd
+
+ if (material_changed_)
+ {
+ if (material_ != "")
+ {
+ if (!MaterialDatabase::instance()->is_supported(material_))
+ {
+ MaterialDatabase::instance()->load_material(material_);
+ }
+ }
+
+ material_changed_ = false;
+ }
+
+ GeometryNode::update_cache();
+ }
+
////////////////////////////////////////////////////////////////////////////////
std::shared_ptr NURBSNode::copy() const {
return std::make_shared(get_name(), filename_, material_, get_transform());
diff --git a/src/gua/scenegraph/Node.cpp b/src/gua/scenegraph/Node.cpp
index f266bd5b4..eaea881d9 100644
--- a/src/gua/scenegraph/Node.cpp
+++ b/src/gua/scenegraph/Node.cpp
@@ -61,13 +61,15 @@ namespace gua {
void Node::update_cache() {
- if (self_dirty_) {
- math::mat4 old_world_trans(world_transform_);
- if (is_root()) {
- world_transform_ = get_transform();
- } else {
- world_transform_ = parent_->world_transform_ * get_transform();
- }
+ if (self_dirty_)
+ {
+ math::mat4 old_world_trans(world_transform_);
+ if (is_root()) {
+ world_transform_ = get_transform();
+ } else {
+ world_transform_ = parent_->world_transform_ * get_transform();
+ }
+
if (is_root()) {
world_transform_ = get_transform();
}
@@ -75,11 +77,10 @@ namespace gua {
world_transform_ = parent_->world_transform_ * get_transform();
}
- if (world_transform_ != old_world_trans) {
- on_world_transform_changed.emit(world_transform_);
- }
+ if (world_transform_ != old_world_trans) {
+ on_world_transform_changed.emit(world_transform_);
+ }
- self_dirty_ = false;
self_dirty_ = false;
}
@@ -358,6 +359,7 @@ namespace gua {
////////////////////////////////////////////////////////////////////////////////
void Node::set_dirty() const {
+ self_dirty_ = true;
set_children_dirty();
set_parent_dirty();
}
@@ -377,11 +379,11 @@ namespace gua {
if (!self_dirty_) {
self_dirty_ = true;
child_dirty_ = true;
-
- for (auto child : children_) {
- child->set_children_dirty();
- }
}
+ for (auto child : children_) {
+ child->set_children_dirty();
+ }
+
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gua/scenegraph/TriMeshNode.cpp b/src/gua/scenegraph/TriMeshNode.cpp
index 6e9717ac9..58eb3eae7 100644
--- a/src/gua/scenegraph/TriMeshNode.cpp
+++ b/src/gua/scenegraph/TriMeshNode.cpp
@@ -230,15 +230,14 @@ namespace gua {
{
if (!MaterialDatabase::instance()->is_supported(material_))
{
- auto mat = std::make_shared(material_, MaterialDescription(material_));
- MaterialDatabase::instance()->add(material_, mat);
+ MaterialDatabase::instance()->load_material(material_);
}
}
material_changed_ = false;
}
- Node::update_cache();
+ GeometryNode::update_cache();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gua/scenegraph/Video3DNode.cpp b/src/gua/scenegraph/Video3DNode.cpp
index 6bf84fb14..70a58c330 100644
--- a/src/gua/scenegraph/Video3DNode.cpp
+++ b/src/gua/scenegraph/Video3DNode.cpp
@@ -25,7 +25,8 @@
// guacamole headers
#include
#include
-#include
+#include
+#include
#include
#include
#include
@@ -47,17 +48,70 @@ namespace gua {
math::vec3( 3.0, 2.5, 3.0));
}
+ /////////////////////////////////////////////////////////////////////////////
+
void Video3DNode::update_bounding_box() const {
//Logger::LOG_WARNING << "not implemented: Video3DNode::update_bounding_box()" << std::endl;
}
+ /////////////////////////////////////////////////////////////////////////////
+
void Video3DNode::ray_test_impl(RayNode const& ray, PickResult::Options options,
Mask const& mask, std::set& hits) {
Logger::LOG_WARNING << "not implemented: Video3DNode::ray_test_impl()" << std::endl;
}
+ /////////////////////////////////////////////////////////////////////////////
+
std::shared_ptr Video3DNode::copy() const {
return std::make_shared(get_name(), filename_, material_, get_transform());
}
+ /////////////////////////////////////////////////////////////////////////////
+
+ /* virtual */ void Video3DNode::update_cache()
+ {
+ if (filename_changed_)
+ {
+ if (filename_ != "")
+ {
+ if (!GeometryDatabase::instance()->is_supported(filename_))
+ {
+ Video3DLoader loader;
+ loader.create_geometry_from_file("dummy", filename_);
+ }
+ else {
+ Logger::LOG_WARNING << "Failed to auto-load geometry " << filename_ << ": Type is not supported!" << std::endl;
+ }
+ }
+ else {
+ Logger::LOG_WARNING << "Failed to auto-load geometry " << filename_ << ": The name does not contain a type, file, id and flag parameter!" << std::endl;
+ }
+
+ filename_changed_ = false;
+ }
+
+ // The code below auto-loads a material if it's not already supported by
+ // the MaterialDatabase. It expects a material name like
+ //
+ // data/materials/Stones.gmd
+
+ if (material_changed_)
+ {
+ if (material_ != "")
+ {
+ if (!MaterialDatabase::instance()->is_supported(material_) &&
+ material_ != Singleton::instance()->default_video_material_name() )
+ {
+ auto mat = std::make_shared(material_, MaterialDescription(material_));
+ MaterialDatabase::instance()->add(material_, mat);
+ }
+ }
+
+ material_changed_ = false;
+ }
+
+ Node::update_cache();
+ }
+
}