diff --git a/modules/gfx/src/CMakeLists.txt b/modules/gfx/src/CMakeLists.txt index 8630622c35b5b03b808fce8d2e47c02015445a6e..26fb2b7b8cf1d3a339ed770e79d7bd56d6993c92 100644 --- a/modules/gfx/src/CMakeLists.txt +++ b/modules/gfx/src/CMakeLists.txt @@ -251,6 +251,7 @@ if (USE_SHADER) shader/toon_fs.glsl shader/toon_vs.glsl shader/screenblur4_fs.glsl + shader/test_tex_fs.glsl ) copy_if_different("./" "${SHARED_DATA_PATH}/shader" "${SHADER_FILES}" "SHADER_TARGETS" ost_gfx) diff --git a/modules/gfx/src/impl/cartoon_renderer.cc b/modules/gfx/src/impl/cartoon_renderer.cc index 5a10e13fa56bf79c6568ea62785947236db82f4f..a8e1bd5cdde3e398da204cd17580c53f11836548 100644 --- a/modules/gfx/src/impl/cartoon_renderer.cc +++ b/modules/gfx/src/impl/cartoon_renderer.cc @@ -490,15 +490,25 @@ TraceProfile CartoonRenderer::TransformAndAddProfile(const std::vector<TraceProf norm[2],orth[2],dir[2]); // assemble profile with custom coloring - TraceProfile tf_prof(prof1.size()); + + /* + N+1 is used here because the first point + needs to be duplicated for texture + coordinate assignment to work properly + */ + TraceProfile tf_prof(prof1.size()+1); + + unsigned int half=prof1.size()/2; unsigned int seg=prof1.size()/16; - for(unsigned int c=0;c<prof1.size();++c) { - geom::Vec3 vec=rmat*se.rad*prof1[c].v; - geom::Vec3 norm=rmat*prof1[c].n; + for(unsigned int c=0;c<prof1.size()+1;++c) { + // use cc everywhere except for the texture coordinate calculation + int cc=c%prof1.size(); + geom::Vec3 vec=rmat*se.rad*prof1[cc].v; + geom::Vec3 norm=rmat*prof1[cc].n; if(fuse_flag) { - geom::Vec3 vec2=rmat*se.rad*prof2[c].v; - geom::Vec3 norm2=rmat*prof2[c].n; + geom::Vec3 vec2=rmat*se.rad*prof2[cc].v; + geom::Vec3 norm2=rmat*prof2[cc].n; vec=se.position+(1.0f-se.frac)*vec+se.frac*vec2; norm=Normalize((1.0f-se.frac)*norm+se.frac*norm2); } else { @@ -516,7 +526,10 @@ TraceProfile CartoonRenderer::TransformAndAddProfile(const std::vector<TraceProf } else if(se.type==2 || se.type==3) { if(c<=seg || (c>=half-seg && c<=half+seg) || c>=prof1.size()-seg) col=se.color2; } - tf_prof[c].id=va.Add(vec,norm, col); + // c is used instead of cc to get 1.0 for the last point + float tx=static_cast<float>(c)/static_cast<float>(prof1.size()); + float ty=se.running_length; + tf_prof[c].id=va.Add(vec,norm,col,geom::Vec2(tx,ty)); } return tf_prof; } @@ -535,15 +548,26 @@ void CartoonRenderer::AssembleProfile(const TraceProfile& prof1, const TraceProfile& prof2, IndexedVertexArray& va) { + /* + the wrap around algorithm used here needs to take into account + that the TraceProfile has a duplicate entry for prof*[0] and + prof*[N-1], which fall onto the same point except and have + the same normal but a different texture coordinate. Hence + all the mods are done with size()-1, but in the assembly + routine prof*[0] is turned into prof*[N-1] if necessary + */ + size_t size=prof1.size()-1; + + // first get the best correction offset 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(); + for(int i=0;i<size;++i) { + int i1=(i+0)%(size); + int i2=(i+1)%(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(); + int i3=(i+k+0+size)%(size); + int i4=(i+k+1+size)%(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); @@ -558,13 +582,17 @@ void CartoonRenderer::AssembleProfile(const TraceProfile& prof1, best_off=k; } } - best_off=(best_off+prof1.size())%prof1.size(); + best_off=(best_off+(size))%(size); + + // now assemble the triangles + for(unsigned int i1=0;i1<size;++i1) { + unsigned int i2=(i1+1)%(size); + unsigned int i3=(i1+best_off)%(size); + unsigned int i4=(i1+best_off+1)%(size); - // assume both profiles have the same size - for(unsigned int i1=0;i1<prof1.size();++i1) { - unsigned int i2=(i1+1)%prof1.size(); - unsigned int i3=(i1+best_off)%prof1.size(); - unsigned int i4=(i1+best_off+1)%prof1.size(); + // wrap around correction for proper texture coordinates + i2 = (i2==0) ? size : i2; + i4 = (i4==0) ? size : i4; #if 1 va.AddTri(prof1[i1].id,prof1[i2].id,prof2[i3].id); @@ -580,13 +608,16 @@ void CartoonRenderer::CapProfile(const impl::TraceProfile& p, bool flipn, IndexedVertexArray& va) { geom::Vec3 norm=flipn ? -se.direction : se.direction; - VertexID pi0 = va.Add(se.position,norm, se.color1); + VertexID pi0 = va.Add(se.position,norm, se.color1,geom::Vec2(0.5,0.5)); std::vector<VertexID> vertices(p.size()); + float fac=2.0*M_PI/static_cast<float>(p.size()-1); for(unsigned int i=0;i<p.size();++i) { - vertices[i]=va.Add(p[i].v,norm,se.color1); + float aa=fac*static_cast<float>(i%(p.size()-1)); + vertices[i]=va.Add(p[i].v,norm,se.color1,geom::Vec2(0.5*cos(aa)+0.5,0.5*sin(aa)+0.5)); } - for(unsigned int i1=0;i1<p.size();++i1) { - unsigned int i2=(i1+1)%p.size(); + // taking first/last duplication into account again (see AssembleProfile) + for(unsigned int i1=0;i1<p.size()-1;++i1) { + unsigned int i2=i1+1; if(flipn) { va.AddTri(pi0,vertices[i2],vertices[i1]); } else { diff --git a/modules/gfx/src/impl/entity_detail.cc b/modules/gfx/src/impl/entity_detail.cc index 59f1042337de0328a45bbc98a35fc3a75bb02445..fb78ff377b0605ba6659f2a9b0703cc095852fcd 100644 --- a/modules/gfx/src/impl/entity_detail.cc +++ b/modules/gfx/src/impl/entity_detail.cc @@ -378,9 +378,10 @@ SplineEntryList Spline::Generate(const SplineEntryList& entry_list, int nsub, ui sublist.at(c*nsub+d).type=entry_list[c].type; sublist.at(c*nsub+d).type1=type1; sublist.at(c*nsub+d).type2=type2; - sublist.at(c*nsub+d).frac=float(d)/float(nsub); + float frac=float(d)/float(nsub); + sublist.at(c*nsub+d).frac=frac; } - } + } int type1=entry_list.back().type; int type2=type1; sublist.back().type=entry_list.back().type; @@ -388,6 +389,11 @@ SplineEntryList Spline::Generate(const SplineEntryList& entry_list, int nsub, ui sublist.back().type2=type2; sublist.back().frac=0.0; + float insub=1.0/static_cast<float>(nsub); + for(int c=0;c<sublist.size();++c) { + sublist[c].running_length=static_cast<float>(c)*insub; + } + // the id for selections, shifted by one half for(int c=0;c<size-1;++c) { int d=0; diff --git a/modules/gfx/src/impl/entity_detail.hh b/modules/gfx/src/impl/entity_detail.hh index 243ade1572723e578753901f6c9bb0ffdfe0f0f3..2ae0a848f14c3e7c711f67dc31e436969a4a22d0 100644 --- a/modules/gfx/src/impl/entity_detail.hh +++ b/modules/gfx/src/impl/entity_detail.hh @@ -123,6 +123,7 @@ struct DLLEXPORT_OST_GFX SplineEntry { type1(0), type2(0), frac(0.0), + running_length(0.0), v0(1.0,0.0,0.0), v1(0.0,1.0,0.0), v2(0.0,0.0,1.0), @@ -137,7 +138,7 @@ struct DLLEXPORT_OST_GFX SplineEntry { const Color& c1, const Color& c2, unsigned int t, int i): position(p),direction(d),normal(n),color1(c1),color2(c2),rad(r),type(t), - type1(t),type2(t),frac(0.0),v0(),v1(),v2(),nflip(false),id(i) + type1(t),type2(t),frac(0.0),running_length(0.0),v0(),v1(),v2(),nflip(false),id(i) { } @@ -146,7 +147,7 @@ struct DLLEXPORT_OST_GFX SplineEntry { float rad; unsigned int type; unsigned int type1, type2; - float frac; + float frac,running_length; geom::Vec3 v0,v1,v2; // helper vectors bool nflip; int id; diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc index fdac2ef582bc0d7ccd7e43f68b09b8d6cac48e3e..b2fbd79d54eb53c6dfefdf80fc8f0942fcac5938 100644 --- a/modules/gfx/src/scene.cc +++ b/modules/gfx/src/scene.cc @@ -276,6 +276,8 @@ void Scene::SetShadingMode(const std::string& smode) Shader::Instance().Activate("toon1"); } else if(smode=="toon2") { Shader::Instance().Activate("toon2"); + } else if(smode=="test_tex") { + Shader::Instance().Activate("test_tex"); } else { Shader::Instance().Activate("fraglight"); } diff --git a/modules/gfx/src/shader.cc b/modules/gfx/src/shader.cc index 81df738587895a1f4c8dad546a78bcea749c441a..b82bae72b21fc20766fa869f79cc2df5b31783d5 100644 --- a/modules/gfx/src/shader.cc +++ b/modules/gfx/src/shader.cc @@ -162,7 +162,8 @@ void Shader::Setup() {"scenefx_vs.glsl", GL_VERTEX_SHADER}, {"scenefx_fs.glsl", GL_FRAGMENT_SHADER}, {"beacon_fs.glsl", GL_FRAGMENT_SHADER}, - {"screenblur4_fs.glsl", GL_FRAGMENT_SHADER} + {"screenblur4_fs.glsl", GL_FRAGMENT_SHADER}, + {"test_tex_fs.glsl", GL_FRAGMENT_SHADER} ////////////////////////////////////////////////////////////////// }; @@ -305,6 +306,13 @@ void Shader::Setup() if(link_shader(shader_program_list,"screenblur4",shader_program_id)) { shader_program_map_["screenblur4"]=shader_program_id; } + // test tex shader + shader_program_list.clear(); + shader_program_list.push_back(shader_code_map_["fraglight_vs.glsl"]); + shader_program_list.push_back(shader_code_map_["test_tex_fs.glsl"]); + if(link_shader(shader_program_list,"test_tex",shader_program_id)) { + shader_program_map_["test_tex"]=shader_program_id; + } valid_=true; } diff --git a/modules/gfx/src/shader/test_tex_fs.glsl b/modules/gfx/src/shader/test_tex_fs.glsl new file mode 100644 index 0000000000000000000000000000000000000000..575f75dfda4409b0267f9674d23fbcabc119e10b --- /dev/null +++ b/modules/gfx/src/shader/test_tex_fs.glsl @@ -0,0 +1,6 @@ +void main() +{ + gl_FragColor.rg=frac(gl_TexCoord[0].st); + gl_FragColor.b=1.0; + gl_FragColor.a=1.0; +} diff --git a/modules/gfx/src/vertex_array.cc b/modules/gfx/src/vertex_array.cc index 541b881511c621c4bf3aa3df75d91ed319059231..b47a682a9a8be373d41d61d3a9acf61af5fc12b1 100644 --- a/modules/gfx/src/vertex_array.cc +++ b/modules/gfx/src/vertex_array.cc @@ -670,7 +670,7 @@ void IndexedVertexArray::Reset() outline_exp_factor_=0.1; outline_exp_color_=Color(0,0,0); draw_normals_=false; - use_tex_=false; + use_tex_=true; } void IndexedVertexArray::FlagRefresh() @@ -1146,7 +1146,7 @@ void IndexedVertexArray::draw_ltq(bool use_buff) { if(use_buff && !Scene::Instance().InOffscreenMode()) { #if OST_SHADER_SUPPORT_ENABLED -#if 1 +#if 0 /* for now, since v,n,c live in a packed format (formerly used with glInterleavedArrays), only a single buffer is diff --git a/modules/gfx/src/vertex_array.hh b/modules/gfx/src/vertex_array.hh index 332f03df3eadf12f2414585c02c070ddb43ba1b5..3883c2abe9e298be14c9f64a7d091d51b52e4bda 100644 --- a/modules/gfx/src/vertex_array.hh +++ b/modules/gfx/src/vertex_array.hh @@ -111,7 +111,7 @@ class DLLEXPORT_OST_GFX IndexedVertexArray { void SetOutlineExpandFactor(float f); void SetOutlineExpandColor(const Color& c); - // vertex, normal, and color (C4F_N3F_V3F) + // vertex, normal, color and texcoord (T2F_C4F_N3F_V3F) VertexID Add(const geom::Vec3& vert, const geom::Vec3& norm, const Color& col, const geom::Vec2& tex=geom::Vec2()); unsigned int GetVertexCount() const; @@ -182,7 +182,7 @@ class DLLEXPORT_OST_GFX IndexedVertexArray { // experimental, do not use void SmoothVertices(float smoothf); - void SetTex(bool b) {use_tex_=b;} + void UseTex(bool b) {use_tex_=b;} uint& TexID() {return tex_id_;} const EntryList& GetEntries() const {return entry_list_;}