diff --git a/modules/gfx/src/CMakeLists.txt b/modules/gfx/src/CMakeLists.txt index e21c2cbecedcca362ea28e7887fe949482f05940..1ee9cf86ca56787b6798e3a3a92ec671e2c52de4 100644 --- a/modules/gfx/src/CMakeLists.txt +++ b/modules/gfx/src/CMakeLists.txt @@ -244,6 +244,8 @@ if (USE_SHADER) shader/fast_sphere_vs.glsl shader/fast_sphere_fs.glsl shader/outline_vs.glsl + shader/convolute1_vs.glsl + shader/convolute1_fs.glsl ) copy_if_different("./" "${SHARED_DATA_PATH}/shader" "${SHADER_FILES}" "SHADER_TARGETS" ost_gfx) diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc index e2aadfae3bf37b684e686669656f9631e9f8cb53..c25c34344d7a91ed03f8cc4017b77a4678c4d8f1 100644 --- a/modules/gfx/src/gfx_object.cc +++ b/modules/gfx/src/gfx_object.cc @@ -632,6 +632,7 @@ void GfxObj::render_depth_only() glDisable(GL_NORMALIZE); glEnable(GL_DEPTH_TEST); CustomRenderGL(STANDARD_RENDER_PASS); + CustomRenderGL(TRANSPARENT_RENDER_PASS); glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); glPopAttrib(); } diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc index b81d4b0cf211d37df099ec5cf8fd1a2f401a9ca1..ead1566ffb0621989f3edcf597c2e1ead2cd411b 100644 --- a/modules/gfx/src/scene.cc +++ b/modules/gfx/src/scene.cc @@ -112,7 +112,10 @@ Scene::Scene(): fog_color_(0.0,0.0,0.0,0.0), shadow_flag_(false), shadow_quality_(1), - shadow_texture_id_(), + shadow_tex_id_(), + depth_tex_id_(), + kernel_tex_id_(), + scene_tex_id_(), auto_autoslab_(true), offscreen_flag_(false), main_offscreen_buffer_(0), @@ -285,7 +288,10 @@ void Scene::InitGL() Shader::Instance().Setup(); Shader::Instance().Activate("fraglight"); - glGenTextures(1,&shadow_texture_id_); + glGenTextures(1,&shadow_tex_id_); + glGenTextures(1,&depth_tex_id_); + glGenTextures(1,&kernel_tex_id_); + glGenTextures(1,&scene_tex_id_); #endif prep_glyphs(); @@ -1590,7 +1596,7 @@ void Scene::prep_shadow_map() // now get the shadow map glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, shadow_texture_id_); + glBindTexture(GL_TEXTURE_2D, shadow_tex_id_); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0,0, smap_size,smap_size, 0); @@ -1675,6 +1681,177 @@ void Scene::prep_shadow_map() glEnd(); Shader::Instance().Activate("basic_shadow"); #endif +#endif +} + +void Scene::prep_depth_map() +{ +#if OST_SHADER_SUPPORT_ENABLED + unsigned int vp_width2=vp_width_/2; + unsigned int vp_height2=vp_height_/2; + + // render pass 1 - without shadows + // turn shadowing off for subsequent rendering + glUniform1i(glGetUniformLocation(Shader::Instance().GetCurrentProgram(), + "shadow_flag"),0); + // save overall gl settings + glPushAttrib(GL_ENABLE_BIT); + // maximize rendering for depth-only information + glDisable(GL_LIGHTING); + glDisable(GL_FOG); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_NORMALIZE); + glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); + + // render scene with only depth components + glClear(GL_DEPTH_BUFFER_BIT); + glViewport(0,0,vp_width2,vp_height2); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glMultMatrix(transform_.GetTransposedMatrix().Data()); + root_node_->RenderGL(DEPTH_RENDER_PASS); + + // now get the depth map + glActiveTexture(GL_TEXTURE1); + 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); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, + 0,0, vp_width2, vp_height2, 0); + + // restore settings + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glPopAttrib(); + 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 } diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh index 42e9c98571d8e851aa577cc3292c44249f1569a1..6896d29e7fa6a933485920abeb1865ecf82bcbbd 100644 --- a/modules/gfx/src/scene.hh +++ b/modules/gfx/src/scene.hh @@ -403,7 +403,10 @@ private: Color fog_color_; bool shadow_flag_; int shadow_quality_; - GLuint shadow_texture_id_; + GLuint shadow_tex_id_; + GLuint depth_tex_id_; + GLuint kernel_tex_id_; + GLuint scene_tex_id_; bool auto_autoslab_; bool offscreen_flag_; // a simple indicator whether in offscreen mode or not @@ -431,6 +434,7 @@ private: void set_far(float f); void update_fog(); void prep_shadow_map(); + void prep_depth_map(); 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 9f1cbb8036c3e503915660422221dea005cda24f..cb4af5c5b6cf1b26df661bc6ad7cc65d545d5168 100644 --- a/modules/gfx/src/shader.cc +++ b/modules/gfx/src/shader.cc @@ -129,7 +129,7 @@ void Shader::Setup() GLenum type; } shader_list[] = { ////////////////////////////////////////////////////////////////// - // this is the master list of all shader code in lib/ost/shader + // 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}, @@ -151,7 +151,9 @@ void Shader::Setup() {"iso_fs.glsl", GL_FRAGMENT_SHADER}, {"fast_sphere_vs.glsl", GL_VERTEX_SHADER}, {"fast_sphere_fs.glsl", GL_FRAGMENT_SHADER}, - {"outline_vs.glsl", GL_VERTEX_SHADER} + {"outline_vs.glsl", GL_VERTEX_SHADER}, + {"convolute1_vs.glsl", GL_VERTEX_SHADER}, + {"convolute1_fs.glsl", GL_FRAGMENT_SHADER} ////////////////////////////////////////////////////////////////// }; @@ -259,13 +261,20 @@ void Shader::Setup() if(link_shader(shader_program_list,"fast_sphere",shader_program_id)) { shader_program_map_["fast_sphere"]=shader_program_id; } - // basic shader + // 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"]); if(link_shader(shader_program_list,"outline",shader_program_id)) { shader_program_map_["outline"]=shader_program_id; } + // convolute1 shader + shader_program_list.clear(); + shader_program_list.push_back(shader_code_map_["convolute1_vs.glsl"]); + shader_program_list.push_back(shader_code_map_["convolute1_fs.glsl"]); + if(link_shader(shader_program_list,"convolute1",shader_program_id)) { + shader_program_map_["convolute1"]=shader_program_id; + } valid_=true; } diff --git a/modules/gfx/src/shader/convolute1_fs.glsl b/modules/gfx/src/shader/convolute1_fs.glsl new file mode 100644 index 0000000000000000000000000000000000000000..67cc0cdb1d5094c8118e0a5d442b051986fc65ba --- /dev/null +++ b/modules/gfx/src/shader/convolute1_fs.glsl @@ -0,0 +1,62 @@ +uniform sampler2D data; +uniform sampler1D kernel; +uniform int kernel_size; +uniform int vp_width; +uniform int vp_height; + +void main() +{ + vec3 kernel_data[13]; + vec3 kmod=vec3(1.0/(float)vp_width,1.0/(float)vp_height,1.0); + kernel_data[0]=kmod*vec3(-2,0,0.02); + kernel_data[1]=kmod*vec3(-1,-1,0.141421); + kernel_data[2]=kmod*vec3(-1,0,0.37606); + kernel_data[3]=kmod*vec3(-1,1,0.141421); + kernel_data[4]=kmod*vec3(0,-2,0.02); + kernel_data[5]=kmod*vec3(0,-1,0.37606); + kernel_data[6]=kmod*vec3(0,0,1); + kernel_data[7]=kmod*vec3(0,1,0.37606); + kernel_data[8]=kmod*vec3(0,2,0.02); + kernel_data[9]=kmod*vec3(1,-1,0.141421); + kernel_data[10]=kmod*vec3(1,0,0.37606); + kernel_data[11]=kmod*vec3(1,1,0.141421); + kernel_data[12]=kmod*vec3(2,0,0.02); + + float sum=0.0; + float sum2=0.0; + int i; + for (i=0;i<13;i=i+1) { + sum+=kernel_data[i].z*texture2D(data,gl_TexCoord[0].xy+kernel_data[i].xy).r; + sum2+=kernel_data[i].z; + } + sum=sum/sum2; + float delta=5.0*(sum-texture2D(data,gl_TexCoord[0].xy).r); + if(delta<0.0) { + gl_FragColor.rgb=vec3(1+delta,1+delta,1+delta); + } else { + gl_FragColor.rgb=vec3(1,1,1); + } + gl_FragColor.a=1.0; + + +/* + float sum=0.0; + float sum2=0.0; + float isize=1.0/(float)(kernel_size); + for (i=0;i<kernel_size;i=i+1) { + float ii=(float(i)+0.5)*isize; + vec3 kernel_value=texture1D(kernel,ii).xyz; + vec2 offset = kernel_value.xy*2.0-1.0; + sum+=kernel_value.z*texture2D(data,gl_TexCoord[0].xy+offset).r; + sum2+=kernel_value.z; + } + sum=sum/sum2; + float delta=(sum-texture2D(data,gl_TexCoord[0].xy).r); + if(delta<0.0) { + gl_FragColor.rgb=vec3(1+delta,1+delta,1+delta); + } else { + gl_FragColor.rgb=vec3(1,1,1); + } + gl_FragColor.a=1.0; +*/ +} diff --git a/modules/gfx/src/shader/convolute1_vs.glsl b/modules/gfx/src/shader/convolute1_vs.glsl new file mode 100644 index 0000000000000000000000000000000000000000..5760f62116b23c27f68ef3f74d9e4a079429718c --- /dev/null +++ b/modules/gfx/src/shader/convolute1_vs.glsl @@ -0,0 +1,6 @@ +void main() +{ + gl_Position = ftransform(); + gl_TexCoord[0].st = 0.5*(gl_Position.xy+vec2(1.0,1.0)); +} +