diff --git a/modules/gfx/pymod/export_gfx_obj.cc b/modules/gfx/pymod/export_gfx_obj.cc index 3a0f4d7be36f3a9f0ca0695627264a878847662d..825ac0d91da088b68a540a15d41f12fe46a6ebe8 100644 --- a/modules/gfx/pymod/export_gfx_obj.cc +++ b/modules/gfx/pymod/export_gfx_obj.cc @@ -73,12 +73,14 @@ void export_GfxObj() .def("SetLineHalo",&GfxObjBase::SetLineHalo) .def("Outline",&GfxObjBase::Outline) .def("SetOutlineMode",&GfxObjBase::SetOutlineMode) + .def("SetOutlineWidth",&GfxObjBase::SetOutlineWidth) .def("SetOutlineExpandFactor",&GfxObjBase::SetOutlineExpandFactor) .def("SetOutlineExpandColor",&GfxObjBase::SetOutlineExpandColor) .def("AmbientOcclusion",&GfxObjBase::AmbientOcclusion) .def("SetAmbientLocalWeight",&GfxObjBase::SetAmbientLocalWeight) .def("SetAmbientOcclusionWeight",&GfxObjBase::SetAmbientOcclusionWeight) .def("SetOpacity",&GfxObjBase::SetOpacity) + .def("GetOpacity",&GfxObjBase::GetOpacity) .add_property("center", &GfxObjBase::GetCenter) COLOR_BY_DEF() ; @@ -95,7 +97,6 @@ void export_GfxObj() .def("GetAALines",&GfxObj::GetAALines) .def("GetLineWidth",&GfxObj::GetLineWidth) .def("GetLineHalo",&GfxObj::GetLineHalo) - .def("GetOpacity",&GfxObj::GetOpacity) ; register_ptr_to_python<GfxObjP>(); diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc index d87d76308e6ef66640861dfa4604d27f3e14c6fe..5a1a2057f0ddfdb7a4edbe4d1e855079df9fba61 100644 --- a/modules/gfx/pymod/export_scene.cc +++ b/modules/gfx/pymod/export_scene.cc @@ -83,6 +83,7 @@ void export_Scene() .def("CenterOn",center_on1) .def("CenterOn",center_on2) .def("UnProject", &Scene::UnProject, arg("ignore_vp")=false) + .def("Project", &Scene::Project, arg("ignore_vp")=false) .def("InitGL", &Scene::InitGL) .def("RenderGL", &Scene::RenderGL) .def("Resize", &Scene::Resize) @@ -116,9 +117,11 @@ void export_Scene() .def("BlurSnapshot",&Scene::BlurSnapshot) .def("SetShadow",&Scene::SetShadow) .def("SetShadowQuality",&Scene::SetShadowQuality) + .def("SetDepthDarkening",&Scene::SetDepthDarkening) .def("AttachObserver",&Scene::AttachObserver) .def("StartOffscreenMode",&Scene::StartOffscreenMode) .def("StopOffscreenMode",&Scene::StopOffscreenMode) + .def("SetShadingMode",&Scene::SetShadingMode) .def("__getitem__",scene_getitem) .add_property("bg", &Scene::GetBackground, diff --git a/modules/gfx/src/CMakeLists.txt b/modules/gfx/src/CMakeLists.txt index 1ee9cf86ca56787b6798e3a3a92ec671e2c52de4..8de2ae86c0fec224a64a4e8fc7e65a2dc0c8e1ea 100644 --- a/modules/gfx/src/CMakeLists.txt +++ b/modules/gfx/src/CMakeLists.txt @@ -223,12 +223,8 @@ target_link_libraries(ost_gfx ${OPENGL_LIBRARIES} ${PNG_LIBRARIES}) if (USE_SHADER) set(SHADER_FILES - shader/basic_lf_vs.glsl - shader/basic_lf_fs.glsl - shader/fraglight_lf_vs.glsl - shader/fraglight_lf_fs.glsl - shader/basic_lfs_vs.glsl - shader/basic_lfs_fs.glsl + shader/basic_vs.glsl + shader/basic_fs.glsl shader/fraglight_vs.glsl shader/fraglight_fs.glsl shader/basic_hf_vs.glsl diff --git a/modules/gfx/src/entity.cc b/modules/gfx/src/entity.cc index b9956105f03267502bf0f068bab6451c71ae8d79..84d0a1bb7ed1f1207f75c7dab3454c0861bc4b22 100644 --- a/modules/gfx/src/entity.cc +++ b/modules/gfx/src/entity.cc @@ -71,7 +71,10 @@ Entity::Entity(const String& name, sel_(), sel_update_(), trace_(), - opacity_(1.0) + opacity_(1.0), + blur_(false), + blurf1_(1.0), + blurf2_(0.8) { init(RenderMode::SIMPLE); } @@ -86,7 +89,10 @@ Entity::Entity(const String& name, sel_(), sel_update_(), trace_(), - opacity_(1.0) + opacity_(1.0), + blur_(false), + blurf1_(1.0), + blurf2_(0.8) { init(m); } @@ -99,7 +105,10 @@ Entity::Entity(const String& name, sel_(), sel_update_(), trace_(), - opacity_(1.0) + opacity_(1.0), + blur_(false), + blurf1_(1.0), + blurf2_(0.8) { init(RenderMode::SIMPLE); } @@ -113,7 +122,10 @@ Entity::Entity(const String& name, sel_(), sel_update_(), trace_(), - opacity_(1.0) + opacity_(1.0), + blur_(false), + blurf1_(1.0), + blurf2_(0.8) { init(m); } @@ -180,38 +192,29 @@ void Entity::init(RenderMode::Type rm) Rebuild(); } -namespace { - -SimpleRenderOptionsPtr get_sro(impl::EntityRenderer* renderer) -{ - impl::SimpleRenderer* sr=dynamic_cast<SimpleRenderer*>(renderer); - assert(sr); - return dyn_cast<SimpleRenderOptions>(sr->GetOptions()); -} -} void Entity::SetBlur(bool f) { - impl::EntityRenderer* renderer=this->GetOrCreateRenderer(RenderMode::SIMPLE); - if(!renderer) return; - SimpleRenderOptionsPtr sro=get_sro(renderer); - sro->SetBlurFlag(f); + blur_=f; } void Entity::BlurSnapshot() { - impl::EntityRenderer* renderer=this->GetOrCreateRenderer(RenderMode::SIMPLE); - if(!renderer) return; - impl::SimpleRenderer* sr=dynamic_cast<SimpleRenderer*>(renderer); - assert(sr); - sr->BlurSnapshot(); + for (RendererMap::iterator i=renderer_.begin(),e=renderer_.end(); i!=e; ++i) { + impl::SimpleRenderer* sr = dynamic_cast<impl::SimpleRenderer*>(i->second); + if(sr) { + DoBlurSnapshot(sr->GetBondEntryList()); + } + impl::LineTraceRenderer* lr = dynamic_cast<impl::LineTraceRenderer*>(i->second); + if(lr) { + DoBlurSnapshot(lr->GetBondEntryList()); + } + } } void Entity::SetBlurFactors(float bf1,float bf2) { - impl::EntityRenderer* renderer=this->GetOrCreateRenderer(RenderMode::SIMPLE); - if(!renderer) return; - SimpleRenderOptionsPtr sro=get_sro(renderer); - sro->SetBlurFactors(bf1, bf2); + blurf1_=bf1; + blurf2_=bf2; } void Entity::Rebuild() @@ -368,6 +371,16 @@ void Entity::CustomRenderGL(RenderPass pass) } else if(pass==GLOW_RENDER_PASS) { r->Render(GLOW_RENDER_PASS); } + if(blur_) { + impl::SimpleRenderer* sr = dynamic_cast<impl::SimpleRenderer*>(r); + if(sr) { + DoRenderBlur(sr->GetBondEntryList(),blurf1_,blurf2_); + } + impl::LineTraceRenderer* lr = dynamic_cast<impl::LineTraceRenderer*>(r); + if(lr) { + DoRenderBlur(lr->GetBondEntryList(),blurf1_,blurf2_); + } + } } } } @@ -560,6 +573,36 @@ void Entity::SetOpacity(float f) Scene::Instance().RequestRedraw(); } +void Entity::SetOutlineWidth(float f) +{ + for (RendererMap::iterator it=renderer_.begin(); it!=renderer_.end(); ++it) { + if(it->second->IsEnabled()){ + it->second->VA().SetOutlineWidth(f); + } + } + Scene::Instance().RequestRedraw(); +} + +void Entity::SetOutlineExpandFactor(float f) +{ + for (RendererMap::iterator it=renderer_.begin(); it!=renderer_.end(); ++it) { + if(it->second->IsEnabled()){ + it->second->VA().SetOutlineExpandFactor(f); + } + } + Scene::Instance().RequestRedraw(); +} + +void Entity::SetOutlineExpandColor(const Color& c) +{ + for (RendererMap::iterator it=renderer_.begin(); it!=renderer_.end(); ++it) { + if(it->second->IsEnabled()){ + it->second->VA().SetOutlineExpandColor(c); + } + } + Scene::Instance().RequestRedraw(); +} + void Entity::OnRenderModeChange() { for (RendererMap::iterator i=renderer_.begin(), diff --git a/modules/gfx/src/entity.hh b/modules/gfx/src/entity.hh index 10930da73d680e19f44eb79844e190ff0a57d93c..d8896375428ffec7f95e3922b073e40a532be064 100644 --- a/modules/gfx/src/entity.hh +++ b/modules/gfx/src/entity.hh @@ -142,6 +142,9 @@ public: virtual void SetOpacity(float f); virtual float GetOpacity() const {return opacity_;} + virtual void SetOutlineWidth(float f); + virtual void SetOutlineExpandFactor(float f); + virtual void SetOutlineExpandColor(const Color& c); /// \brief rebuild graphical object (see ctor comments) /* @@ -299,6 +302,9 @@ private: mutable RendererMap renderer_; float opacity_; + bool blur_; + float blurf1_; + float blurf2_; }; diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc index c25c34344d7a91ed03f8cc4017b77a4678c4d8f1..645e01708265c2a2a50bafd746643b4953bc469c 100644 --- a/modules/gfx/src/gfx_object.cc +++ b/modules/gfx/src/gfx_object.cc @@ -307,14 +307,22 @@ void GfxObj::SetOutlineMode(int m) } } +void GfxObj::SetOutlineWidth(float f) +{ + va_.SetOutlineWidth(f); + Scene::Instance().RequestRedraw(); +} + void GfxObj::SetOutlineExpandFactor(float f) { va_.SetOutlineExpandFactor(f); + Scene::Instance().RequestRedraw(); } void GfxObj::SetOutlineExpandColor(const Color& c) { va_.SetOutlineExpandColor(c); + Scene::Instance().RequestRedraw(); } void GfxObj::AmbientOcclusion(bool f) diff --git a/modules/gfx/src/gfx_object.hh b/modules/gfx/src/gfx_object.hh index 878601c809be14c995ce4bcf8230ab918d36ec23..8d004e3cc9d1cabf7bad5e275495b197102a450f 100644 --- a/modules/gfx/src/gfx_object.hh +++ b/modules/gfx/src/gfx_object.hh @@ -76,6 +76,7 @@ public: virtual void SetLineHalo(float f); virtual void Outline(bool f); virtual void SetOutlineMode(int m); + virtual void SetOutlineWidth(float f); virtual void SetOutlineExpandFactor(float f); virtual void SetOutlineExpandColor(const Color& c); virtual void AmbientOcclusion(bool f); diff --git a/modules/gfx/src/gfx_object_base.hh b/modules/gfx/src/gfx_object_base.hh index c18022b47e6d071471bf268395b800abff6ce3a4..0ffb6d94a968bafeaf436aae29dc9351599f89d4 100644 --- a/modules/gfx/src/gfx_object_base.hh +++ b/modules/gfx/src/gfx_object_base.hh @@ -91,27 +91,25 @@ class DLLEXPORT_OST_GFX GfxObjBase: public GfxNode /// \brief turn outline rendering on or off virtual void Outline(bool f) = 0; - /// \brief set outline mode virtual void SetOutlineMode(int m) = 0; - /// \brief set outline tweak factor + /// \brief set outline width (modes 1 + 2) + virtual void SetOutlineWidth(float f) = 0; + /// \brief set outline tweak factor (mode 3) virtual void SetOutlineExpandFactor(float f) = 0; - /// \brief set outline color + /// \brief set outline color (mode 3) virtual void SetOutlineExpandColor(const Color& c) = 0; /// \brief ambient occlusion rendering /// results are cached, but may be very slow on first call virtual void AmbientOcclusion(bool f) = 0; - /// \brief blending weight of local color to fragment color virtual void SetAmbientLocalWeight(float w) = 0; - /// \brief blending weight of occlusion factor virtual void SetAmbientOcclusionWeight(float w) = 0; /// \brief set opacity (1 = no transparency) virtual void SetOpacity(float f) = 0; - /// \brief returns a value smaller than 1.0 if transparency is used in this object virtual float GetOpacity() const = 0; diff --git a/modules/gfx/src/impl/backbone_trace.cc b/modules/gfx/src/impl/backbone_trace.cc index 85403263a9b157fc209634078f9be17e8af7f499..32fef42cde9ffb8ae17e306fe9510b934fc00b35 100644 --- a/modules/gfx/src/impl/backbone_trace.cc +++ b/modules/gfx/src/impl/backbone_trace.cc @@ -210,7 +210,7 @@ BackboneTrace BackboneTrace::CreateSubset(const mol::EntityView& subview) const NodeEntryList& nlist=*nitnit; for(NodeEntryList::const_iterator nit=nlist.begin();nit!=nlist.end();++nit) { if(subview.FindAtom(nit->atom).IsValid()) { - new_nlist.push_back(*nit); + new_nlist.push_back(*nit); } } if(!new_nlist.empty()) { diff --git a/modules/gfx/src/impl/cartoon_renderer.cc b/modules/gfx/src/impl/cartoon_renderer.cc index 942bff0ab88f8bd60bfa9029e607ffcb8d129ef2..1dd9a8cbfd231cb76e1e241a281db634eb287440 100644 --- a/modules/gfx/src/impl/cartoon_renderer.cc +++ b/modules/gfx/src/impl/cartoon_renderer.cc @@ -505,12 +505,45 @@ TraceProfile CartoonRenderer::TransformAndAddProfile(const std::vector<TraceProf return tf_prof; } +namespace { + + float spread(const geom::Vec3& v1, geom::Vec3& v2, geom::Vec3& v3, geom::Vec3& v4) + { + return geom::Dot(geom::Normalize(geom::Cross(geom::Normalize(v3-v1),geom::Normalize(v2-v1))), + geom::Normalize(geom::Cross(geom::Normalize(v3-v4),geom::Normalize(v2-v4)))); + } + +} + void CartoonRenderer::AssembleProfile(const TraceProfile& prof1, const TraceProfile& prof2, IndexedVertexArray& va) { - // determine rotational offset with a heuristic routine - int best_off=0; + float accum[]={0.0,0.0,0.0,0.0,0.0}; + for(int i=0;i<prof1.size();++i) { + int i1=(i+0)%prof1.size(); + int i2=(i+1)%prof1.size(); + geom::Vec3 v1=va.GetVert(prof1[i1].id); + geom::Vec3 v2=va.GetVert(prof1[i2].id); + for(int k=-2;k<=2;++k) { + int i3=(i+k+0+prof1.size())%prof1.size(); + int i4=(i+k+1+prof1.size())%prof1.size(); + geom::Vec3 v3=va.GetVert(prof2[i3].id); + geom::Vec3 v4=va.GetVert(prof2[i4].id); + accum[k+2]+=spread(v1,v2,v3,v4); + } + } + + float best_spread=accum[0]; + int best_off=-2; + for(int k=-1;k<=2;++k) { + if(accum[k+2]<best_spread) { + best_spread=accum[k+2]; + best_off=k; + } + } + best_off=(best_off+prof1.size())%prof1.size(); + #if 0 uint i1=0; uint i2=prof1.size()/4; diff --git a/modules/gfx/src/impl/connect_renderer_base.hh b/modules/gfx/src/impl/connect_renderer_base.hh index 78b730fc18c5bc56cf5b0edd3a7df89fda2d2d6e..1c88950fff335dc19b90d5b80a6d298f1096ada7 100644 --- a/modules/gfx/src/impl/connect_renderer_base.hh +++ b/modules/gfx/src/impl/connect_renderer_base.hh @@ -60,7 +60,7 @@ protected: float GetFixedPickRadius() const { return pick_radius_; } protected: - float pick_radius_; + float pick_radius_; GfxView view_; GfxView sel_view_; }; diff --git a/modules/gfx/src/impl/entity_detail.cc b/modules/gfx/src/impl/entity_detail.cc index 399c342c2895134eb6ea850252a817c24bc6f040..c11c6a73c2fac5e5df04a04a640134ed74c4b8bf 100644 --- a/modules/gfx/src/impl/entity_detail.cc +++ b/modules/gfx/src/impl/entity_detail.cc @@ -16,19 +16,148 @@ // along with this library; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //------------------------------------------------------------------------------ + +#include <ost/gfx/gl_helper.hh> +#include <ost/gfx/scene.hh> +#include <ost/gfx/color.hh> + #include "entity_detail.hh" + namespace ost { using namespace mol; namespace gfx { namespace impl { - namespace { +namespace { + +static const float default_radius=0.28; + +struct BlurQuadEntry +{ + float zdist; + geom::Vec3 p1,p2,p3,p4; + gfx::Color c1,c2,c3,c4; +}; + +struct BlurQuadEntryLess +{ + bool operator()(const BlurQuadEntry& e1, const BlurQuadEntry& e2) + { + // provides back-to-front sorting + return e1.zdist<e2.zdist; + } +}; + +} // anon ns - static const float default_radius=0.28; +void DoRenderBlur(BondEntryList& bl, float bf1, float bf2) +{ + // add blur for this particular orientation! + // don't use vertex array, but on-the-fly oriented and z-sorted quads + mol::Transform tf = Scene::Instance().GetTransform(); + + std::vector<BlurQuadEntry> bql; + for (BondEntryList::iterator it=bl.begin(); it!=bl.end();++it) { + + if(!it->atom1 || !it->atom2) continue; + + const geom::Vec3 p0=tf.Apply(it->atom1->atom.GetPos()); + const geom::Vec3 p2=tf.Apply(it->atom2->atom.GetPos()); + geom::Vec3 p1=(p0+p2)*0.5; + + const geom::Vec3 q0=tf.Apply(it->pp1); + const geom::Vec3 q2=tf.Apply(it->pp2); + geom::Vec3 q1=(q0+q2)*0.5; + + float ll0 = geom::Length2(p0-q0); + float ll1 = geom::Length2(p1-q1); + float ll2 = geom::Length2(p2-q2); + + if(ll0<1e-2 && ll1<1e-2 && ll2<1e-2) continue; + + float x0 = exp(-bf1*ll0); + float x1 = exp(-bf1*ll1); + float x2 = exp(-bf1*ll2); + + BlurQuadEntry bqe; + + bqe.zdist=0.25*(p0[2]+p2[2]+q0[2]+q2[2]); + + // first half + bqe.p1 = p0; + bqe.p2 = p1; + bqe.p3 = q0; + bqe.p4 = q1; + bqe.c1 = it->atom1->color; + bqe.c2 = it->atom1->color; + bqe.c3 = it->atom1->color; + bqe.c4 = it->atom1->color; + bqe.c1[3] = x0; + bqe.c2[3] = x1; + bqe.c3[3]=x0*bf2; + bqe.c4[3]=x1*bf2; + + bql.push_back(bqe); + + // second half + bqe.p1 = p1; + bqe.p2 = p2; + bqe.p3 = q1; + bqe.p4 = q2; + bqe.c1 = it->atom2->color; + bqe.c2 = it->atom2->color; + bqe.c3 = it->atom2->color; + bqe.c4 = it->atom2->color; + bqe.c1[3] = x1; + bqe.c2[3] = x2; + bqe.c3[3]=x1*bf2; + bqe.c4[3]=x2*bf2; + + bql.push_back(bqe); + } + + std::sort(bql.begin(),bql.end(),BlurQuadEntryLess()); + + glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_LIGHTING_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + glDepthFunc(GL_LESS); + glDepthMask(GL_FALSE); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glBegin(GL_QUADS); + glNormal3f(0.0,0.0,0.0); + for (std::vector<BlurQuadEntry>::const_iterator it=bql.begin(); + it!=bql.end();++it) { + glColor4fv(it->c1); + glVertex3v(it->p1.Data()); + glColor4fv(it->c2); + glVertex3v(it->p2.Data()); + glColor4fv(it->c4); + glVertex3v(it->p4.Data()); + glColor4fv(it->c3); + glVertex3v(it->p3.Data()); + } + + glEnd(); + glPopMatrix(); + glPopAttrib(); +} +void DoBlurSnapshot(BondEntryList& bl) +{ + for (BondEntryList::iterator it=bl.begin(); + it!=bl.end();++it) { + if(it->atom1 && it->atom2) { + it->pp1=it->atom1->atom.GetPos(); + it->pp2=it->atom2->atom.GetPos(); + } } +} + void GfxView::Clear() { diff --git a/modules/gfx/src/impl/entity_detail.hh b/modules/gfx/src/impl/entity_detail.hh index 0b539993d35a859b64fd2a64ea448c1d07718ddc..36e2d5e5e2ea09b60c48b6a78a432f5fb1774ff7 100644 --- a/modules/gfx/src/impl/entity_detail.hh +++ b/modules/gfx/src/impl/entity_detail.hh @@ -70,6 +70,9 @@ struct DLLEXPORT_OST_GFX BondEntry typedef std::vector<BondEntry> BondEntryList; +void DoRenderBlur(BondEntryList& bl, float bf1, float bf2); +void DoBlurSnapshot(BondEntryList& bl); + class DLLEXPORT_OST_GFX GfxView { public: void Clear(); diff --git a/modules/gfx/src/impl/line_trace_renderer.cc b/modules/gfx/src/impl/line_trace_renderer.cc index efd91670667d0aa5d25db71f2c43aecb965ca623..e8fd9a224c094f144e8cda0ad4b64a6b01e5b98e 100644 --- a/modules/gfx/src/impl/line_trace_renderer.cc +++ b/modules/gfx/src/impl/line_trace_renderer.cc @@ -26,10 +26,36 @@ namespace ost { namespace gfx { namespace impl { +namespace { + +void add_atom_and_bond(mol::AtomHandle atom1,mol::AtomHandle atom2, AtomEntryMap& amap, BondEntryList& blist) +{ + AtomEntry ae1(atom1,0.0,0.0,Color(1,1,1)); + amap[atom1.GetHashCode()]=ae1; + AtomEntry ae2(atom2,0.0,0.0,Color(1,1,1)); + amap[atom2.GetHashCode()]=ae2; + blist.push_back(BondEntry(mol::BondHandle(),0.0f, + &amap[atom1.GetHashCode()], + &amap[atom2.GetHashCode()])); +} + +} + + LineTraceRenderer::LineTraceRenderer(BackboneTrace* trace): - TraceRendererBase(trace, 1), options_(new LineTraceRenderOptions()) + TraceRendererBase(trace, 1), + options_(new LineTraceRenderOptions()), + amap_(), + blist_() { this->SetName("Fast Trace"); + + for (int node_list=0; node_list<trace->GetListCount(); ++node_list) { + const NodeEntryList& nl=trace->GetList(node_list); + for (unsigned int i=0; i<nl.size()-1;++i) { + add_atom_and_bond(nl[i].atom,nl[i+1].atom,amap_,blist_); + } + } } void LineTraceRenderer::PrepareRendering() @@ -61,14 +87,13 @@ void LineTraceRenderer::PrepareRendering(const BackboneTrace& trace_subset, va.SetAALines(options_->GetAALines()); for (int node_list=0; node_list<trace_subset.GetListCount(); ++node_list) { const NodeEntryList& nl=trace_subset.GetList(node_list); - + if (nl.size()<2) { - continue; + continue; } VertexID p0=va.Add(nl[0].atom.GetPos(), geom::Vec3(), - is_sel ? sel_clr : nl[0].color1); - + is_sel ? sel_clr : nl[0].color1); for (unsigned int i=1; i<nl.size()-1;++i) { const NodeEntry& entry=nl[i]; VertexID p1 =va.Add(entry.atom.GetPos(), geom::Vec3(), @@ -76,9 +101,9 @@ void LineTraceRenderer::PrepareRendering(const BackboneTrace& trace_subset, va.AddLine(p0, p1); p0=p1; } - const NodeEntry& entry=nl.back(); + const NodeEntry& entry=nl.back(); VertexID p1 =va.Add(entry.atom.GetPos(), geom::Vec3(), - is_sel ? sel_clr : entry.color1); + is_sel ? sel_clr : entry.color1); va.AddLine(p0, p1); } } diff --git a/modules/gfx/src/impl/line_trace_renderer.hh b/modules/gfx/src/impl/line_trace_renderer.hh index 39f1e0e10a60cdd6a740cb2076a90d7991f3d23c..ce42fc004dd6c70b444c04d7bea50d751dedb330 100644 --- a/modules/gfx/src/impl/line_trace_renderer.hh +++ b/modules/gfx/src/impl/line_trace_renderer.hh @@ -53,8 +53,12 @@ public: virtual ~LineTraceRenderer(); + BondEntryList& GetBondEntryList() {return blist_;} + private: LineTraceRenderOptionsPtr options_; + AtomEntryMap amap_; // for blur rendering + BondEntryList blist_; // dito }; }}} diff --git a/modules/gfx/src/impl/simple_renderer.cc b/modules/gfx/src/impl/simple_renderer.cc index 4e228f0dc06f9e7fee003411bbf02f241de77e26..983ef012d4476adf0857c3a747787dfeccb740cf 100644 --- a/modules/gfx/src/impl/simple_renderer.cc +++ b/modules/gfx/src/impl/simple_renderer.cc @@ -30,25 +30,6 @@ namespace ost { namespace gfx { namespace impl { -namespace { - -struct BlurQuadEntry -{ - float zdist; - geom::Vec3 p1,p2,p3,p4; - Color c1,c2,c3,c4; -}; - -struct BlurQuadEntryLess -{ - bool operator()(const BlurQuadEntry& e1, const BlurQuadEntry& e2) - { - // provides back-to-front sorting - return e1.zdist<e2.zdist; - } -}; - -} SimpleRenderer::SimpleRenderer(): options_(new SimpleRenderOptions()) { @@ -200,120 +181,9 @@ void SimpleRenderer::PrepareRendering(GfxView& view, IndexedVertexArray& va) } } -void SimpleRenderer::RenderBlur() -{ - // add blur for this particular orientation! - // don't use vertex array, but on-the-fly oriented and z-sorted quads - mol::Transform tf = Scene::Instance().GetTransform(); - - std::vector<BlurQuadEntry> bql; - const std::pair<Real, Real>& bf=options_->GetBlurFactors(); - for (BondEntryList::iterator it=view_.bond_list.begin(); - it!=view_.bond_list.end();++it) { - - const geom::Vec3 p0=tf.Apply(it->bond.GetFirst().GetPos()); - const geom::Vec3 p2=tf.Apply(it->bond.GetSecond().GetPos()); - geom::Vec3 p1=(p0+p2)*0.5; - - const geom::Vec3 q0=tf.Apply(it->pp1); - const geom::Vec3 q2=tf.Apply(it->pp2); - geom::Vec3 q1=(q0+q2)*0.5; - - float ll0 = geom::Length2(p0-q0); - float ll1 = geom::Length2(p1-q1); - float ll2 = geom::Length2(p2-q2); - - if(ll0<1e-2 && ll1<1e-2 && ll2<1e-2) continue; - - float x0 = exp(-bf.first*ll0); - float x1 = exp(-bf.first*ll1); - float x2 = exp(-bf.first*ll2); - - BlurQuadEntry bqe; - - bqe.zdist=0.25*(p0[2]+p2[2]+q0[2]+q2[2]); - - // first half - bqe.p1 = p0; - bqe.p2 = p1; - bqe.p3 = q0; - bqe.p4 = q1; - bqe.c1 = it->atom1->color; - bqe.c2 = it->atom1->color; - bqe.c3 = it->atom1->color; - bqe.c4 = it->atom1->color; - bqe.c1[3] = x0; - bqe.c2[3] = x1; - bqe.c3[3]=x0*bf.second; - bqe.c4[3]=x1*bf.second; - - bql.push_back(bqe); - - // first half - bqe.p1 = p1; - bqe.p2 = p2; - bqe.p3 = q1; - bqe.p4 = q2; - bqe.c1 = it->atom2->color; - bqe.c2 = it->atom2->color; - bqe.c3 = it->atom2->color; - bqe.c4 = it->atom2->color; - bqe.c1[3] = x1; - bqe.c2[3] = x2; - bqe.c3[3]=x1*bf.second; - bqe.c4[3]=x2*bf.second; - - bql.push_back(bqe); - } - - std::sort(bql.begin(),bql.end(),BlurQuadEntryLess()); - - glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT); - glDisable(GL_LIGHTING); - glDisable(GL_CULL_FACE); - glDepthFunc(GL_LESS); - glDepthMask(GL_FALSE); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glBegin(GL_QUADS); - glNormal3f(0.0,0.0,0.0); - for (std::vector<BlurQuadEntry>::const_iterator it=bql.begin(); - it!=bql.end();++it) { - glColor4fv(it->c1); - glVertex3v(it->p1.Data()); - glColor4fv(it->c2); - glVertex3v(it->p2.Data()); - glColor4fv(it->c4); - glVertex3v(it->p4.Data()); - glColor4fv(it->c3); - glVertex3v(it->p3.Data()); - } - - glEnd(); - glPopMatrix(); - glPopAttrib(); -} - -void SimpleRenderer::BlurSnapshot() +BondEntryList& SimpleRenderer::GetBondEntryList() { - for (BondEntryList::iterator it=view_.bond_list.begin(); - it!=view_.bond_list.end();++it) { - it->pp1=it->atom1->atom.GetPos(); - it->pp2=it->atom2->atom.GetPos(); - } -} -void SimpleRenderer::Render(RenderPass pass) -{ - ConnectRendererBase::Render(pass); - if (pass==STANDARD_RENDER_PASS && options_->GetBlurFlag()) { - this->RenderBlur(); - } -} - -SimpleRenderer::~SimpleRenderer() -{ - + return view_.bond_list; } void SimpleRenderer::RenderPov(PovState& pov, const std::string& name) diff --git a/modules/gfx/src/impl/simple_renderer.hh b/modules/gfx/src/impl/simple_renderer.hh index 78038ffe543780b5d92389866d142c105cbcd8ba..41b801cbd6721d4a57309edf271c80f6d7dbb8e3 100644 --- a/modules/gfx/src/impl/simple_renderer.hh +++ b/modules/gfx/src/impl/simple_renderer.hh @@ -43,12 +43,10 @@ public: virtual void SetOptions(RenderOptionsPtr& render_options); virtual RenderOptionsPtr GetOptions(); - virtual void Render(RenderPass pass); - virtual ~SimpleRenderer(); virtual void RenderPov(PovState& pov, const std::string& name); - void BlurSnapshot(); + + BondEntryList& GetBondEntryList(); private: - void RenderBlur(); void PrepareRendering(GfxView& view, IndexedVertexArray& va); geom::Vec3 GetDoubleBondPlane(mol::BondHandle b); void GetBondPartnerNormal(geom::Vec3& vec, int& n, geom::Vec3& bond_vec, diff --git a/modules/gfx/src/impl/trace_renderer_base.cc b/modules/gfx/src/impl/trace_renderer_base.cc index 9231e929c5c791fc823bfbb8afc108b14d32319d..8ccf5e26ee514d6a4dae4d54062b94d765e52598 100644 --- a/modules/gfx/src/impl/trace_renderer_base.cc +++ b/modules/gfx/src/impl/trace_renderer_base.cc @@ -72,7 +72,7 @@ inline void apply_color_op(TraceRendererBase* rend, BackboneTrace& trace_subset, } //ns TraceRendererBase::TraceRendererBase(BackboneTrace* trace, int n): - trace_(trace), trace_subset_(*trace), sel_subset_() + trace_(trace), trace_subset_(), sel_subset_() { } diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc index ead1566ffb0621989f3edcf597c2e1ead2cd411b..181120438e325e610919e2c1d19ea0729f444b65 100644 --- a/modules/gfx/src/scene.cc +++ b/modules/gfx/src/scene.cc @@ -56,8 +56,6 @@ # include "shader.hh" #endif -//#define DEBUG_SMAP - using boost::bind; namespace ost { @@ -113,6 +111,7 @@ Scene::Scene(): shadow_flag_(false), shadow_quality_(1), shadow_tex_id_(), + depth_dark_flag_(false), depth_tex_id_(), kernel_tex_id_(), scene_tex_id_(), @@ -168,20 +167,45 @@ Color Scene::GetFogColor() const void Scene::SetShadow(bool f) { shadow_flag_=f; + // the redraw routine will deal with the Shader RequestRedraw(); } -bool Scene::GetShadow() +void Scene::SetShadowQuality(int q) { - return shadow_flag_; + shadow_quality_=std::min(3,std::max(0,q)); + if(shadow_flag_) { + RequestRedraw(); + } } -void Scene::SetShadowQuality(int q) +void Scene::SetDepthDarkening(bool f) { - shadow_quality_=std::min(3,std::max(0,q)); + depth_dark_flag_=f; + // the redraw routine will deal with the Shader RequestRedraw(); } + +void Scene::SetShadingMode(const std::string& smode) +{ +#if OST_SHADER_SUPPORT_ENABLED + if(smode=="fallback") { + Shader::Instance().Activate(""); + } else if(smode=="basic") { + Shader::Instance().Activate("basic"); + } else if(smode=="hf") { + Shader::Instance().Activate("hemilight"); + } else if(smode=="toon1") { + Shader::Instance().Activate("toon1"); + } else if(smode=="toon2") { + Shader::Instance().Activate("toon2"); + } else { + Shader::Instance().Activate("fraglight"); + } +#endif +} + namespace { void set_light_dir(Vec3 ld) @@ -286,7 +310,7 @@ void Scene::InitGL() #if OST_SHADER_SUPPORT_ENABLED LOGN_DEBUG("scene: shader setup"); Shader::Instance().Setup(); - Shader::Instance().Activate("fraglight"); + SetShadingMode("default"); glGenTextures(1,&shadow_tex_id_); glGenTextures(1,&depth_tex_id_); @@ -474,12 +498,16 @@ void Scene::RenderGL() if(auto_autoslab_) Autoslab(false, false); #if OST_SHADER_SUPPORT_ENABLED - if(shadow_flag_) { - prep_shadow_map(); - #ifdef DEBUG_SMAP - return; - #endif - } + if(depth_dark_flag_) { + prep_depth_darkening(); + } else { + Shader::Instance().SetDepthMapping(0,0); + } + if(shadow_flag_) { + prep_shadow_map(); + } else { + Shader::Instance().SetShadowMapping(0,0); + } #endif glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); prep_blur(); @@ -1543,6 +1571,95 @@ void Scene::update_fog() glFogf(GL_FOG_END,zfar_+ffar_); } +namespace { + + void draw_screen_quad(unsigned int w, unsigned int h, GLuint gltex, GLuint tex_id) + { + glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_FOG_BIT); + + // setup + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_FOG); + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + glDisable(GL_LINE_SMOOTH); + glDisable(GL_POINT_SMOOTH); + glClear(GL_COLOR_BUFFER_BIT); + glViewport(0,0,w,h); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0,1,0,1,-1,1); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // draw + glColor3f(1.0,0.0,1.0); + glBegin(GL_QUADS); + glTexCoord2f(0.0,0.0); + glVertex2f(0.0,0.0); + glTexCoord2f(0.0,1.0); + glVertex2f(0.0,1.0); + glTexCoord2f(1.0,1.0); + glVertex2f(1.0,1.0); + glTexCoord2f(1.0,0.0); + glVertex2f(1.0,0.0); + glEnd(); + + // grab the result + glEnable(GL_TEXTURE_2D); + glActiveTexture(gltex); + glBindTexture(GL_TEXTURE_2D, tex_id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0,0, w, h, 0); + + // restore settings + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glPopAttrib(); + } + + // this debug code draws the given texture across the complete screen + void draw_debug_tex(unsigned int w, unsigned int h, GLuint tex_id) + { + glPushAttrib(GL_ALL_ATTRIB_BITS); + Shader::Instance().PushProgram(); + + Shader::Instance().Activate(""); + glViewport(0,0,w,h); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0,1,0,1,-1,1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glColor3f(1.0,0.0,1.0); + glEnable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex_id); + glBegin(GL_QUADS); + glTexCoord2f(0.0,0.0); + glVertex2f(0.01,0.01); + glTexCoord2f(0.0,1.0); + glVertex2f(0.01,0.99); + glTexCoord2f(1.0,1.0); + glVertex2f(0.99,0.99); + glTexCoord2f(1.0,0.0); + glVertex2f(0.99,0.01); + glEnd(); + glPopAttrib(); + Shader::Instance().PopProgram(); + } +} + void Scene::prep_shadow_map() { #if OST_SHADER_SUPPORT_ENABLED @@ -1560,20 +1677,19 @@ void Scene::prep_shadow_map() // render pass 1 - without shadows // turn shadowing off for subsequent rendering - glUniform1i(glGetUniformLocation(Shader::Instance().GetCurrentProgram(), - "shadow_flag"),0); + Shader::Instance().SetShadowMapping(false,0); + // save overall gl settings glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); // maximize rendering for depth-only information -#ifndef DEBUG_SMAP glDisable(GL_LIGHTING); glDisable(GL_FOG); glDisable(GL_COLOR_MATERIAL); glDisable(GL_NORMALIZE); glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); -#endif // render scene with only depth components + // seen from the light's perspective glViewport(0,0,smap_size,smap_size); glClear(GL_DEPTH_BUFFER_BIT); @@ -1601,7 +1717,6 @@ void Scene::prep_shadow_map() glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0,0, smap_size,smap_size, 0); - //////////////// // all of the following texture and shader params need to be moved // to a one-time initialization place glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -1611,21 +1726,8 @@ void Scene::prep_shadow_map() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - GLuint cpr=Shader::Instance().GetCurrentProgram(); - // assign tex unit 0 to shadow map - glUniform1i(glGetUniformLocation(Shader::Instance().GetCurrentProgram(),"shadow_map"),0); - //int depth_bits; - //glGetIntegerv(GL_DEPTH_BITS, &depth_bits); - //float depth_bias = 1.0/static_cast<float>(1<<depth_bits); - glUniform1f(glGetUniformLocation(cpr,"depth_bias"),0.008); - - glUniform1f(glGetUniformLocation(cpr,"epsilon"),0.002); - - glUniform1f(glGetUniformLocation(cpr,"shadow_multiplier"),0.4); - - // - ////////////////// + Shader::Instance().SetShadowMapping(true,0); // restore settings glPopMatrix(); @@ -1638,10 +1740,6 @@ void Scene::prep_shadow_map() glEnable(GL_TEXTURE_2D); - // and turn shadowing on for subsequent rendering - glUniform1i(glGetUniformLocation(cpr,"shadow_flag"),1); - -#ifndef DEBUG_SMAP // set up appropriate texture matrix Mat4 bias(0.5,0.0,0.0,0.5, 0.0,0.5,0.0,0.5, @@ -1655,45 +1753,47 @@ void Scene::prep_shadow_map() Mat4 ttmp=Transpose(texm); glLoadMatrix(ttmp.Data()); glMatrixMode(GL_MODELVIEW); -#else - // this debug code draws the depth map across the screen - Shader::Instance().Activate(""); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glDisable(GL_CULL_FACE); - glDisable(GL_LIGHTING); - glDisable(GL_FOG); - glEnable(GL_TEXTURE_2D); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(-1,11,-1,11,-1,1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glColor3f(1.0,1.0,1.0); - glBegin(GL_QUADS); - glTexCoord2f(0.0,0.0); - glVertex2f(0.0,0.0); - glTexCoord2f(0.0,1.0); - glVertex2f(0.0,10.0); - glTexCoord2f(1.0,1.0); - glVertex2f(10.0,10.0); - glTexCoord2f(1.0,0.0); - glVertex2f(10.0,0.0); - glEnd(); - Shader::Instance().Activate("basic_shadow"); #endif +} + +void Scene::prep_depth_darkening() +{ +#if OST_SHADER_SUPPORT_ENABLED + prep_depth_map(vp_width_/2,vp_height_/2); + // in unit 1, bound to depth_tex_id_ + + // kernel is static for now, inside the convolution shader + + // now convolute the depth map with the kernel + Shader::Instance().PushProgram(); + Shader::Instance().Activate("convolute1"); + GLuint cpr=Shader::Instance().GetCurrentProgram(); + // assign tex units + glUniform1i(glGetUniformLocation(cpr,"data"),1); + glUniform1i(glGetUniformLocation(cpr,"vp_width"),vp_width_/2); + glUniform1i(glGetUniformLocation(cpr,"vp_height"),vp_height_/2); + + // set up viewport filling quad to run the fragment shader + draw_screen_quad(vp_width_/2,vp_height_/2,GL_TEXTURE1, depth_tex_id_); + + Shader::Instance().PopProgram(); + + // mode 1, tex unit 1 + Shader::Instance().SetDepthMapping(1,1); + #endif } -void Scene::prep_depth_map() +// returns the depth map in texture 1 +// bound to depth_tex_id_ +void Scene::prep_depth_map(unsigned int w, unsigned int h) { #if OST_SHADER_SUPPORT_ENABLED - unsigned int vp_width2=vp_width_/2; - unsigned int vp_height2=vp_height_/2; + unsigned int vp_width2=w; + unsigned int vp_height2=h; // render pass 1 - without shadows - // turn shadowing off for subsequent rendering - glUniform1i(glGetUniformLocation(Shader::Instance().GetCurrentProgram(), - "shadow_flag"),0); + Shader::Instance().SetShadowMapping(false,0); // save overall gl settings glPushAttrib(GL_ENABLE_BIT); // maximize rendering for depth-only information @@ -1731,127 +1831,6 @@ void Scene::prep_depth_map() glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); glViewport(0,0,vp_width_,vp_height_); - // next is the kernel - static std::vector<GLfloat> kernel_data; - if(kernel_data.empty()) { - int kernel_size=2; - float sum=0.0; - float prec=0.02; - float sigma=static_cast<float>(kernel_size)/std::sqrt(-std::log(prec)); - for( int u=-kernel_size;u<=kernel_size;++u) { - for( int v=-kernel_size;v<=kernel_size;++v) { - float y=std::exp(static_cast<float>(-u*u-v*v)/(sigma*sigma)); - if(y>=prec) { - sum+=y; - kernel_data.push_back(static_cast<float>(u)); - kernel_data.push_back(static_cast<float>(v)); - kernel_data.push_back(y); - } - } - } - float ivpw=1.0/static_cast<float>(vp_width2); - float ivph=1.0/static_cast<float>(vp_height2); - for(unsigned int i=0;i<kernel_data.size();i+=3) { - kernel_data[i+0]=(ivpw*kernel_data[i+0])*0.5+0.5; - kernel_data[i+1]=(ivph*kernel_data[i+1])*0.5+0.5; - kernel_data[i+2]=kernel_data[i+2]/sum; - } - } - - glEnable(GL_TEXTURE_1D); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_1D, kernel_tex_id_); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexImage1D(GL_TEXTURE_1D,0,GL_RGB,kernel_data.size()/3,0,GL_RGB,GL_FLOAT,&kernel_data[0]); - - // now convolute the depth map with the kernel - Shader::Instance().PushProgram(); - Shader::Instance().Activate("convolute1"); - GLuint cpr=Shader::Instance().GetCurrentProgram(); - // assign tex units - glUniform1i(glGetUniformLocation(cpr,"data"),1); - glUniform1i(glGetUniformLocation(cpr,"kernel"),2); - glUniform1i(glGetUniformLocation(cpr,"kernel_size"),kernel_data.size()); - glUniform1i(glGetUniformLocation(cpr,"vp_width"),vp_width_); - glUniform1i(glGetUniformLocation(cpr,"vp_height"),vp_height_); - - // set up viewport filling quad to run the fragment shader - glPushAttrib(GL_ENABLE_BIT); - glDisable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT); - glViewport(0,0,vp_width2,vp_height2); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0,1,0,1,-1,1); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glColor3f(1.0,0.0,1.0); - glBegin(GL_QUADS); - glTexCoord2f(0.0,0.0); - glVertex2f(0.0,0.0); - glTexCoord2f(0.0,1.0); - glVertex2f(0.0,1.0); - glTexCoord2f(1.0,1.0); - glVertex2f(1.0,1.0); - glTexCoord2f(1.0,0.0); - glVertex2f(1.0,0.0); - glEnd(); - - // now grab the result - glEnable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, scene_tex_id_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - 0,0, vp_width2, vp_height2, 0); - - -#if 1 - // this debug code draws the depth map across the complete screen - //glViewport(0,0,vp_width_,vp_height_); - Shader::Instance().Activate(""); - glViewport(0,0,vp_width_,vp_height_); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0,1,0,1,-1,1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glColor3f(1.0,0.0,1.0); - glEnable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, scene_tex_id_); - glBegin(GL_QUADS); - glTexCoord2f(0.0,0.0); - glVertex2f(0.01,0.01); - glTexCoord2f(0.0,1.0); - glVertex2f(0.01,0.99); - glTexCoord2f(1.0,1.0); - glVertex2f(0.99,0.99); - glTexCoord2f(1.0,0.0); - glVertex2f(0.99,0.01); - glEnd(); -#endif - - // restore settings - Shader::Instance().PopProgram(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glPopAttrib(); - glViewport(0,0,vp_width_,vp_height_); - - - #endif } @@ -1902,14 +1881,6 @@ void Scene::SetTestMode(bool f) } } -// temporary interface -void Scene::ActivateShader(const String& name) -{ -#if OST_SHADER_SUPPORT_ENABLED - Shader::Instance().Activate(name); -#endif -} - void Scene::prep_glyphs() { glGenTextures(1,&glyph_tex_id_); diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh index 6896d29e7fa6a933485920abeb1865ecf82bcbbd..142b4c94278a6c05270bd1aae6618c5f9576bb7c 100644 --- a/modules/gfx/src/scene.hh +++ b/modules/gfx/src/scene.hh @@ -102,15 +102,21 @@ class DLLEXPORT_OST_GFX Scene { /// \brief get the fog color Color GetFogColor() const; - /// \brief turn shadow on and off + /// \brief turn shadow mapping on and off void SetShadow(bool f); - /// \brief returns true if shadow is on - bool GetShadow(); + /// \brief get shadow mapping status + bool GetShadow() const {return shadow_flag_;} /// \brief shadow quality from 0 (low) to 3 (high), default=1 void SetShadowQuality(int q); + + void SetDepthDarkening(bool f); + /// \brief select shading mode + /// one of fallback, basic, default, hf, toon1, toon2 + void SetShadingMode(const std::string& smode); + /// \name clipping planes //@{ /// \brief get near clipping plane @@ -345,9 +351,6 @@ class DLLEXPORT_OST_GFX Scene { /// \brief stops offline rendering in interactive mode void StopOffscreenMode(); - // temporary interface - void ActivateShader(const String& name); - void SetBlur(uint n); void BlurSnapshot(); @@ -404,6 +407,7 @@ private: bool shadow_flag_; int shadow_quality_; GLuint shadow_tex_id_; + bool depth_dark_flag_; GLuint depth_tex_id_; GLuint kernel_tex_id_; GLuint scene_tex_id_; @@ -434,7 +438,8 @@ private: void set_far(float f); void update_fog(); void prep_shadow_map(); - void prep_depth_map(); + void prep_depth_darkening(); + void prep_depth_map(uint,uint); void flag_all_dirty(); void prep_glyphs(); void prep_blur(); diff --git a/modules/gfx/src/shader.cc b/modules/gfx/src/shader.cc index cb4af5c5b6cf1b26df661bc6ad7cc65d545d5168..982306a52484825899df521514863cc6ebc67d76 100644 --- a/modules/gfx/src/shader.cc +++ b/modules/gfx/src/shader.cc @@ -131,12 +131,8 @@ void Shader::Setup() ////////////////////////////////////////////////////////////////// // this is the master list of all shader code in shader/ - {"basic_lf_vs.glsl", GL_VERTEX_SHADER}, - {"basic_lf_fs.glsl", GL_FRAGMENT_SHADER}, - {"fraglight_lf_vs.glsl", GL_VERTEX_SHADER}, - {"fraglight_lf_fs.glsl", GL_FRAGMENT_SHADER}, - {"basic_lfs_vs.glsl", GL_VERTEX_SHADER}, - {"basic_lfs_fs.glsl", GL_FRAGMENT_SHADER}, + {"basic_vs.glsl", GL_VERTEX_SHADER}, + {"basic_fs.glsl", GL_FRAGMENT_SHADER}, {"fraglight_vs.glsl", GL_VERTEX_SHADER}, {"fraglight_fs.glsl", GL_FRAGMENT_SHADER}, {"basic_hf_vs.glsl", GL_VERTEX_SHADER}, @@ -186,36 +182,22 @@ void Shader::Setup() std::vector<GLuint> shader_program_list; GLuint shader_program_id; // basic shader - shader_program_list.push_back(shader_code_map_["basic_lf_vs.glsl"]); - shader_program_list.push_back(shader_code_map_["basic_lf_fs.glsl"]); + shader_program_list.push_back(shader_code_map_["basic_vs.glsl"]); + shader_program_list.push_back(shader_code_map_["basic_fs.glsl"]); if(link_shader(shader_program_list,"basic",shader_program_id)) { shader_program_map_["basic"]=shader_program_id; } // fraglight shader shader_program_list.clear(); - shader_program_list.push_back(shader_code_map_["fraglight_lf_vs.glsl"]); - shader_program_list.push_back(shader_code_map_["fraglight_lf_fs.glsl"]); - if(link_shader(shader_program_list,"fraglight",shader_program_id)) { - shader_program_map_["fraglight"]=shader_program_id; - } - // basic shadow map shader - shader_program_list.clear(); - shader_program_list.push_back(shader_code_map_["basic_lfs_vs.glsl"]); - shader_program_list.push_back(shader_code_map_["basic_lfs_fs.glsl"]); - if(link_shader(shader_program_list,"basic_shadow",shader_program_id)) { - shader_program_map_["basic_shadow"]=shader_program_id; - } - // fraglight shader with shadow map - shader_program_list.clear(); shader_program_list.push_back(shader_code_map_["fraglight_vs.glsl"]); shader_program_list.push_back(shader_code_map_["fraglight_fs.glsl"]); - if(link_shader(shader_program_list,"fraglight_shadow",shader_program_id)) { - shader_program_map_["fraglight_shadow"]=shader_program_id; + if(link_shader(shader_program_list,"fraglight",shader_program_id)) { + shader_program_map_["fraglight"]=shader_program_id; } // basic hemisphere lighting shader shader_program_list.clear(); shader_program_list.push_back(shader_code_map_["basic_hf_vs.glsl"]); - shader_program_list.push_back(shader_code_map_["basic_lf_fs.glsl"]); + shader_program_list.push_back(shader_code_map_["basic_fs.glsl"]); if(link_shader(shader_program_list,"hemilight",shader_program_id)) { shader_program_map_["hemilight"]=shader_program_id; } @@ -230,8 +212,8 @@ void Shader::Setup() shader_program_list.clear(); shader_program_list.push_back(shader_code_map_["toon_vs.glsl"]); shader_program_list.push_back(shader_code_map_["toon_fs.glsl"]); - if(link_shader(shader_program_list,"toon",shader_program_id)) { - shader_program_map_["toon"]=shader_program_id; + if(link_shader(shader_program_list,"toon1",shader_program_id)) { + shader_program_map_["toon1"]=shader_program_id; } // toon2 shader shader_program_list.clear(); @@ -242,7 +224,7 @@ void Shader::Setup() } // line shader shader_program_list.clear(); - shader_program_list.push_back(shader_code_map_["basic_lf_vs.glsl"]); + shader_program_list.push_back(shader_code_map_["basic_vs.glsl"]); shader_program_list.push_back(shader_code_map_["aaline_fs.glsl"]); if(link_shader(shader_program_list,"aaline",shader_program_id)) { shader_program_map_["aaline"]=shader_program_id; @@ -264,7 +246,7 @@ void Shader::Setup() // outline shader shader_program_list.clear(); shader_program_list.push_back(shader_code_map_["outline_vs.glsl"]); - shader_program_list.push_back(shader_code_map_["basic_lf_fs.glsl"]); + shader_program_list.push_back(shader_code_map_["basic_fs.glsl"]); if(link_shader(shader_program_list,"outline",shader_program_id)) { shader_program_map_["outline"]=shader_program_id; } @@ -289,14 +271,6 @@ void Shader::Activate(const String& name) current_program_=it->second; current_name_=name; - if(name=="basic_shadow" || name=="fraglight_shadow") { - if(!Scene::Instance().GetShadow()) - Scene::Instance().SetShadow(true); - } else { - if(Scene::Instance().GetShadow()) - Scene::Instance().SetShadow(false); - } - UpdateState(); return; @@ -345,10 +319,28 @@ void Shader::PopProgram() } } +void Shader::SetShadowMapping(bool flag, GLuint texid) +{ + shadow_flag_=flag; + if(flag) { + shadow_map_id_=texid; + } + UpdateState(); +} + +void Shader::SetDepthMapping(int mode, GLuint texid) +{ + depth_mode_=mode; + if(mode>0) { + depth_map_id_=texid; + } + UpdateState(); +} + void Shader::UpdateState() { if(current_program_!=0) { - // update current lighting and fog settings, valid for all shaders + // update all settings GLint result; glGetIntegerv(GL_LIGHTING,&result); LOGN_TRACE("setting lighting flag to " << result); @@ -360,7 +352,25 @@ void Shader::UpdateState() glGetIntegerv(GL_FOG,&result); LOGN_TRACE("setting fog flag to " << result); glUniform1i(glGetUniformLocation(current_program_,"fog_flag"),result); + if(shadow_flag_) { + LOGN_TRACE("setting shadow flag to 1"); + glUniform1i(glGetUniformLocation(current_program_,"shadow_flag"),1); + glUniform1i(glGetUniformLocation(current_program_,"shadow_map"),shadow_map_id_); + glUniform1f(glGetUniformLocation(current_program_,"shadow_depth_bias"),0.008); + glUniform1f(glGetUniformLocation(current_program_,"shadow_epsilon"),0.002); + glUniform1f(glGetUniformLocation(current_program_,"shadow_multiplier"),0.4); + } else { + LOGN_TRACE("setting shadow flag to 0"); + glUniform1i(glGetUniformLocation(current_program_,"shadow_flag"),0); + } + LOGN_TRACE("setting depth mode to" << depth_mode_); + glUniform1i(glGetUniformLocation(current_program_,"depth_mode"),depth_mode_); + if(depth_mode_>0) { + glUniform1i(glGetUniformLocation(current_program_,"depth_map"),depth_map_id_); + } + glDisable(GL_COLOR_MATERIAL); + } else { glEnable(GL_COLOR_MATERIAL); } diff --git a/modules/gfx/src/shader.hh b/modules/gfx/src/shader.hh index 054fdc37e1e98c19f27a6d29a17f20085547b895..32ea8d1297e719070c71314a4c4ec2fe288c848d 100644 --- a/modules/gfx/src/shader.hh +++ b/modules/gfx/src/shader.hh @@ -52,6 +52,9 @@ public: void PopProgram(); void UpdateState(); + + void SetShadowMapping(bool flag, GLuint texid); + void SetDepthMapping(int mode, GLuint texid); private: Shader(); @@ -60,6 +63,11 @@ private: GLuint current_program_; String current_name_; + bool shadow_flag_; + GLuint shadow_map_id_; + int depth_mode_; + GLuint depth_map_id_; + std::stack<String> program_stack_; std::map<String,GLuint> shader_code_map_; diff --git a/modules/gfx/src/shader/basic_lfs_fs.glsl b/modules/gfx/src/shader/basic_fs.glsl similarity index 86% rename from modules/gfx/src/shader/basic_lfs_fs.glsl rename to modules/gfx/src/shader/basic_fs.glsl index 66d8b04415336972b8553a7146601e67516e6dea..ceda497725ff8666bda220f6ab20e734bb66bae9 100644 --- a/modules/gfx/src/shader/basic_lfs_fs.glsl +++ b/modules/gfx/src/shader/basic_fs.glsl @@ -1,14 +1,14 @@ uniform sampler2D shadow_map; uniform bool shadow_flag; -uniform float depth_bias; -uniform float epsilon; +uniform float shadow_depth_bias; +uniform float shadow_epsilon; uniform float shadow_multiplier; uniform bool fog_flag; float CalcShadowFactor(in vec4 coord, in vec2 o) { // get original depth value of line projected towards light - float d = texture2D(shadow_map, coord.xy+o*epsilon).x+depth_bias; + float d = texture2D(shadow_map, coord.xy+o*shadow_epsilon).x+shadow_depth_bias; return d<=coord.z ? shadow_multiplier : 1.0; } diff --git a/modules/gfx/src/shader/basic_lfs_vs.glsl b/modules/gfx/src/shader/basic_vs.glsl similarity index 100% rename from modules/gfx/src/shader/basic_lfs_vs.glsl rename to modules/gfx/src/shader/basic_vs.glsl diff --git a/modules/gfx/src/shader/fraglight_fs.glsl b/modules/gfx/src/shader/fraglight_fs.glsl index d4ed6cb6f03e2eda9830169532a02672c10105d1..ac28cee890768a42313d1a3feb297b40a60b6937 100644 --- a/modules/gfx/src/shader/fraglight_fs.glsl +++ b/modules/gfx/src/shader/fraglight_fs.glsl @@ -4,11 +4,13 @@ uniform bool fog_flag; uniform bool occlusion_flag; uniform vec2 ambient_weight; varying vec4 ambient_color; -uniform sampler2D shadow_map; uniform bool shadow_flag; -uniform float depth_bias; -uniform float epsilon; +uniform sampler2D shadow_map; +uniform float shadow_depth_bias; +uniform float shadow_epsilon; uniform float shadow_multiplier; +uniform sampler2D depth_map; +uniform int depth_mode; // copy from basic_fl_vs ! bool DirectionalLight(in vec3 normal, @@ -38,7 +40,7 @@ bool DirectionalLight(in vec3 normal, float CalcShadowFactor(in vec4 coord, in vec2 o) { // get original depth value of line projected towards light - float d = texture2D(shadow_map, coord.xy+o*epsilon).x+depth_bias; + float d = texture2D(shadow_map, coord.xy+o*shadow_epsilon).x+shadow_depth_bias; return d<=coord.z ? shadow_multiplier : 1.0; } diff --git a/modules/gui/src/gl_canvas.cc b/modules/gui/src/gl_canvas.cc index 320cc3d0f129f046c9f52aa5ed775cee31a6d7d4..1b953d77ce40e08ac05766da1995fdc9fca9b286 100644 --- a/modules/gui/src/gl_canvas.cc +++ b/modules/gui/src/gl_canvas.cc @@ -342,35 +342,31 @@ void GLCanvas::keyPressEvent(QKeyEvent* event) this->CopySelectionToClipboard(); return; } else if(event->key()==Qt::Key_1) { - gfx::Scene::Instance().ActivateShader(""); + gfx::Scene::Instance().SetShadingMode("fallback"); DoRefresh(); return; } else if(event->key()==Qt::Key_2) { - gfx::Scene::Instance().ActivateShader("basic"); + gfx::Scene::Instance().SetShadingMode("basic"); DoRefresh(); return; } else if(event->key()==Qt::Key_3) { - gfx::Scene::Instance().ActivateShader("fraglight"); + gfx::Scene::Instance().SetShadingMode("default"); DoRefresh(); return; } else if(event->key()==Qt::Key_4) { - gfx::Scene::Instance().ActivateShader("basic_shadow"); + gfx::Scene::Instance().SetShadingMode("hf"); DoRefresh(); return; } else if(event->key()==Qt::Key_5) { - gfx::Scene::Instance().ActivateShader("fraglight_shadow"); + gfx::Scene::Instance().SetShadingMode("toon1"); DoRefresh(); return; } else if(event->key()==Qt::Key_6) { - gfx::Scene::Instance().ActivateShader("hemilight"); + gfx::Scene::Instance().SetShadingMode("toon2"); DoRefresh(); return; - } else if(event->key()==Qt::Key_7) { - gfx::Scene::Instance().ActivateShader("toon"); - DoRefresh(); - return; - } else if(event->key()==Qt::Key_8) { - gfx::Scene::Instance().ActivateShader("toon2"); + } else if(event->key()==Qt::Key_P) { + gfx::Scene::Instance().SetShadow(!gfx::Scene::Instance().GetShadow()); DoRefresh(); return; }