diff --git a/modules/gfx/pymod/export_gfx_obj.cc b/modules/gfx/pymod/export_gfx_obj.cc index 07d845636676fbd2c381ee1bbab25a4bf8aa0ca4..68e88f90169ae1c1f190a3b778da26d0f63160a1 100644 --- a/modules/gfx/pymod/export_gfx_obj.cc +++ b/modules/gfx/pymod/export_gfx_obj.cc @@ -157,6 +157,9 @@ void export_GfxObj() .add_property("opacity",&GfxObjBase::GetOpacity,&GfxObjBase::SetOpacity) .add_property("solid",&GfxObjBase::GetSolid,&GfxObjBase::SetSolid) .add_property("solid_color",&GfxObjBase::GetSolidColor,&GfxObjBase::SetSolidColor) + .add_property("clip",&GfxObjBase::GetClip,&GfxObjBase::SetClip) + .add_property("clip_plane",&GfxObjBase::GetClipPlane,&GfxObjBase::SetClipPlane) + .add_property("clip_offset",&GfxObjBase::GetClipOffset,&GfxObjBase::SetClipOffset) COLOR_BY_DEF() ; diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc index 71181316fedef1e2ded80931432cc7e4726e96e5..052f5c9f2d94298eb0b84e2367383ff9ece45aee 100644 --- a/modules/gfx/src/gfx_object.cc +++ b/modules/gfx/src/gfx_object.cc @@ -39,6 +39,10 @@ # include <ost/img/alg/stat.hh> #endif // OST_IMG_ENABLED +#if OST_SHADER_SUPPORT_ENABLED +#include "shader.hh" +#endif + namespace ost { namespace gfx { GfxObj::GfxObj(const String& name): @@ -66,6 +70,9 @@ GfxObj::GfxObj(const String& name): #endif solid_(false), solid_color_(RGB(0.7,0.7,0.7)), + clip_flag_(false), + clip_plane_(), + clip_offset_(0.0), c_ops_(), labels_(), use_occlusion_(false) @@ -102,6 +109,11 @@ void GfxObj::DeepSwap(GfxObj& go) std::swap(smoothf_,go.smoothf_); std::swap(outline_flag_,go.outline_flag_); std::swap(outline_mode_,go.outline_mode_); + std::swap(solid_,go.solid_); + std::swap(solid_color_,go.solid_color_); + std::swap(clip_flag_,go.clip_flag_); + std::swap(clip_plane_,go.clip_plane_); + std::swap(clip_offset_,go.clip_offset_); std::swap(c_ops_,go.c_ops_); std::swap(labels_,go.labels_); std::swap(use_occlusion_,go.use_occlusion_); @@ -152,7 +164,27 @@ void GfxObj::RenderGL(RenderPass pass) only STANDARD_RENDER_PASS and GLOW_RENDER_PASS are passed down to the custom rendering routines */ - + + if(clip_flag_) { + glEnable(GL_CLIP_DISTANCE0); +#if OST_SHADER_SUPPORT_ENABLED + GLuint cp = Shader::Instance().GetCurrentProgram(); + if(cp>0) { + glUniform1i(glGetUniformLocation(cp,"clip_flag"),1); + glUniform4f(glGetUniformLocation(cp,"clip_plane"), + clip_plane_[0],clip_plane_[1],clip_plane_[2],clip_plane_[3]); + } else { + GLdouble eq[4]; + for(size_t i=0;i<4;++i) eq[i]=clip_plane_[i]; + glClipPlane(GL_CLIP_PLANE0,eq); + } +#else + GLdouble eq[4]; + for(size_t i=0;i<4;++i) eq[i]=clip_plane_[i]; + glClipPlane(GL_CLIP_PLANE0,eq); +#endif + } + if(pass==DEPTH_RENDER_PASS) { render_depth_only(); } else if(pass==TRANSPARENT_RENDER_PASS) { @@ -181,6 +213,10 @@ void GfxObj::RenderGL(RenderPass pass) render_labels(); } + if(clip_flag_) { + glDisable(GL_CLIP_DISTANCE0); + } + glPopMatrix(); } } @@ -393,6 +429,27 @@ void GfxObj::SetSolidColor(const Color& c) Scene::Instance().RequestRedraw(); } +void GfxObj::SetClip(bool f) +{ + clip_flag_=f; + // va_.SetClip(clip_flag_); + Scene::Instance().RequestRedraw(); +} + +void GfxObj::SetClipPlane(const geom::Vec4& p) +{ + clip_plane_=p; + // va_.SetSolidColor(solid_color_); + Scene::Instance().RequestRedraw(); +} + +void GfxObj::SetClipOffset(float f) +{ + clip_offset_=f; + va_.SetClipOffset(clip_offset_); + Scene::Instance().RequestRedraw(); +} + void GfxObj::ColorBy(const mol::EntityView& ev, const String& prop, const Gradient& g, float minv, float maxv) diff --git a/modules/gfx/src/gfx_object.hh b/modules/gfx/src/gfx_object.hh index 0b70065d7f820ca924ef07b3d2ad3005fe4e71b2..51806e3570e4b8de696df5eba939049bffa4c4dc 100644 --- a/modules/gfx/src/gfx_object.hh +++ b/modules/gfx/src/gfx_object.hh @@ -93,6 +93,13 @@ public: virtual void SetSolidColor(const Color& c); virtual Color GetSolidColor() const {return solid_color_;} + virtual void SetClip(bool f); + virtual bool GetClip() const {return clip_flag_;} + virtual void SetClipPlane(const geom::Vec4&); + virtual geom::Vec4 GetClipPlane() const {return clip_plane_;} + virtual void SetClipOffset(float f); + virtual float GetClipOffset() const {return clip_offset_;} + virtual void ColorBy(const mol::EntityView& ev, const String& prop, const Gradient& g, float minv, float maxv); @@ -250,6 +257,10 @@ public: bool solid_; Color solid_color_; + bool clip_flag_; + geom::Vec4 clip_plane_; + float clip_offset_; + boost::ptr_vector<gfx::ColorOp> c_ops_; TextPrimList labels_; diff --git a/modules/gfx/src/gfx_object_base.hh b/modules/gfx/src/gfx_object_base.hh index 448de0cf2687781045e7b59bc72b145be0ee1c2d..07e49a92eb4df39fa9359b3f09e37f4e3eb9ef40 100644 --- a/modules/gfx/src/gfx_object_base.hh +++ b/modules/gfx/src/gfx_object_base.hh @@ -121,6 +121,13 @@ class DLLEXPORT_OST_GFX GfxObjBase: public GfxNode virtual bool GetSolid() const = 0; virtual void SetSolidColor(const Color& c) = 0; virtual Color GetSolidColor() const = 0; + + virtual void SetClip(bool f) = 0; + virtual bool GetClip() const = 0; + virtual void SetClipPlane(const geom::Vec4&) = 0; + virtual geom::Vec4 GetClipPlane() const = 0; + virtual void SetClipOffset(float f) = 0; + virtual float GetClipOffset() const = 0; /// \brief color each component based on the gradient-mapped property of /// the given entity diff --git a/modules/gfx/src/shader/basic_fs.glsl b/modules/gfx/src/shader/basic_fs.glsl index 9856cd3a47445b3ea94d57e9e00ea34c90ec2474..c0a9d6f084f88fc66f8844d8a595edcc5c4ea10b 100644 --- a/modules/gfx/src/shader/basic_fs.glsl +++ b/modules/gfx/src/shader/basic_fs.glsl @@ -1,7 +1,12 @@ uniform bool fog_flag; +uniform float clip_offset; void main() { + if(gl_FragCoord.z<clip_offset) { + discard; + } + float fog = fog_flag ? clamp((gl_Fog.end-gl_FogFragCoord) * gl_Fog.scale, 0.0, 1.0) : 1.0; gl_FragColor.rgb = mix(gl_Fog.color.rgb, gl_Color.rgb, fog); gl_FragColor.a = gl_Color.a; diff --git a/modules/gfx/src/shader/dumpnorm_fs.glsl b/modules/gfx/src/shader/dumpnorm_fs.glsl index 09bee99284fd774c4d5a010f10b31c603d104aa9..926622a7dc2085624f570c3388a55f9277a64a8d 100644 --- a/modules/gfx/src/shader/dumpnorm_fs.glsl +++ b/modules/gfx/src/shader/dumpnorm_fs.glsl @@ -1,5 +1,10 @@ +uniform float clip_offset; + void main() { + if(gl_FragCoord.z<clip_offset) { + discard; + } gl_FragColor.rgb=normalize(gl_TexCoord[0]).stp*0.5+0.5; } diff --git a/modules/gfx/src/shader/fraglight_fs.glsl b/modules/gfx/src/shader/fraglight_fs.glsl index 9baa64b043a516b1293a66beaaf684e1627600b9..b8c7b6b21ded3428e6907d06d27b83d14c8f206b 100644 --- a/modules/gfx/src/shader/fraglight_fs.glsl +++ b/modules/gfx/src/shader/fraglight_fs.glsl @@ -5,9 +5,13 @@ uniform sampler2D depth_map; uniform int depth_mode; uniform bool tex_flag; uniform sampler2D tex_map; +uniform float clip_offset; void main() { + if(gl_FragCoord.z<clip_offset) { + discard; + } vec4 color = gl_Color; if(tex_flag) { diff --git a/modules/gfx/src/shader/fraglight_vs.glsl b/modules/gfx/src/shader/fraglight_vs.glsl index 8a7ca2a3bc6e7fbac32e8420f867f5a833a876bc..18472b2c150c6297ddb5d606437d0dfa1fa6e84d 100644 --- a/modules/gfx/src/shader/fraglight_vs.glsl +++ b/modules/gfx/src/shader/fraglight_vs.glsl @@ -1,3 +1,6 @@ +uniform vec4 clip_plane; +uniform bool clip_flag; + void main() { // transformed position @@ -21,5 +24,8 @@ void main() gl_FrontColor=gl_Color; gl_BackColor=gl_Color; + if(clip_flag) { + gl_ClipDistance[0] = dot(ec_Pos, clip_plane); + } } diff --git a/modules/gfx/src/vertex_array.cc b/modules/gfx/src/vertex_array.cc index 155417b65e2cb2080bd6a5230ee30b936c3f5134..d52506f49501760f2f151b7b9b0eea971a4fb70e 100644 --- a/modules/gfx/src/vertex_array.cc +++ b/modules/gfx/src/vertex_array.cc @@ -431,7 +431,9 @@ void IndexedVertexArray::RenderGL() glPushAttrib(GL_ALL_ATTRIB_BITS); glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); - + + set_clip_offset(clip_offset_); + if(use_tex_) { glEnable(GL_TEXTURE_2D); } else { @@ -493,7 +495,7 @@ void IndexedVertexArray::RenderGL() } else { glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); } - if(cull_face_ && !solid_) { + if(cull_face_ && !solid_ && clip_offset_<=0.0) { glEnable(GL_CULL_FACE); } else { glDisable(GL_CULL_FACE); @@ -537,6 +539,7 @@ void IndexedVertexArray::RenderGL() glUniform4f(glGetUniformLocation(Shader::Instance().GetCurrentProgram(),"color"), outline_exp_color_[0],outline_exp_color_[1], outline_exp_color_[2],opacity_); + set_clip_offset(clip_offset_); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); draw_ltq(use_buff); @@ -700,6 +703,7 @@ void IndexedVertexArray::Reset() outline_exp_color_=Color(0,0,0); solid_=false; solid_color_=RGB(1,1,1); + clip_offset_=0.0; draw_normals_=false; use_tex_=false; } @@ -1098,6 +1102,7 @@ void IndexedVertexArray::copy(const IndexedVertexArray& va) outline_exp_color_=va.outline_exp_color_; solid_=va.solid_; solid_color_=va.solid_color_; + clip_offset_=va.clip_offset_; draw_normals_=va.draw_normals_; use_tex_=va.use_tex_; } @@ -1253,10 +1258,12 @@ void IndexedVertexArray::draw_ltq(bool use_buff) float aspect=Scene::Instance().GetAspect(); float rh=2.0*fabs(tan(fov)*znear); float rw=rh*aspect; - float rz=-znear-0.1; + float rz=-(znear+clip_offset_)-0.05; glDisable(GL_LIGHTING); - + + set_clip_offset(0.0); + glBegin(GL_TRIANGLE_STRIP); glColor3fv(solid_color_); glNormal3f(0,0,1); @@ -1265,6 +1272,9 @@ void IndexedVertexArray::draw_ltq(bool use_buff) glVertex3f(-rw,rh,rz); glVertex3f(rw,rh,rz); glEnd(); + + set_clip_offset(clip_offset_); + glDisable(GL_STENCIL_TEST); glPopMatrix(); } @@ -1486,4 +1496,16 @@ geom::AlignedCuboid IndexedVertexArray::GetBoundingBox() const } } +void IndexedVertexArray::set_clip_offset(float o) +{ +#if OST_SHADER_SUPPORT_ENABLED + float n=Scene::Instance().GetNear(); + float f=Scene::Instance().GetFar(); + float z=n+o; + float t=(f*(-n+o)+n*(n+o))/((f-n)*(n+o)); + t=(t+1.0)*0.5; + glUniform1f(glGetUniformLocation(Shader::Instance().GetCurrentProgram(),"clip_offset"),t); +#endif +} + }} // ns diff --git a/modules/gfx/src/vertex_array.hh b/modules/gfx/src/vertex_array.hh index 539d871b775c6219a397c0ca4795a23baa8c402b..f0380b671d7552eacdb943381d3985aaf77e2c1f 100644 --- a/modules/gfx/src/vertex_array.hh +++ b/modules/gfx/src/vertex_array.hh @@ -121,6 +121,8 @@ class DLLEXPORT_OST_GFX IndexedVertexArray { bool GetSolid() const {return solid_;} void SetSolidColor(const Color& c) {solid_color_=c;} bool GetSolidcolor() const {return solid_color_;} + void SetClipOffset(float f) {clip_offset_=f;} + float GetClipOffset() const {return clip_offset_;} // vertex, normal, color and texcoord (T2F_C4F_N3F_V3F) VertexID Add(const geom::Vec3& vert, const geom::Vec3& norm, const Color& col, const geom::Vec2& tex=geom::Vec2()); @@ -240,6 +242,7 @@ class DLLEXPORT_OST_GFX IndexedVertexArray { Color outline_exp_color_; bool solid_; Color solid_color_; + float clip_offset_; bool draw_normals_; bool use_tex_; @@ -253,6 +256,7 @@ class DLLEXPORT_OST_GFX IndexedVertexArray { void draw_p(bool use_buff); void draw_aalines(); void draw_line_halo(bool use_buff); + void set_clip_offset(float); }; }} // ns