diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc index 97a555d6f6f6505d4a01d36e4961fbcdb3d6095c..e5e93d5b50c4b90269dfcf507a346e84c1ad5ed3 100644 --- a/modules/gfx/pymod/export_scene.cc +++ b/modules/gfx/pymod/export_scene.cc @@ -96,11 +96,13 @@ void export_Scene() .def("SetFogOffsets",&Scene::SetFogOffsets) .def("Stereo",&Scene::Stereo) .def("SetStereoInverted",&Scene::SetStereoInverted) - .def("Apply", apply) - .def("SetStereoEye",&Scene::SetStereoEye) + .def("SetStereoView",&Scene::SetStereoView) + .def("SetStereoEyeDist",&Scene::SetStereoEyeDist) + .def("SetStereoEyeOffset",&Scene::SetStereoEyeOffset) .def("SetLightDir",&Scene::SetLightDir) .def("SetLightProp",set_light_prop1) .def("SetLightProp",set_light_prop2) + .def("Apply", apply) .def("Export",export1, arg("transparent")=true) .def("Export",export2, arg("transparent")=true) .def("ExportPov",&Scene::ExportPov, diff --git a/modules/gfx/src/gl_helper.hh b/modules/gfx/src/gl_helper.hh index 1c955212cd7e228ad9ef54939b82e1ab9a6d6b8d..db9c07d9f3dd82d8b806de2bed149ac29a925594 100644 --- a/modules/gfx/src/gl_helper.hh +++ b/modules/gfx/src/gl_helper.hh @@ -38,18 +38,24 @@ Author: Juergen Haas #include "glext_include.hh" #include "gl_include.hh" +#include <ost/log.hh> + +inline void check_gl_error() +{ + GLenum error_code; + if((error_code=glGetError())!=GL_NO_ERROR) { + LOGN_VERBOSE("GL error: " << gluErrorString(error_code)); + } +} + inline void glVertex3v(double* v){ glVertex3dv(v); } - - inline void glVertex3v(const double* v){ glVertex3dv(v); } - - inline void glVertex3v(float* v){ glVertex3fv(v); } diff --git a/modules/gfx/src/impl/scene_fx.cc b/modules/gfx/src/impl/scene_fx.cc index a4da9955ab033a5522c127208e8490e4aac5069a..6c4dfb3083b1c022e855fd6cc62aebfc1cbd8311 100644 --- a/modules/gfx/src/impl/scene_fx.cc +++ b/modules/gfx/src/impl/scene_fx.cc @@ -72,42 +72,49 @@ void SceneFX::Setup() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 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); glBindTexture(GL_TEXTURE_2D, depth_tex_id_); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 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); glBindTexture(GL_TEXTURE_2D, shadow_tex_id_); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 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); glBindTexture(GL_TEXTURE_2D, occl_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); + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE); glBindTexture(GL_TEXTURE_2D, dark_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); + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE); glBindTexture(GL_TEXTURE_2D, norm_tex_id_); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 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); glActiveTexture(GL_TEXTURE0); 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); + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE); std::vector<GLfloat> tmp; for(int u=-20;u<=20;++u) { @@ -201,7 +208,7 @@ void SceneFX::Postprocess() if(!shadow_flag && !amb_occl_flag && !depth_dark_flag) { // no postprocessing is needed - return; + //return; } Viewport vp=Scene::Instance().GetViewport(); @@ -245,14 +252,9 @@ void SceneFX::Postprocess() glBindTexture(GL_TEXTURE_2D,depth_tex_id_); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,scene_tex_id_); + glUniform1i(glGetUniformLocation(cpr,"scene_map"),0); glUniform1i(glGetUniformLocation(cpr,"depth_map"),1); - glUniform2f(glGetUniformLocation(cpr,"scalef"), - 1.0f/static_cast<float>(vp.width), - 1.0f/static_cast<float>(vp.height)); - glUniform2f(glGetUniformLocation(cpr,"zmorph"), - Scene::Instance().GetFar()-Scene::Instance().GetNear(), - Scene::Instance().GetNear()); glUniform2f(glGetUniformLocation(cpr,"i_vp"),1.0/static_cast<float>(vp.width),1.0/static_cast<float>(vp.height)); double pm[16]; glGetDoublev(GL_PROJECTION_MATRIX,pm); @@ -261,12 +263,13 @@ void SceneFX::Postprocess() if(shadow_flag) { glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D,shadow_tex_id_); + glActiveTexture(GL_TEXTURE0); glUniform1i(glGetUniformLocation(cpr,"shadow_flag"),1); glUniform1i(glGetUniformLocation(cpr,"shadow_map"),2); glUniform1f(glGetUniformLocation(cpr,"shadow_depth_bias"),0.008); glUniform1f(glGetUniformLocation(cpr,"shadow_epsilon"),0.002); glUniform1f(glGetUniformLocation(cpr,"shadow_multiplier"),0.4); - glActiveTexture(GL_TEXTURE0); + glMatrixMode(GL_TEXTURE); glPushMatrix(); // make explicit object instead of temporary to avoid potential crash with Data() @@ -279,15 +282,18 @@ void SceneFX::Postprocess() if(amb_occl_flag) { glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D,occl_tex_id_); + glActiveTexture(GL_TEXTURE0); glUniform1i(glGetUniformLocation(cpr,"occl_flag"),1); glUniform1i(glGetUniformLocation(cpr,"occl_map"),3); glUniform1f(glGetUniformLocation(cpr,"occl_mult"),amb_occl_factor); } else { glUniform1i(glGetUniformLocation(cpr,"occl_flag"),0); } + if(depth_dark_flag) { glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_2D,dark_tex_id_); + glActiveTexture(GL_TEXTURE0); glUniform1i(glGetUniformLocation(cpr,"dark_flag"),1); glUniform1i(glGetUniformLocation(cpr,"dark_map"),4); glUniform1f(glGetUniformLocation(cpr,"dark_mult"),depth_dark_factor); @@ -308,6 +314,18 @@ void SceneFX::Postprocess() Shader::Instance().PopProgram(); } +void SceneFX::DrawTex(unsigned int w, unsigned int h, GLuint texid) +{ + Shader::Instance().PushProgram(); + Shader::Instance().Activate(""); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texid); + + draw_screen_quad(w,h); + + Shader::Instance().PopProgram(); +} + void SceneFX::prep_shadow_map() { GLint smap_size=256 << shadow_quality; @@ -353,7 +371,7 @@ void SceneFX::prep_shadow_map() Scene::Instance().GetRootNode()->RenderGL(STANDARD_RENDER_PASS); // now get the shadow map - glActiveTexture(GL_TEXTURE2); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, shadow_tex_id_); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0,0, smap_size,smap_size, 0); @@ -371,18 +389,7 @@ void SceneFX::prep_shadow_map() 0.0,0.5,0.0,0.5, 0.0,0.0,0.5,0.5, 0.0,0.0,0.0,1.0); - float glpmat2[16]; - glGetv(GL_PROJECTION_MATRIX, glpmat2); - geom::Mat4 pmat2(Transpose(geom::Mat4(glpmat2))); - float glmmat2[16]; - glGetv(GL_MODELVIEW_MATRIX, glmmat2); - geom::Mat4 mmat2(Transpose(geom::Mat4(glmmat2))); - - geom::Mat4 lmat2; - lmat2.PasteRotation(Scene::Instance().GetLightRot()); - shadow_tex_mat_ = bias*pmat*ltrans.GetMatrix(); - //shadow_tex_mat_ = bias*pmat*lmat2*geom::Invert(pmat2); } void SceneFX::prep_amb_occlusion() @@ -402,6 +409,7 @@ void SceneFX::prep_amb_occlusion() glBindTexture(GL_TEXTURE_2D,norm_tex_id_); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_1D,kernel_tex_id_); + glActiveTexture(GL_TEXTURE0); glUniform1i(glGetUniformLocation(cpr,"depth_map"),0); glUniform1i(glGetUniformLocation(cpr,"norm_map"),1); glUniform1i(glGetUniformLocation(cpr,"kernel"),2); @@ -411,13 +419,13 @@ void SceneFX::prep_amb_occlusion() glGetDoublev(GL_PROJECTION_MATRIX,pm); glUniform4f(glGetUniformLocation(cpr,"abcd"),pm[0],pm[5],pm[10],pm[14]); + // set up viewport filling quad to run the fragment shader draw_screen_quad(width,height); - glActiveTexture(GL_TEXTURE3); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, occl_tex_id_); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0,0, width, height, 0); - Shader::Instance().PopProgram(); } @@ -433,6 +441,8 @@ void SceneFX::prep_depth_darkening() glBindTexture(GL_TEXTURE_2D,depth_tex_id_); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_1D,kernel2_tex_id_); + glActiveTexture(GL_TEXTURE0); + glUniform1i(glGetUniformLocation(cpr,"data"),1); glUniform1i(glGetUniformLocation(cpr,"kernel"),2); glUniform1f(glGetUniformLocation(cpr,"step"),1.0/static_cast<float>(kernel2_size_)); @@ -441,7 +451,7 @@ void SceneFX::prep_depth_darkening() // set up viewport filling quad to run the fragment shader draw_screen_quad(vp.width/2,vp.height/2); - glActiveTexture(GL_TEXTURE4); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, dark_tex_id_); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0,0,vp.width/2, vp.height/2, 0); @@ -461,6 +471,7 @@ void SceneFX::draw_screen_quad(unsigned int w, unsigned int h) glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); glDisable(GL_POINT_SMOOTH); + glShadeModel(GL_FLAT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); @@ -492,18 +503,4 @@ void SceneFX::draw_screen_quad(unsigned int w, unsigned int h) glPopAttrib(); } -// this debug code draws the given texture across the complete screen -void SceneFX::draw_debug_tex(unsigned int w, unsigned int h, GLuint texid) -{ - Shader::Instance().PushProgram(); - Shader::Instance().Activate(""); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texid); - - draw_screen_quad(w,h); - - Shader::Instance().PopProgram(); -} - - }}} // ns diff --git a/modules/gfx/src/impl/scene_fx.hh b/modules/gfx/src/impl/scene_fx.hh index c71ba6bd7154b828c5a8ddf6e5300e9371ca83ab..ebd4ae6e7c97131408af38d3db200974fdc73fe3 100644 --- a/modules/gfx/src/impl/scene_fx.hh +++ b/modules/gfx/src/impl/scene_fx.hh @@ -35,6 +35,7 @@ class Scene; namespace impl { class SceneFX { + friend class ::ost::gfx::Scene; public: ~SceneFX(); static SceneFX& Instance(); @@ -47,6 +48,8 @@ public: // assumes scene has been drawn in the active framebuffer void Postprocess(); + void DrawTex(unsigned int w, unsigned int h, GLuint texid); + bool shadow_flag; int shadow_quality; bool depth_dark_flag; @@ -63,7 +66,6 @@ private: void prep_depth_darkening(); void prep_amb_occlusion(); void draw_screen_quad(uint w, uint h); - void draw_debug_tex(unsigned int w, unsigned int h, GLuint texid); GLuint scene_tex_id_; GLuint depth_tex_id_; diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc index 4b70553e266c74cbf07b2db49f9ed330c5b3b4c6..38aaaff76d781d76cca6eb6d5f7780415109fb27 100644 --- a/modules/gfx/src/scene.cc +++ b/modules/gfx/src/scene.cc @@ -95,9 +95,9 @@ Scene::Scene(): observers_(), transform_(), fov_(30.0), - znear_(-200.0),zfar_(200.0), - fnear_(5.0), ffar_(0.0), - vp_width_(100),vp_height_(100), + znear_(1.0),zfar_(1000.0), + fnear_(1.0), ffar_(1000.0), + vp_width_(1000),vp_height_(1000), scene_view_stack_(), aspect_ratio_(1.0), background_(Color(0.0,0.0,0.0,0.0)), @@ -125,8 +125,10 @@ Scene::Scene(): stereo_(0), stereo_inverted_(false), stereo_eye_(0), - stereo_eye_dist_(150.0), - stereo_eye_offset_(10.0) + stereo_eye_dist_(5.0), + stereo_eye_offset_(10.0), + scene_left_tex_(), + scene_right_tex_() { transform_.SetTrans(Vec3(0,0,-100)); } @@ -257,6 +259,8 @@ void Scene::InitGL() { LOGN_DEBUG("scene: initializing GL state"); + LOGN_VERBOSE(glGetString(GL_RENDERER) << ", openGL version " << glGetString(GL_VERSION)); + #if OST_SHADER_SUPPORT_ENABLED LOGN_DEBUG("scene: shader pre-gl"); Shader::Instance().PreGLInit(); @@ -352,6 +356,27 @@ void Scene::InitGL() #endif prep_glyphs(); + + glGenTextures(1,&scene_left_tex_); + glGenTextures(1,&scene_right_tex_); + + glEnable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + + glBindTexture(GL_TEXTURE_2D, scene_left_tex_); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + 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); + + glBindTexture(GL_TEXTURE_2D, scene_right_tex_); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + 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() @@ -533,36 +558,15 @@ void Scene::RenderGL() { if(auto_autoslab_) Autoslab(false, false); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); prep_blur(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - set_light_dir(light_dir_); - - glMultMatrix(transform_.GetTransposedMatrix().Data()); - - // TODO: handle stereo -#if OST_SHADER_SUPPORT_ENABLED - impl::SceneFX::Instance().Preprocess(); -#endif - render_standard_scene(); -#if OST_SHADER_SUPPORT_ENABLED - impl::SceneFX::Instance().Postprocess(); -#endif - render_glow(); - -#if 0 - if(stereo_==2 || stereo_==3) { + if(stereo_==1) { + render_quad_buffered_stereo(); + } else if (stereo_==2) { render_interlaced_stereo(); - } else if (stereo_==1) { - this->render_quad_buffered_stereo(); } else { - this->render_scene_with_glow(); + render_scene(); } -#endif - } void Scene::Register(GLWinBase* win) @@ -1195,13 +1199,13 @@ void Scene::Stereo(unsigned int m) { if(m==1) { stereo_=m; - if(win_) win_->SetStereo(true); + //if(win_) win_->SetStereo(true); } else if(m==2 || m==3) { stereo_=m; - if(win_) win_->SetStereo(false); + //if(win_) win_->SetStereo(false); } else { stereo_=0; - if(win_) win_->SetStereo(false); + //if(win_) win_->SetStereo(false); } RequestRedraw(); } @@ -1209,15 +1213,33 @@ void Scene::Stereo(unsigned int m) void Scene::SetStereoInverted(bool f) { stereo_inverted_=f; + RequestRedraw(); } -void Scene::SetStereoEye(unsigned int m) +void Scene::SetStereoView(unsigned int m) { stereo_eye_= (m>2) ? 0: m; ResetProjection(); RequestRedraw(); } +void Scene::SetStereoEyeDist(float d) +{ + stereo_eye_dist_=d; + if(stereo_>0) { + RequestRedraw(); + } +} + +void Scene::SetStereoEyeOffset(float o) +{ + stereo_eye_offset_=o; + if(stereo_>0) { + RequestRedraw(); + } +} + + void Scene::SetLightDir(const Vec3& dir) { @@ -1699,11 +1721,18 @@ void Scene::prep_blur() glFlush(); } -void Scene::render_standard_scene() +void Scene::render_scene() { - glDepthFunc(GL_LEQUAL); - glDepthMask(1); - glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glMultMatrix(transform_.GetTransposedMatrix().Data()); + +#if OST_SHADER_SUPPORT_ENABLED + impl::SceneFX::Instance().Preprocess(); +#endif root_node_->RenderGL(STANDARD_RENDER_PASS); glEnable(GL_BLEND); @@ -1711,6 +1740,12 @@ void Scene::render_standard_scene() root_node_->RenderGL(TRANSPARENT_RENDER_PASS); glDisable(GL_BLEND); root_node_->RenderGL(OVERLAY_RENDER_PASS); + +#if OST_SHADER_SUPPORT_ENABLED + impl::SceneFX::Instance().Postprocess(); +#endif + + render_glow(); } void Scene::render_glow() @@ -1743,12 +1778,32 @@ void Scene::stereo_projection(unsigned int view) glMatrixMode(GL_PROJECTION); glLoadIdentity(); - float zn=std::max(float(1.0),znear_); - float zf=std::max(float(1.1),zfar_); + GLdouble zn=std::max<float>(1.0,znear_); + GLdouble zf=std::max<float>(1.1,zfar_); +#if 1 + GLdouble top = zn * std::tan(fov_*M_PI/360.0); + GLdouble bot = -top; + GLdouble right = top*aspect_ratio_; + GLdouble left = -right; + GLdouble shift=0.0; + if(view==1 || view==2) { + shift = 0.5*stereo_eye_dist_*zn/zf * (view==1 ? 1.0 : -1.0); + left+=shift; + right+=shift*0.5; + } + glFrustum(left,right,bot,top,zn,zf); + GLdouble trans[16]; + for(int i=0;i<16;++i) trans[i]=0.0; + trans[0]=1.0; + trans[5]=1.0; + trans[10]=1.0; + trans[15]=1.0; + trans[12]=shift; + glMultMatrixd(trans); +#else gluPerspective(fov_,aspect_ratio_,zn,zf); - - if(view>0) { + if(view==1 || view==2) { float iod = (view==1) ? -stereo_eye_dist_ : stereo_eye_dist_; //float fr=(-stereo_eye_offset_-zn)/(zf-zn); float angle=180.0f/M_PI*std::atan(stereo_eye_offset_/(2.0*iod)); @@ -1756,21 +1811,36 @@ void Scene::stereo_projection(unsigned int view) glRotated(-angle,0.0,1.0,0.0); glTranslated(0.0,0.0,-transform_.GetTrans()[2]); } +#endif } void Scene::render_interlaced_stereo() { -#if 0 - // set up stencil buffer - glPushAttrib(GL_STENCIL_BUFFER_BIT| GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0,vp_width_,0,vp_height_,-1,1); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glDrawBuffer(GL_NONE); + glGetError(); + stereo_projection(1); + render_scene(); + + glEnable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, scene_left_tex_); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, vp_width_, vp_height_, 0); + check_gl_error(); + + stereo_projection(2); + render_scene(); + glEnable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, scene_right_tex_); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, vp_width_, vp_height_, 0); + check_gl_error(); + stereo_projection(0); + +#if OST_SHADER_SUPPORT_ENABLED + Shader::Instance().PushProgram(); + Shader::Instance().Activate(""); +#endif + + glPushAttrib(GL_ALL_ATTRIB_BITS); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glDisable(GL_COLOR_MATERIAL); @@ -1779,6 +1849,17 @@ void Scene::render_interlaced_stereo() glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); glDisable(GL_POINT_SMOOTH); + glDisable(GL_MULTISAMPLE); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0,vp_width_,0,vp_height_,-1,1); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // draw interlace lines in stencil buffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLineWidth(1.0); glEnable(GL_STENCIL_TEST); glStencilMask(0x1); @@ -1793,52 +1874,54 @@ void Scene::render_interlaced_stereo() glVertex2i(vp_width_-1,i); } glEnd(); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopAttrib(); - glEnable(GL_STENCIL_TEST); glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); + // left eye glStencilFunc(GL_EQUAL,0x1,0x1); - stereo_projection(stereo_==2 ? 1 : 2); - root_node_->RenderGL(STANDARD_RENDER_PASS); - root_node_->RenderGL(GLOW_RENDER_PASS); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, stereo_inverted_ ? scene_right_tex_ : scene_left_tex_); + // draw + glColor3f(1.0,0.0,1.0); + glBegin(GL_QUADS); + glTexCoord2f(0.0,0.0); glVertex2i(0,0); + glTexCoord2f(0.0,1.0); glVertex2i(0,vp_height_); + glTexCoord2f(1.0,1.0); glVertex2i(vp_width_,vp_height_); + glTexCoord2f(1.0,0.0); glVertex2i(vp_width_,0); + glEnd(); + + // right eye glStencilFunc(GL_EQUAL,0x0,0x1); - stereo_projection(stereo_==2 ? 2 : 1); - root_node_->RenderGL(STANDARD_RENDER_PASS); - root_node_->RenderGL(GLOW_RENDER_PASS); - glDisable(GL_STENCIL_TEST); + glBindTexture(GL_TEXTURE_2D, stereo_inverted_ ? scene_left_tex_ : scene_right_tex_); + // draw + glColor3f(1.0,0.0,1.0); + glBegin(GL_QUADS); + glTexCoord2f(0.0,0.0); glVertex2i(0,0); + glTexCoord2f(0.0,1.0); glVertex2i(0,vp_height_); + glTexCoord2f(1.0,1.0); glVertex2i(vp_width_,vp_height_); + glTexCoord2f(1.0,0.0); glVertex2i(vp_width_,0); + glEnd(); + + // restore settings + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); glPopAttrib(); +#if OST_SHADER_SUPPORT_ENABLED + Shader::Instance().PopProgram(); #endif } void Scene::render_quad_buffered_stereo() { -#if 0 - glDrawBuffer(GL_BACK); - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glDrawBuffer(GL_BACK_LEFT); - glClear(GL_DEPTH_BUFFER_BIT); - if (stereo_inverted_) { - stereo_projection(stereo_==1 ? 2 : 1); - } else { - stereo_projection(stereo_==1 ? 1 : 2); - } - this->render_scene_with_glow(); + stereo_projection(stereo_inverted_ ? 1 : 2); + render_scene(); glDrawBuffer(GL_BACK_RIGHT); - glClear(GL_DEPTH_BUFFER_BIT); - if (stereo_inverted_) { - stereo_projection(stereo_==1 ? 1 : 2); - } else { - stereo_projection(stereo_==1 ? 2 : 1); - } - this->render_scene_with_glow(); - glDrawBuffer(GL_BACK); -#endif + stereo_projection(stereo_inverted_ ? 2 : 1); + render_scene(); } }} // ns diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh index 29fd72a5069c78febdb913f1ab83b78d3cd31efc..397d2dbb3192592a9f5428439af72f3bb962d488 100644 --- a/modules/gfx/src/scene.hh +++ b/modules/gfx/src/scene.hh @@ -173,16 +173,18 @@ class DLLEXPORT_OST_GFX Scene { /* 0=off 1=quad-buffered - 2=interlaced variant #1 - 3=interlaced variant #2 + 2=interlaced stereo */ void Stereo(unsigned int); /// \brief invert stereo eyes for stereo mode=0 void SetStereoInverted(bool f); - /// \brief eye mode, 0=center, 1=left, 2=right - void SetStereoEye(unsigned int); + /// \brief stereo view mode, 0=center, 1=left, 2=right + void SetStereoView(unsigned int); + + void SetStereoEyeDist(float); + void SetStereoEyeOffset(float); /// \brief set main light direction void SetLightDir(const geom::Vec3& dir); @@ -429,11 +431,12 @@ private: uint blur_count_; std::vector<boost::shared_array<unsigned char> > blur_buffer_; - GLuint glow_tex_; unsigned int stereo_; bool stereo_inverted_; unsigned int stereo_eye_; float stereo_eye_dist_,stereo_eye_offset_; + unsigned int scene_left_tex_; + unsigned int scene_right_tex_; void set_near(float n); void set_far(float f); @@ -442,10 +445,10 @@ private: void prep_glyphs(); void prep_blur(); void stereo_projection(unsigned int view); + void render_scene(); + void render_glow(); void render_interlaced_stereo(); void render_quad_buffered_stereo(); - void render_standard_scene(); - void render_glow(); bool IsNameAvailable(String name); }; diff --git a/modules/gfx/src/shader/scenefx_fs.glsl b/modules/gfx/src/shader/scenefx_fs.glsl index bed4469eded2d9271a2da51def4dff176d2e8f7c..2c7341de096e8f03c23075cb1046135c59a1a68c 100644 --- a/modules/gfx/src/shader/scenefx_fs.glsl +++ b/modules/gfx/src/shader/scenefx_fs.glsl @@ -1,7 +1,7 @@ uniform sampler2D scene_map; uniform sampler2D depth_map; -uniform vec2 scalef; -uniform vec2 zmorph; +uniform vec2 i_vp; +uniform vec4 abcd; uniform bool shadow_flag; uniform sampler2D shadow_map; uniform float shadow_depth_bias; @@ -13,8 +13,6 @@ uniform float occl_mult; uniform bool dark_flag; uniform sampler2D dark_map; uniform float dark_mult; -uniform vec2 i_vp; -uniform vec4 abcd; vec3 unproject(in vec3 scr) { @@ -40,9 +38,7 @@ void main() float depth = texture2D(depth_map,gl_TexCoord[0].xy).r; vec4 tcoord = gl_ModelViewProjectionMatrixInverse*vec4(gl_FragCoord.xy*i_vp*2.0-1.0,depth,1.0); vec4 coord = gl_TextureMatrix[0]*tcoord; - //vec4 coord = gl_TextureMatrix[0]*vec4(gl_FragCoord.xy*i_vp*2.0-1.0,depth,1.0); coord/=coord.w; - shadow_factor = 0.0; shadow_factor += 0.18*CalcShadowFactor(coord, vec2(-0.7, -0.7)); shadow_factor += 0.18*CalcShadowFactor(coord, vec2(0.7, -0.7));