diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc index 41f0e3db45aed86b7403d314c4dada87c95d20be..1eb5a8fe2c97d56690552cc35be5d7b7c9dd99f3 100644 --- a/modules/gfx/pymod/export_scene.cc +++ b/modules/gfx/pymod/export_scene.cc @@ -130,6 +130,8 @@ void export_Scene() .def("StartOffscreenMode",&Scene::StartOffscreenMode) .def("StopOffscreenMode",&Scene::StopOffscreenMode) .def("SetShadingMode",&Scene::SetShadingMode) + .def("SetBeacon",&Scene::SetBeacon) + .def("SetBeaconOff",&Scene::SetBeaconOff) .def("__getitem__",scene_getitem) .add_property("bg", &Scene::GetBackground, diff --git a/modules/gfx/src/impl/scene_fx.cc b/modules/gfx/src/impl/scene_fx.cc index 474efaba3102e48f3a349c2b160a88d930aa3026..d53059db387021a6a2058208e20ee23c80e97428 100644 --- a/modules/gfx/src/impl/scene_fx.cc +++ b/modules/gfx/src/impl/scene_fx.cc @@ -31,6 +31,8 @@ SceneFX::SceneFX(): amb_occl_factor(1.0), amb_occl_mode(1), amb_occl_quality(1), + use_beacon(false), + beacon(), scene_tex_id_(), depth_tex_id_(), shadow_tex_id_(), @@ -211,7 +213,7 @@ void SceneFX::Postprocess() glBindFramebuffer(GL_FRAMEBUFFER, 0); } - if(!shadow_flag && !amb_occl_flag && !depth_dark_flag) { + if(!shadow_flag && !amb_occl_flag && !depth_dark_flag && !use_beacon) { // no postprocessing is needed return; } @@ -316,6 +318,63 @@ void SceneFX::Postprocess() glActiveTexture(GL_TEXTURE0); } + if(use_beacon) { + Shader::Instance().Activate(""); + cpr=Shader::Instance().GetCurrentProgram(); + glPushAttrib(GL_ALL_ATTRIB_BITS); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + Scene::Instance().ResetProjection(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + geom::Vec3 w0=Scene::Instance().Project(beacon.p0); + geom::Vec3 w1=Scene::Instance().Project(beacon.p1)-w0; + geom::Vec2 q0(w0[0]-5.0,w0[1]-5.0); + geom::Vec2 q1(w0[0]-5.0,w0[1]+5.0); + geom::Vec2 q2(w0[0]+5.0,w0[1]+5.0); + geom::Vec2 q3(w0[0]+5.0,w0[1]-5.0); + std::cerr << beacon.p0 << " " << w0 << std::endl; + float iw=1.0/static_cast<float>(vp.width); + float ih=1.0/static_cast<float>(vp.height); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D,depth_tex_id_); + glActiveTexture(GL_TEXTURE0); + glUniform1i(glGetUniformLocation(cpr,"depth_map"),1); + glUniform3f(glGetUniformLocation(cpr,"wpos"),w0[0],w0[1],w0[2]); + glUniform3f(glGetUniformLocation(cpr,"wdir"),w1[0],w1[1],w1[2]); + glUniform1f(glGetUniformLocation(cpr,"wlen"),geom::Length(w1)); + glUniform1f(glGetUniformLocation(cpr,"rad"),2.0); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_FOG); + glDisable(GL_CULL_FACE); + glDisable(GL_LINE_SMOOTH); + glDisable(GL_POINT_SMOOTH); + glShadeModel(GL_FLAT); + glViewport(0,0,vp.width,vp.height); + glEnable(GL_TEXTURE_2D); + glColor3f(1.0,0.0,1.0); + glBegin(GL_QUADS); + glTexCoord2f(iw*q0[0],ih*q0[1]); + glVertex2f(q0[0],q0[1]); + glTexCoord2f(iw*q1[0],ih*q1[1]); + glVertex2f(q1[0],q1[1]); + glTexCoord2f(iw*q2[0],ih*q2[1]); + glVertex2f(q2[0],q2[1]); + glTexCoord2f(iw*q3[0],ih*q3[1]); + glVertex2f(q3[0],q3[1]); + glEnd(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glPopAttrib(); + } + glDisable(GL_TEXTURE_1D); glDisable(GL_TEXTURE_2D); Shader::Instance().PopProgram(); diff --git a/modules/gfx/src/impl/scene_fx.hh b/modules/gfx/src/impl/scene_fx.hh index fb19525a835740cbd496d6cde85f369360cf4aa4..b2a56f2061b2c1c74f636a9c2dbf1857cd278884 100644 --- a/modules/gfx/src/impl/scene_fx.hh +++ b/modules/gfx/src/impl/scene_fx.hh @@ -34,6 +34,10 @@ class Scene; namespace impl { +struct Beacon { + geom::Vec3 p0,p1; +}; + class SceneFX { friend class ::ost::gfx::Scene; public: @@ -59,6 +63,8 @@ public: float amb_occl_factor; uint amb_occl_mode; uint amb_occl_quality; + bool use_beacon; + Beacon beacon; private: SceneFX(); @@ -89,6 +95,8 @@ private: GLuint depth_rb_; bool use_fb_; + + bool use_beacon_; }; }}} // ns diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc index e784007fc423a64fed2849b79c320840d975f715..4672d899fb24267f2b2e7d6c9c37e4360d6a2562 100644 --- a/modules/gfx/src/scene.cc +++ b/modules/gfx/src/scene.cc @@ -280,6 +280,27 @@ void Scene::SetShadingMode(const std::string& smode) #endif } +void Scene::SetBeacon(int wx, int wy) +{ +#if OST_SHADER_SUPPORT_ENABLED + stereo_projection(0); + geom::Vec3 p0=UnProject(geom::Vec3(static_cast<Real>(wx),static_cast<Real>(wy),0.0)); + std::cerr << p0 << Project(p0) << std::endl; + geom::Vec3 p1=UnProject(geom::Vec3(static_cast<Real>(wx),static_cast<Real>(wy),1.0)); + stereo_projection(stereo_eye_); + impl::SceneFX::Instance().use_beacon=true; + impl::SceneFX::Instance().beacon.p0=p0; + impl::SceneFX::Instance().beacon.p1=p1; +#endif +} + +void Scene::SetBeaconOff() +{ +#if OST_SHADER_SUPPORT_ENABLED + impl::SceneFX::Instance().use_beacon=false; +#endif +} + namespace { void set_light_dir(Vec3 ld) @@ -412,7 +433,6 @@ void Scene::InitGL() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE); - } void Scene::RequestRedraw() @@ -1819,7 +1839,6 @@ void Scene::stereo_projection(unsigned int view) GLdouble bot = -top; GLdouble right = top*aspect_ratio_; GLdouble left = -right; - GLdouble shift=0.0; glFrustum(left,right,bot,top,zn,zf); diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh index 1027d2a0f4d9128f62b327725bbdc9f2f549a428..db798acc1f31ed371394c5984daa5f8ad4ecccd7 100644 --- a/modules/gfx/src/scene.hh +++ b/modules/gfx/src/scene.hh @@ -370,6 +370,9 @@ class DLLEXPORT_OST_GFX Scene { geom::Vec3 GetLightDir() const {return light_dir_;} geom::Mat3 GetLightRot() const {return light_rot_;} + void SetBeacon(int wx, int wy); + void SetBeaconOff(); + protected: friend class GfxObj; friend class GfxNode; diff --git a/modules/gfx/src/shader.cc b/modules/gfx/src/shader.cc index 49f86a1a974ad3a13f7b64059e67efa3f6d582b9..f1325e10867b3ea3266baa64636ab226d881c1f5 100644 --- a/modules/gfx/src/shader.cc +++ b/modules/gfx/src/shader.cc @@ -154,7 +154,8 @@ void Shader::Setup() {"convolute1_fs.glsl", GL_FRAGMENT_SHADER}, {"amboccl_fs.glsl", GL_FRAGMENT_SHADER}, {"scenefx_vs.glsl", GL_VERTEX_SHADER}, - {"scenefx_fs.glsl", GL_FRAGMENT_SHADER} + {"scenefx_fs.glsl", GL_FRAGMENT_SHADER}, + {"beacon_fs.glsl", GL_FRAGMENT_SHADER} ////////////////////////////////////////////////////////////////// }; @@ -276,6 +277,13 @@ void Shader::Setup() if(link_shader(shader_program_list,"amboccl",shader_program_id)) { shader_program_map_["amboccl"]=shader_program_id; } + // beacon shader + shader_program_list.clear(); + shader_program_list.push_back(shader_code_map_["scenefx_vs.glsl"]); + shader_program_list.push_back(shader_code_map_["beacon_fs.glsl"]); + if(link_shader(shader_program_list,"beacon",shader_program_id)) { + shader_program_map_["beacon"]=shader_program_id; + } // scenefx shader shader_program_list.clear(); shader_program_list.push_back(shader_code_map_["scenefx_vs.glsl"]); diff --git a/modules/gfx/src/shader/beacon_fs.glsl b/modules/gfx/src/shader/beacon_fs.glsl new file mode 100644 index 0000000000000000000000000000000000000000..7e1290e60888a0b779f8a141159b958c02616e21 --- /dev/null +++ b/modules/gfx/src/shader/beacon_fs.glsl @@ -0,0 +1,21 @@ +uniform vec3 wpos; +uniform vec3 wdir; +uniform float wlen; +uniform float rad; +uniform sampler2D depth_map; + +void main() +{ + float depth = texture2D(depth_map,gl_TexCoord[0].xy).r; + if(depth>=1.0) { + //discard; + } + float d = length(cross(wdir,vec3(gl_FragCoord.xy,depth)-wpos))/wlen; + if(d<rad) { + gl_FragColor.rgb=vec3(0,1,0); + gl_FragColor.a=1.0; + } else { + gl_FragColor.rgb=vec3(1,0,0); + gl_FragColor.a=1.0; + } +}