diff --git a/modules/gfx/pymod/export_gfx_obj.cc b/modules/gfx/pymod/export_gfx_obj.cc index de30f31ec2c981b966cee2a042228aaf91415bf1..a68c505d11d2bf159722236da9fb9c1470df600d 100644 --- a/modules/gfx/pymod/export_gfx_obj.cc +++ b/modules/gfx/pymod/export_gfx_obj.cc @@ -80,6 +80,7 @@ void export_GfxObj() .def("SetOutlineExpandFactor",&GfxObj::SetOutlineExpandFactor) .def("SetOutlineExpandColor",&GfxObj::SetOutlineExpandColor) .def("SmoothVertices",&GfxObj::SmoothVertices) + .def("AmbientOcclusion",&GfxObj::AmbientOcclusion) .add_property("debug",get_debug,set_debug) .add_property("center", &GfxObj::GetCenter) COLOR_BY_DEF() diff --git a/modules/gfx/src/CMakeLists.txt b/modules/gfx/src/CMakeLists.txt index 1f3569435d076ee65bbce91396eedb07453cb918..c07798109ce865af880e7d071888cbdac7ae7991 100644 --- a/modules/gfx/src/CMakeLists.txt +++ b/modules/gfx/src/CMakeLists.txt @@ -61,6 +61,7 @@ trace_render_options.hh set(OST_GFX_IMPL_HEADERS +calc_ambient.hh cartoon_renderer.hh custom_renderer.hh cpk_renderer.hh @@ -115,6 +116,7 @@ color_ops/gradient_color_op.cc color_ops/entity_view_color_op.cc color_ops/basic_gradient_color_op.cc color_ops/gradient_level_color_op.cc +impl/calc_ambient.cc impl/entity_renderer.cc impl/entity_detail.cc impl/cartoon_renderer.cc diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc index 7aaf85e382283c1bb8d7645073e7dc1e4057d2d0..bfd47eaed143133ae131d9e378422d2e6e8d03f5 100644 --- a/modules/gfx/src/gfx_object.cc +++ b/modules/gfx/src/gfx_object.cc @@ -62,7 +62,8 @@ GfxObj::GfxObj(const String& name): smoothf_(0.0), omode_(0), c_ops_(), - labels_() + labels_(), + use_occlusion_(false) { } @@ -155,6 +156,7 @@ void GfxObj::RefreshVA(IndexedVertexArray& va) va.SetLineHalo(GetLineHalo()); va.DrawNormals(debug_flags_&0x1); va.SetPolyMode(debug_flags_&0x2 ? 1 : 2); + va.UseAmbient(use_occlusion_); va.FlagRefresh(); } @@ -609,6 +611,13 @@ void GfxObj::SmoothVertices(float smoothf) FlagRefresh(); } +void GfxObj::AmbientOcclusion(bool f) +{ + use_occlusion_=f; + va_.UseAmbient(f); + // FlagRefresh(); +} + void GfxObj::ColorBy(const mol::EntityView& ev, const String& prop, const Gradient& g, float minv, float maxv) diff --git a/modules/gfx/src/gfx_object.hh b/modules/gfx/src/gfx_object.hh index 15500849db52db226103823d8bdbd06226df0af4..2a52179120a2d09c243d971fe64924b75b3ff68f 100644 --- a/modules/gfx/src/gfx_object.hh +++ b/modules/gfx/src/gfx_object.hh @@ -195,8 +195,11 @@ public: void SetOutlineExpandFactor(float f); void SetOutlineExpandColor(const Color& c); + // experimental, don't use void SmoothVertices(float smoothf); - + // experimental, don't use + void AmbientOcclusion(bool f); + void GLCleanup(); /// \brief color each component based on the gradient-mapped property of @@ -300,6 +303,7 @@ public: TextPrimList labels_; void render_labels() const; + bool use_occlusion_; }; }} //ns diff --git a/modules/gfx/src/impl/calc_ambient.cc b/modules/gfx/src/impl/calc_ambient.cc new file mode 100644 index 0000000000000000000000000000000000000000..7fb0584c75c8b426f3f28236a66de12ee41af14d --- /dev/null +++ b/modules/gfx/src/impl/calc_ambient.cc @@ -0,0 +1,234 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2010 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ + +/* + Author: Ansgar Philippsen +*/ + +#include <map> +#include <vector> +#include <limits> + +#include <ost/geom/geom.hh> +#include <ost/gfx/vertex_array.hh> + +#include "calc_ambient.hh" + +using namespace ost; +using namespace ost::gfx; + +namespace { + + typedef IndexedVertexArray::EntryList EntryList; + typedef IndexedVertexArray::IndexList IndexList; + + + std::pair<geom::Vec3, geom::Vec3> calc_limits(const EntryList& elist) + { + geom::Vec3 minc(std::numeric_limits<float>::max(), + std::numeric_limits<float>::max(), + std::numeric_limits<float>::max()); + geom::Vec3 maxc(-std::numeric_limits<float>::max(), + -std::numeric_limits<float>::max(), + -std::numeric_limits<float>::max()); + + for(EntryList::const_iterator it=elist.begin();it!=elist.end();++it) { + minc[0]=std::min(it->v[0],minc[0]); + minc[1]=std::min(it->v[1],minc[1]); + minc[2]=std::min(it->v[2],minc[2]); + maxc[0]=std::max(it->v[0],maxc[0]); + maxc[1]=std::max(it->v[1],maxc[1]); + maxc[2]=std::max(it->v[2],maxc[2]); + } + return std::make_pair(minc,maxc); + } + + struct CIndex { + CIndex(): u(0),v(0),w(0) {} + CIndex(long uu, long vv, long ww): u(uu), v(vv), w(ww) {} + long u,v,w; + bool operator<(const CIndex& rhs) const { + return u==rhs.u ? (v==rhs.v ? w<rhs.w : v<rhs.v) : u<rhs.u; + } + }; + + struct CEntry { + CEntry(): id(0), v(),n(),c() {} + CEntry(unsigned int ii, const geom::Vec3& vv, const geom::Vec3& nn, const Color& cc): id(ii), v(vv), n(nn), c(cc) {} + unsigned int id; + geom::Vec3 v; + geom::Vec3 n; + Color c; + }; + + typedef std::map<CIndex,std::vector<CEntry> > CMap; + + class AmbientOcclusionBuilder { + public: + AmbientOcclusionBuilder(IndexedVertexArray& va): va_(va), cmap_(), bsize_(5.0), weight_(0.2), cutoff2_(25.0) {} + + CIndex coord_to_index(const geom::Vec3& v) + { + return CIndex(static_cast<int>(floor(v[0]/bsize_)), + static_cast<int>(floor(v[1]/bsize_)), + static_cast<int>(floor(v[2]/bsize_))); + } + + void build_cmap() { + const EntryList& elist = va_.GetEntries(); + const IndexList& tlist = va_.GetTriIndices(); + const IndexList& qlist = va_.GetQuadIndices(); + + cmap_.clear(); + + for(unsigned int c=0;c<tlist.size();c+=3) { + const float* v0=elist[tlist[c+0]].v; + const float* v1=elist[tlist[c+1]].v; + const float* v2=elist[tlist[c+2]].v; + const float* n0=elist[tlist[c+0]].n; + const float* n1=elist[tlist[c+1]].n; + const float* n2=elist[tlist[c+2]].n; + const float* c0=elist[tlist[c+0]].c; + const float* c1=elist[tlist[c+1]].c; + const float* c2=elist[tlist[c+2]].c; + add_to_cmap(c, + geom::Vec3((v0[0]+v1[0]+v2[0])/3.0, + (v0[1]+v1[1]+v2[1])/3.0, + (v0[2]+v1[2]+v2[2])/3.0), + geom::Normalize(geom::Vec3((n0[0]+n1[0]+n2[0]), + (n0[1]+n1[1]+n2[1]), + (n0[2]+n1[2]+n2[2]))), + Color((c0[0]+c1[0]+c2[0])/3.0, + (c0[1]+c1[1]+c2[1])/3.0, + (c0[2]+c1[2]+c2[2])/3.0, + (c0[3]+c1[3]+c2[3])/3.0)); + } + for(unsigned int c=0;c<qlist.size();c+=4) { + const float* v0=elist[tlist[c+0]].v; + const float* v1=elist[tlist[c+1]].v; + const float* v2=elist[tlist[c+2]].v; + const float* v3=elist[tlist[c+3]].v; + const float* n0=elist[tlist[c+0]].n; + const float* n1=elist[tlist[c+1]].n; + const float* n2=elist[tlist[c+2]].n; + const float* n3=elist[tlist[c+3]].n; + const float* c0=elist[tlist[c+0]].c; + const float* c1=elist[tlist[c+1]].c; + const float* c2=elist[tlist[c+2]].c; + const float* c3=elist[tlist[c+3]].c; + add_to_cmap(c, + geom::Vec3((v0[0]+v1[0]+v2[0]+v3[0])/4.0, + (v0[1]+v1[1]+v2[1]+v3[1])/4.0, + (v0[2]+v1[2]+v2[2]+v3[2])/4.0), + geom::Normalize(geom::Vec3((n0[0]+n1[0]+n2[0]+n3[0]), + (n0[1]+n1[1]+n2[1]+n3[1]), + (n0[2]+n1[2]+n2[2]+n3[2]))), + Color((c0[0]+c1[0]+c2[0]+c3[0])/4.0, + (c0[1]+c1[1]+c2[1]+c3[1])/4.0, + (c0[2]+c1[2]+c2[2]+c3[2])/4.0, + (c0[3]+c1[3]+c2[3]+c3[3])/4.0)); + } + } + + void add_to_cmap(unsigned int id, const geom::Vec3& v, const geom::Vec3& n, const Color& c) + { + CIndex cindex=coord_to_index(v); + CMap::iterator it=cmap_.find(cindex); + if(it==cmap_.end()) { + std::vector<CEntry> tmplist(1); + tmplist[0]=CEntry(id,v,n,c); + cmap_[cindex]=tmplist; + } else { + it->second.push_back(CEntry(id,v,n,c)); + } + } + + void accumulate(unsigned int eid, const CIndex& cindex, const geom::Vec3& epos, const geom::Vec3& enorm, Color& color, float& factor) + { + CMap::iterator cit=cmap_.find(cindex); + if(cit==cmap_.end()) return; + std::vector<CEntry>::const_iterator eit2=cit->second.end(); + for(std::vector<CEntry>::const_iterator eit=cit->second.begin();eit!=eit2;++eit) { + geom::Vec3 diff=(eit->v-epos); + float l2=geom::Length2(diff); + if(l2<cutoff2_) { + // angle between vertex normal and direction to close face + float cw1=geom::Dot(geom::Normalize(diff),enorm); + // only consider those that are "in front" + if(cw1>0.0) { + // angle between direction and close face normal + float cw2=1.0-geom::Dot(diff,eit->n); + // only consider those that point towards each other + if(cw2>0.0) { + cw2*=cw1; + color[0]+=cw2*eit->c[0]; + color[1]+=cw2*eit->c[1]; + color[2]+=cw2*eit->c[2]; + factor+=1.0; + } + } + } + } + } + + void calc_all() { + const EntryList& elist = va_.GetEntries(); + + for(unsigned int c=0;c<elist.size();++c) { + geom::Vec3 epos(elist[c].v[0],elist[c].v[1],elist[c].v[2]); + geom::Vec3 enorm(elist[c].n[0],elist[c].n[1],elist[c].n[2]); + CIndex cindex0=coord_to_index(epos); + Color color; + float factor; + + for(int w=-1;w<=1;++w) { + for(int v=-1;v<=1;++v) { + for(int u=-1;u<=1;++u) { + accumulate(c,CIndex(cindex0.u+u,cindex0.v+v,cindex0.w+w),epos,enorm,color,factor); + } + } + } + + color[0]/=factor; + color[1]/=factor; + color[2]/=factor; + color[3]=weight_; + va_.SetAmbientColor(c,color); + } + + } + + private: + IndexedVertexArray& va_; + CMap cmap_; + float bsize_; + float weight_; + float cutoff2_; + }; + +} // ns + + + +void ost::gfx::CalcAmbientTerms(IndexedVertexArray& va) +{ + AmbientOcclusionBuilder aob(va); + aob.build_cmap(); + aob.calc_all(); +} diff --git a/modules/gfx/src/impl/calc_ambient.hh b/modules/gfx/src/impl/calc_ambient.hh new file mode 100644 index 0000000000000000000000000000000000000000..6064f84c9aabf4344734254461e91a2b67683788 --- /dev/null +++ b/modules/gfx/src/impl/calc_ambient.hh @@ -0,0 +1,35 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2010 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#ifndef OST_CALC_AMBIENT_HH +#define OST_CALC_AMBIENT_HH + +/* + calculate ambient contributions per VA entry + + Author: Ansgar Philippsen +*/ + +namespace ost { namespace gfx { + + class IndexedVertexArray; + void CalcAmbientTerms(IndexedVertexArray& va); + +}} // ns + +#endif diff --git a/modules/gfx/src/shader/fraglight_lf_fs.glsl b/modules/gfx/src/shader/fraglight_lf_fs.glsl index 7c225a41b86e60d92eee192fbdf4b7fdb98d6751..08b7f3a1cdc15d5737d9ca6e3ecbc75461c440ee 100644 --- a/modules/gfx/src/shader/fraglight_lf_fs.glsl +++ b/modules/gfx/src/shader/fraglight_lf_fs.glsl @@ -1,6 +1,7 @@ uniform bool lighting_flag; uniform bool two_sided_flag; uniform bool fog_flag; +uniform bool occlusion_flag; // copy from basic_fl_vs ! bool DirectionalLight(in vec3 normal, @@ -51,6 +52,10 @@ void main() gl_FragColor = gl_Color; } + if(occlusion_flag) { + gl_FragColor.rgb = mix(gl_TexCoord[2].stp,gl_FragColor.rgb, gl_TexCoord[2].q); + } + if(fog_flag) { float fog = clamp((gl_Fog.end-gl_FogFragCoord) * gl_Fog.scale, 0.0, 1.0); gl_FragColor.rgb = mix(gl_Fog.color.rgb, gl_FragColor.rgb, fog); diff --git a/modules/gfx/src/shader/fraglight_lf_vs.glsl b/modules/gfx/src/shader/fraglight_lf_vs.glsl index 1913f445eaf04f43bdce4d9e9dea6a4021777e8c..c6328cf10c3ad357fde3abd555c9817294c12502 100644 --- a/modules/gfx/src/shader/fraglight_lf_vs.glsl +++ b/modules/gfx/src/shader/fraglight_lf_vs.glsl @@ -1,3 +1,5 @@ +uniform bool occlusion_flag; + void main() { // transformed position @@ -11,6 +13,10 @@ void main() // since a directional light is used, the position is not needed gl_TexCoord[0].stp=normal; + if(occlusion_flag) { + // ambient color + gl_TexCoord[2] = gl_MultiTexCoord0; + } gl_FrontColor=gl_Color; gl_BackColor=gl_Color; } diff --git a/modules/gfx/src/vertex_array.cc b/modules/gfx/src/vertex_array.cc index b93bd594159f8b486fbe4ce0a930324fd49b79ab..f0ef0822c36eaad65d8c205be6506d37b4c8bda3 100644 --- a/modules/gfx/src/vertex_array.cc +++ b/modules/gfx/src/vertex_array.cc @@ -31,6 +31,8 @@ #include "vertex_array_helper.hh" #include "povray.hh" +#include "impl/calc_ambient.hh" + #if OST_SHADER_SUPPORT_ENABLED #include "shader.hh" #endif @@ -48,6 +50,15 @@ using namespace geom; namespace gfx { +// the header and this file contain several magic number 7 uses related to the max buffer +static const int VA_VERTEX_BUFFER=0; +static const int VA_LINEINDEX_BUFFER=1; +static const int VA_TRIINDEX_BUFFER=2; +static const int VA_QUADINDEX_BUFFER=3; +static const int VA_AMBIENT_BUFFER=4; +static const int VA_NORMAL_BUFFER=5; +static const int VA_COLOR_BUFFER=6; + IndexedVertexArray::Entry::Entry() { v[0]=0.0; v[1]=0.0; v[2]=0.0; @@ -96,7 +107,7 @@ void IndexedVertexArray::Cleanup() if(initialized_) { glDeleteLists(outline_mat_dlist_,1); #if OST_SHADER_SUPPORT_ENABLED - glDeleteBuffers(4,buffer_id_); + glDeleteBuffers(7,buffer_id_); #endif initialized_=false; } @@ -329,7 +340,7 @@ void IndexedVertexArray::RenderGL() if(!initialized_) { LOGN_DUMP("initializing vertex array lists"); #if OST_SHADER_SUPPORT_ENABLED - glGenBuffers(4,buffer_id_); + glGenBuffers(7,buffer_id_); #endif outline_mat_dlist_=glGenLists(1); initialized_=true; @@ -338,6 +349,11 @@ void IndexedVertexArray::RenderGL() if(dirty_) { dirty_=false; #if OST_SHADER_SUPPORT_ENABLED + if(use_ambient_) { + LOGN_DUMP("re-calculating ambient occlusion terms"); + recalc_ambient_occlusion(); + } + LOGN_DUMP("checking buffer object availability"); if(mode_&0x2 && aalines_flag_) { use_buff=false; @@ -396,6 +412,7 @@ void IndexedVertexArray::RenderGL() glDisable(GL_BLEND); } } else { + // not in outline mode if(lighting_) { glEnable(GL_LIGHTING); } else { @@ -416,6 +433,11 @@ void IndexedVertexArray::RenderGL() } else { glDisable(GL_CULL_FACE); } +#if OST_SHADER_SUPPORT_ENABLED + if(use_ambient_ && !ambient_data_.empty()) { + glUniform1i(glGetUniformLocation(Shader::Instance().GetCurrentProgram(),"occlusion_flag"),1); + } +#endif } if(mode_&0x1) { @@ -481,6 +503,12 @@ void IndexedVertexArray::RenderGL() } } +#if OST_SHADER_SUPPORT_ENABLED + if(use_ambient_) { + glUniform1i(glGetUniformLocation(Shader::Instance().GetCurrentProgram(),"occlusion_flag"),0); + } +#endif + if(draw_normals_) { //glColor3f(1,0,0); glBegin(GL_LINES); @@ -596,6 +624,9 @@ void IndexedVertexArray::Clear() outline_exp_factor_=0.1; outline_exp_color_=Color(0,0,0); draw_normals_=false; + use_ambient_=false; + ambient_dirty_=true; + ambient_data_.clear(); } void IndexedVertexArray::FlagRefresh() @@ -868,6 +899,35 @@ void IndexedVertexArray::SmoothVertices(float smoothf) } } +void IndexedVertexArray::UseAmbient(bool f) +{ + if(use_ambient_==f) return; + use_ambient_=f; + FlagRefresh(); +} + +Color IndexedVertexArray::GetAmbientColor(VertexID id) const +{ + Color nrvo; + if(id*4>=ambient_data_.size()) return nrvo; + unsigned int offset=id*4; + nrvo = Color(ambient_data_[offset+0], + ambient_data_[offset+1], + ambient_data_[offset+2], + ambient_data_[offset+3]); + return nrvo; +} + +void IndexedVertexArray::SetAmbientColor(VertexID id, const Color& c) +{ + if(id*4>=ambient_data_.size()) return; + unsigned int offset=id*4; + ambient_data_[offset+0]=c[0]; + ambient_data_[offset+1]=c[1]; + ambient_data_[offset+2]=c[2]; + ambient_data_[offset+3]=c[3]; +} + namespace { @@ -991,43 +1051,91 @@ void IndexedVertexArray::copy(const IndexedVertexArray& va) outline_exp_factor_=va.outline_exp_factor_; outline_exp_color_=va.outline_exp_color_; draw_normals_=va.draw_normals_; + use_ambient_=va.use_ambient_; + ambient_dirty_=va.ambient_dirty_; + ambient_data_=va.ambient_data_; } bool IndexedVertexArray::prep_buff() { #if OST_SHADER_SUPPORT_ENABLED + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_INDEX_ARRAY); + int glerr=glGetError(); // clear error flag - glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[0]); - VERTEX_ARRAY_CHECK_GL_ERROR("bind buf0"); + glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[VA_VERTEX_BUFFER]); + VERTEX_ARRAY_CHECK_GL_ERROR("bind vertex buf"); glBufferData(GL_ARRAY_BUFFER, sizeof(Entry) * entry_list_.size(), &entry_list_[0], GL_STATIC_DRAW); - VERTEX_ARRAY_CHECK_GL_ERROR("set buf0"); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_id_[1]); + VERTEX_ARRAY_CHECK_GL_ERROR("set vertex buf"); + + // this will be used later, when refactoring v,c,n to live in separate lists + /* + glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[VA_COLOR_BUFFER]); VERTEX_ARRAY_CHECK_GL_ERROR("bind buf1"); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - sizeof(unsigned int) * line_index_list_.size(), - &line_index_list_[0], + glBufferData(GL_ARRAY_BUFFER, + sizeof(Entry) * entry_list_.size(), + &entry_list_[0].c[0], GL_STATIC_DRAW); VERTEX_ARRAY_CHECK_GL_ERROR("set buf1"); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_id_[2]); + + glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[VA_NORMAL_BUFFER]); VERTEX_ARRAY_CHECK_GL_ERROR("bind buf2"); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - sizeof(unsigned int) * tri_index_list_.size(), - &tri_index_list_[0], + glBufferData(GL_ARRAY_BUFFER, + sizeof(Entry) * entry_list_.size(), + &entry_list_[0].n[0], GL_STATIC_DRAW); VERTEX_ARRAY_CHECK_GL_ERROR("set buf2"); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_id_[3]); - VERTEX_ARRAY_CHECK_GL_ERROR("bind buf3"); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - sizeof(unsigned int) * quad_index_list_.size(), - &quad_index_list_[0], - GL_STATIC_DRAW); - VERTEX_ARRAY_CHECK_GL_ERROR("set buf3"); + */ + + if(!line_index_list_.empty()) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_id_[VA_LINEINDEX_BUFFER]); + VERTEX_ARRAY_CHECK_GL_ERROR("bind lindex buf"); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + sizeof(unsigned int) * line_index_list_.size(), + &line_index_list_[0], + GL_STATIC_DRAW); + VERTEX_ARRAY_CHECK_GL_ERROR("set lindex buf"); + } + + if(!tri_index_list_.empty()) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_id_[VA_TRIINDEX_BUFFER]); + VERTEX_ARRAY_CHECK_GL_ERROR("bind tindex buf"); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + sizeof(unsigned int) * tri_index_list_.size(), + &tri_index_list_[0], + GL_STATIC_DRAW); + VERTEX_ARRAY_CHECK_GL_ERROR("set tindex buf"); + } + + if(!quad_index_list_.empty()) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_id_[VA_QUADINDEX_BUFFER]); + VERTEX_ARRAY_CHECK_GL_ERROR("bind qindex buf"); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + sizeof(unsigned int) * quad_index_list_.size(), + &quad_index_list_[0], + GL_STATIC_DRAW); + VERTEX_ARRAY_CHECK_GL_ERROR("set qindex buf"); + } + + if(use_ambient_) { + if(ambient_data_.empty()) { + LOGN_VERBOSE("ambient data empty"); + } else { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[VA_AMBIENT_BUFFER]); + VERTEX_ARRAY_CHECK_GL_ERROR("bind ambient buf"); + glBufferData(GL_ARRAY_BUFFER, + sizeof(float) * ambient_data_.size(), + &ambient_data_[0], + GL_STATIC_DRAW); + VERTEX_ARRAY_CHECK_GL_ERROR("set ambient buf"); + } + } return true; #else @@ -1039,29 +1147,43 @@ void IndexedVertexArray::draw_ltq(bool use_buff) { if(use_buff && !Scene::Instance().InOffscreenMode()) { #if OST_SHADER_SUPPORT_ENABLED - LOGN_TRACE("binding vertex array buffer"); - glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[0]); - LOGN_TRACE("setting up vertex array"); +#if 1 + /* + for now, since v,n,c live in a packed format (formerly used + with glInterleavedArrays), only a single buffer is + used, with the gl*Pointer calls giving the byte offset + in place of the absolute pointer + */ + glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[VA_VERTEX_BUFFER]); + glVertexPointer(3, GL_FLOAT, sizeof(Entry), reinterpret_cast<void*>(sizeof(float)*7)); + glNormalPointer(GL_FLOAT, sizeof(Entry), reinterpret_cast<void*>(sizeof(float)*4)); + glColorPointer(4, GL_FLOAT, sizeof(Entry), 0); +#else + glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[VA_VERTEX_BUFFER]); glInterleavedArrays(GetFormat(),sizeof(Entry),NULL); - +#endif + + if(use_ambient_) { + if(!ambient_data_.empty()) { + glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[VA_AMBIENT_BUFFER]); + glTexCoordPointer(4,GL_FLOAT,0,NULL); + } + } + glBindBuffer(GL_ARRAY_BUFFER,0); + if(!tri_index_list_.empty() && (mode_ & 0x4)) { - LOGN_TRACE("binding and rendering vertex array tris"); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_id_[2]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_id_[VA_TRIINDEX_BUFFER]); glDrawElements(GL_TRIANGLES,tri_index_list_.size(),GL_UNSIGNED_INT,NULL); } if(!quad_index_list_.empty() && (mode_ & 0x4)) { - LOGN_TRACE("binding and rendering vertex arras quads"); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_id_[3]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_id_[VA_QUADINDEX_BUFFER]); glDrawElements(GL_QUADS,quad_index_list_.size(),GL_UNSIGNED_INT,NULL); } if(!line_index_list_.empty() && (mode_ & 0x2)) { - LOGN_TRACE("binding and rendering vertex array lines"); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_id_[1]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_id_[VA_LINEINDEX_BUFFER]); glDrawElements(GL_LINES,line_index_list_.size(),GL_UNSIGNED_INT,NULL); } - LOGN_TRACE("unbinding vertex array buffer"); - glBindBuffer(GL_ARRAY_BUFFER,0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); #endif } else { @@ -1088,11 +1210,12 @@ void IndexedVertexArray::draw_p(bool use_buff) { if(use_buff && !Scene::Instance().InOffscreenMode()) { #if OST_SHADER_SUPPORT_ENABLED - LOGN_TRACE("binding vertex array buffer"); - glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[0]); - LOGN_TRACE("calling vertex array"); - glInterleavedArrays(GetFormat(),sizeof(Entry),NULL); - glDrawArrays(GL_POINTS,0,entry_list_.size()); + glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[VA_VERTEX_BUFFER]); + glVertexPointer(3, GL_FLOAT, sizeof(Entry), NULL); + glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[VA_NORMAL_BUFFER]); + glNormalPointer(GL_FLOAT, sizeof(Entry), NULL); + glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[VA_COLOR_BUFFER]); + glColorPointer(4, GL_FLOAT, sizeof(Entry), NULL); #endif } else { LOGN_TRACE("calling vertex array"); @@ -1277,4 +1400,11 @@ void IndexedVertexArray::draw_line_halo(bool use_buff) glLineWidth(line_width_); } +void IndexedVertexArray::recalc_ambient_occlusion() +{ + ambient_data_.resize(4*entry_list_.size()); + CalcAmbientTerms(*this); + std::cerr << ambient_data_[0] << "," << ambient_data_[1] << "," << ambient_data_[2] << "," << ambient_data_[3] << std::endl; +} + }} // ns diff --git a/modules/gfx/src/vertex_array.hh b/modules/gfx/src/vertex_array.hh index f54640c44911e1401c983f7f477dd842063e1fdd..eed4d2a7fdc97f4d3f92c3f883ed5caaed50e316 100644 --- a/modules/gfx/src/vertex_array.hh +++ b/modules/gfx/src/vertex_array.hh @@ -46,7 +46,7 @@ typedef unsigned int LineID; typedef unsigned int TriID; typedef unsigned int QuadID; class DLLEXPORT_OST_GFX IndexedVertexArray { - + public: struct Entry { Entry(); Entry(const geom::Vec3& vv, const geom::Vec3& nn, const Color& cc); @@ -74,7 +74,6 @@ class DLLEXPORT_OST_GFX IndexedVertexArray { typedef std::vector<NormalizerVertexEntry> NVEntryList; typedef std::vector<NormalizerTriEntry> NTEntryList; -public: IndexedVertexArray(); ~IndexedVertexArray(); @@ -167,7 +166,17 @@ public: void NPatch(); // experimental, do not use void SmoothVertices(float smoothf); + // experimental, do not use + void UseAmbient(bool f); + + const EntryList& GetEntries() const {return entry_list_;} + const IndexList& GetQuadIndices() const {return quad_index_list_;} + const IndexList& GetTriIndices() const {return tri_index_list_;} + const IndexList& GetLineIndices() const {return line_index_list_;} + Color GetAmbientColor(VertexID id) const; + void SetAmbientColor(VertexID id, const Color& col); + private: bool initialized_; @@ -200,7 +209,11 @@ public: bool draw_normals_; - unsigned int buffer_id_[4]; + unsigned int buffer_id_[7]; // magic number related to the .cc buffer use + + bool use_ambient_; + bool ambient_dirty_; + std::vector<float> ambient_data_; void copy(const IndexedVertexArray& va); bool prep_buff(); @@ -208,6 +221,7 @@ public: void draw_p(bool use_buff); void draw_aalines(); void draw_line_halo(bool use_buff); + void recalc_ambient_occlusion(); }; }} // ns