diff --git a/modules/gfx/src/impl/scene_fx.cc b/modules/gfx/src/impl/scene_fx.cc index d53059db387021a6a2058208e20ee23c80e97428..d9a258eeb83c8845412159a8506d83d84ba0a8d0 100644 --- a/modules/gfx/src/impl/scene_fx.cc +++ b/modules/gfx/src/impl/scene_fx.cc @@ -308,6 +308,10 @@ void SceneFX::Postprocess() glUniform1i(glGetUniformLocation(cpr,"dark_flag"),0); } + if(use_beacon) { + prep_beacon(); + } + draw_screen_quad(vp.width,vp.height); if(shadow_flag) { @@ -319,60 +323,7 @@ void SceneFX::Postprocess() } 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(); + draw_beacon(); } glDisable(GL_TEXTURE_1D); @@ -615,4 +566,110 @@ void SceneFX::draw_screen_quad(unsigned int w, unsigned int h) glPopAttrib(); } +void SceneFX::prep_beacon() +{ + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + Scene::Instance().stereo_projection(0); + GLdouble glpmat[16]; + glGetDoublev(GL_PROJECTION_MATRIX, glpmat); + geom::Mat4 pmat(geom::Transpose(geom::Mat4(glpmat))); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + geom::Mat4 mmat=Scene::Instance().GetTransform().GetTransposedMatrix(); + GLdouble glmmat[16]; + for(int i=0;i<16;++i) glmmat[i]=static_cast<GLdouble>(mmat.Data()[i]); + GLint glvp[4]; + glGetIntegerv(GL_VIEWPORT,glvp); + + double res[3]; + gluUnProject(beacon.wx,beacon.wy,0.0, + glmmat,glpmat,glvp, + &res[0],&res[1],&res[2]); + beacon.p0=geom::Vec3(res[0],res[1],res[2]); + gluUnProject(beacon.wx,beacon.wy,1.0, + glmmat,glpmat,glvp, + &res[0],&res[1],&res[2]); + beacon.p1=geom::Vec3(res[0],res[1],res[2]); + + glGetv(GL_PROJECTION_MATRIX, glpmat); + geom::Mat4 pmat2(geom::Transpose(geom::Mat4(glpmat))); + beacon.mat = geom::Invert(Scene::Instance().GetTransform().GetMatrix())*geom::Invert(pmat2); +} + +void SceneFX::draw_beacon() +{ + Viewport vp=Scene::Instance().GetViewport(); + float iw=1.0/static_cast<float>(vp.width); + float ih=1.0/static_cast<float>(vp.height); + Shader::Instance().PushProgram(); + Shader::Instance().Activate("beacon"); + uint cpr=Shader::Instance().GetCurrentProgram(); + + float rad=0.6; + float delta = rad/(std::max<float>(1.0,Scene::Instance().znear_) * Scene::Instance().aspect_ratio_ * std::tan(Scene::Instance().fov_*M_PI/360.0))/iw; + geom::Vec2 q0(beacon.wx-delta,beacon.wy-delta); + geom::Vec2 q1(beacon.wx-delta,beacon.wy+delta); + geom::Vec2 q2(beacon.wx+delta,beacon.wy+delta); + geom::Vec2 q3(beacon.wx+delta,beacon.wy-delta); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D,depth_tex_id_); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + geom::Mat4 ttmp=geom::Transpose(beacon.mat); + glLoadMatrix(ttmp.Data()); + glActiveTexture(GL_TEXTURE0); + glUniform1i(glGetUniformLocation(cpr,"depth_map"),1); + glUniform3f(glGetUniformLocation(cpr,"pos"),beacon.p0[0],beacon.p0[1],beacon.p0[2]); + geom::Vec3 dir=beacon.p1-beacon.p0; + glUniform3f(glGetUniformLocation(cpr,"dir"),dir[0],dir[1],dir[2]); + glUniform1f(glGetUniformLocation(cpr,"len"),geom::Length(dir)); + glUniform1f(glGetUniformLocation(cpr,"rad"),rad); + + glPushAttrib(GL_ALL_ATTRIB_BITS); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0,vp.width,0,vp.height,-1,1); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + 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(); + glActiveTexture(GL_TEXTURE1); + glMatrixMode(GL_TEXTURE); + glPopMatrix(); + glActiveTexture(GL_TEXTURE0); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glPopAttrib(); + Shader::Instance().PopProgram(); +} + + }}} // ns diff --git a/modules/gfx/src/impl/scene_fx.hh b/modules/gfx/src/impl/scene_fx.hh index b2a56f2061b2c1c74f636a9c2dbf1857cd278884..e4def5e09b571a936fd28cda71c3b9ef34493fe9 100644 --- a/modules/gfx/src/impl/scene_fx.hh +++ b/modules/gfx/src/impl/scene_fx.hh @@ -35,7 +35,9 @@ class Scene; namespace impl { struct Beacon { + float wx, wy; geom::Vec3 p0,p1; + geom::Mat4 mat; }; class SceneFX { @@ -75,6 +77,8 @@ private: void prep_depth_darkening(); void prep_amb_occlusion(); void draw_screen_quad(uint w, uint h); + void prep_beacon(); + void draw_beacon(); GLuint scene_tex_id_; GLuint depth_tex_id_; @@ -95,8 +99,6 @@ 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 4672d899fb24267f2b2e7d6c9c37e4360d6a2562..2080f5d96d25be9636a0bc4ad14caff0cce45b96 100644 --- a/modules/gfx/src/scene.cc +++ b/modules/gfx/src/scene.cc @@ -283,14 +283,9 @@ void Scene::SetShadingMode(const std::string& smode) 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; + impl::SceneFX::Instance().beacon.wx=static_cast<float>(wx); + impl::SceneFX::Instance().beacon.wy=static_cast<float>(wy); #endif } diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh index db798acc1f31ed371394c5984daa5f8ad4ecccd7..ec076cc4e73be53fb2515dbb808aa49679ffca3d 100644 --- a/modules/gfx/src/scene.hh +++ b/modules/gfx/src/scene.hh @@ -57,6 +57,8 @@ struct Viewport { int height; }; +namespace impl {class SceneFX;} + /// \brief main class for organization and root for the graphical display /// /// The scene manages graphical objects for rendering. Typical graphical objects @@ -74,6 +76,7 @@ struct Viewport { /// disabling the AutoAutoslab(). The near and far clipping plane can then be /// adjusted manually. class DLLEXPORT_OST_GFX Scene { + friend class impl::SceneFX; private: // TODO: this struct may be the seed for a proper diff --git a/modules/gfx/src/shader/beacon_fs.glsl b/modules/gfx/src/shader/beacon_fs.glsl index 7e1290e60888a0b779f8a141159b958c02616e21..c1423640ee10ab4ff9abc34d95c000eb52a45ff6 100644 --- a/modules/gfx/src/shader/beacon_fs.glsl +++ b/modules/gfx/src/shader/beacon_fs.glsl @@ -1,6 +1,6 @@ -uniform vec3 wpos; -uniform vec3 wdir; -uniform float wlen; +uniform vec3 pos; +uniform vec3 dir; +uniform float len; uniform float rad; uniform sampler2D depth_map; @@ -8,14 +8,16 @@ void main() { float depth = texture2D(depth_map,gl_TexCoord[0].xy).r; if(depth>=1.0) { - //discard; + 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; + vec4 pcoord = vec4(gl_TexCoord[0].xy*2.0-1.0,depth*2.0-1.0,1.0); + vec4 coord = gl_TextureMatrix[1]*pcoord; + coord/=coord.w; + + float d = length(cross(dir,coord.xyz-pos))/len; + if(d>rad) { + discard; } + gl_FragColor.rgb=vec3(0,1.0,0); + gl_FragColor.a=min(0.9,mix(3.0,0.0,d/rad)); } diff --git a/modules/gui/src/gl_canvas.cc b/modules/gui/src/gl_canvas.cc index 73ebee84600d6088efee685a05a674428c68314a..71923254716df1069a4d2e3d281b30e1bb930e60 100644 --- a/modules/gui/src/gl_canvas.cc +++ b/modules/gui/src/gl_canvas.cc @@ -47,14 +47,19 @@ using gfx::Scene; GLCanvas::GLCanvas(GLWin* gl_win, QWidget* parent, const QGLFormat& f): QGLWidget(f,parent), - glwin_(gl_win) + glwin_(gl_win), + mouse_key_mask_(), + refresh_(true), + master_timer_(), + bench_flag_(false), + last_pos_(), + scene_menu_(NULL), + show_beacon_(false) { if(!isValid()) return; - refresh_=true; master_timer_.start(10,this); setFocusPolicy(Qt::StrongFocus); - bench_flag_=false; - setMouseTracking(false); + setMouseTracking(true); scene_menu_=new SceneMenu(); this->setContextMenuPolicy(Qt::CustomContextMenu); connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, @@ -225,6 +230,10 @@ void GLCanvas::HandleMouseMoveEvent(QMouseEvent* event) int indx=0; gfx::TransformTarget trg=gfx::TRANSFORM_VIEW; + if(show_beacon_) { + Scene::Instance().SetBeacon(event->x(),size().height()-event->y()); + } + QPoint delta=QPoint(event->x(), event->y())-last_pos_; if (event->buttons() & Qt::LeftButton) { if (event->buttons() & Qt::MidButton) { @@ -320,6 +329,12 @@ void GLCanvas::CopySelectionToClipboard() void GLCanvas::keyPressEvent(QKeyEvent* event) { + if(event->key()==Qt::Key_Space) { + show_beacon_=true; + Scene::Instance().SetBeacon(last_pos_.x(),size().height()-last_pos_.y()); + DoRefresh(); + setCursor(Qt::BlankCursor); + } if((event->modifiers() & Qt::ControlModifier)) { // Ctrl pressed if(event->key()==Qt::Key_A) { @@ -373,6 +388,13 @@ void GLCanvas::keyPressEvent(QKeyEvent* event) void GLCanvas::keyReleaseEvent(QKeyEvent* event) { + if(event->key()==Qt::Key_Space) { + show_beacon_=false; + Scene::Instance().SetBeaconOff(); + DoRefresh(); + setCursor(Qt::ArrowCursor); + return; + } if(event->key()==Qt::Key_Alt){ emit ReleaseFocus(); return; diff --git a/modules/gui/src/gl_canvas.hh b/modules/gui/src/gl_canvas.hh index e55ff8fd066fb4ce621b9ec508a4dad9f0ce37aa..e20c3c5ce97bdca8040bbcc9d9fe9496040e0bf3 100644 --- a/modules/gui/src/gl_canvas.hh +++ b/modules/gui/src/gl_canvas.hh @@ -102,6 +102,7 @@ private: bool bench_flag_; QPoint last_pos_; SceneMenu* scene_menu_; + bool show_beacon_; }; }} // ns