From 771efca5c61db45353315b26180c1dfe24ec38d2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 16 Jan 2017 17:18:58 +0000 Subject: [PATCH 01/35] Removed unused class --- src/osgVolume/MultipassTechnique.cpp | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/osgVolume/MultipassTechnique.cpp b/src/osgVolume/MultipassTechnique.cpp index e0e7ab538..3fb79cafe 100644 --- a/src/osgVolume/MultipassTechnique.cpp +++ b/src/osgVolume/MultipassTechnique.cpp @@ -928,33 +928,6 @@ void MultipassTechnique::backfaceSubgraphCullTraversal(osgUtil::CullVisitor* cv) cv->popStateSet(); } -class RTTBackfaceCameraCullCallback : public osg::NodeCallback -{ - public: - - RTTBackfaceCameraCullCallback(MultipassTechnique::MultipassTileData* tileData, MultipassTechnique* mt): - _tileData(tileData), - _mt(mt) {} - - virtual void operator()(osg::Node* /*node*/, osg::NodeVisitor* nv) - { - osgUtil::CullVisitor* cv = nv->asCullVisitor(); - - cv->pushProjectionMatrix(_tileData->projectionMatrix.get()); - - _mt->backfaceSubgraphCullTraversal(cv); - - cv->popProjectionMatrix(); - } - - protected: - - virtual ~RTTBackfaceCameraCullCallback() {} - - osg::observer_ptr _tileData; - osg::observer_ptr _mt; -}; - class ShadingModelVisitor : public osgVolume::PropertyVisitor { public: From 255a86cbe22ba436ab162bd2a2e7cc0341140050 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 17 Jan 2017 10:52:26 +0000 Subject: [PATCH 02/35] Added public accessors --- include/osg/CullStack | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/include/osg/CullStack b/include/osg/CullStack index 5e8714ee1..61eb8b2f2 100644 --- a/include/osg/CullStack +++ b/include/osg/CullStack @@ -168,13 +168,22 @@ class OSG_EXPORT CullStack : public osg::CullSettings return osg::Vec3(-matrix(0,2),-matrix(1,2),-matrix(2,2)); } + typedef fast_back_stack< ref_ptr > MatrixStack; + + MatrixStack& getProjectionStack() { return _projectionStack; } + const MatrixStack& getProjectionStack() const { return _projectionStack; } + + MatrixStack& getModelViewStack() { return _modelviewStack; } + const MatrixStack& getModelViewStack() const { return _modelviewStack; } + + MatrixStack& getMVPWStack() { return _MVPW_Stack; } + const MatrixStack& getMVPWStack() const { return _MVPW_Stack; } protected: // base set of shadow volume occluder to use in culling. ShadowVolumeOccluderList _occluderList; - typedef fast_back_stack< ref_ptr > MatrixStack; MatrixStack _projectionStack; From 10b6f7aa472143e2965ef8555540238b7c4ffecf Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 19 Jan 2017 15:56:17 +0000 Subject: [PATCH 03/35] Fixed indentation of comment --- src/osg/Texture2D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osg/Texture2D.cpp b/src/osg/Texture2D.cpp index 5cb0a459e..d73cebc37 100644 --- a/src/osg/Texture2D.cpp +++ b/src/osg/Texture2D.cpp @@ -313,7 +313,7 @@ void Texture2D::apply(State& state) const glBindTexture( GL_TEXTURE_2D, 0 ); } - // if texture object is now valid and we have to allocate mipmap levels, then + // if texture object is now valid and we have to allocate mipmap levels, then if (textureObject != 0 && _texMipmapGenerationDirtyList[contextID]) { generateMipmap(state); From 7cd7618e8c41e4bbb9497ef433e9d09b299b2d96 Mon Sep 17 00:00:00 2001 From: Marc Helbling Date: Fri, 20 Jan 2017 15:09:25 +0100 Subject: [PATCH 04/35] Updates gles from sketchfab * fixes bbox issue for animated scenes * fixes geometry split (perf + line/point primitive management) * removes degenerated faces --- src/osgPlugins/gles/AABBonBoneVisitor.cpp | 2 +- src/osgPlugins/gles/CMakeLists.txt | 6 +- src/osgPlugins/gles/GeometryCleaner | 138 +++++++++++ src/osgPlugins/gles/GeometryIndexSplitter | 92 +++++++- src/osgPlugins/gles/GeometryIndexSplitter.cpp | 222 +++++++----------- src/osgPlugins/gles/GeometryInspector | 4 +- src/osgPlugins/gles/GeometryMapper | 31 +++ src/osgPlugins/gles/OpenGLESGeometryOptimizer | 33 ++- .../gles/OpenGLESGeometryOptimizer.cpp | 6 + src/osgPlugins/gles/RemapGeometryVisitor | 51 ++++ src/osgPlugins/gles/RemapGeometryVisitor.cpp | 72 ++++++ src/osgPlugins/gles/SmoothNormalVisitor | 38 ++- src/osgPlugins/gles/TangentSpaceVisitor.cpp | 35 +-- src/osgPlugins/gles/TriangleMeshSmoother.cpp | 16 +- src/osgPlugins/gles/glesUtil | 76 +++++- 15 files changed, 608 insertions(+), 214 deletions(-) create mode 100644 src/osgPlugins/gles/GeometryCleaner create mode 100644 src/osgPlugins/gles/GeometryMapper create mode 100644 src/osgPlugins/gles/RemapGeometryVisitor create mode 100644 src/osgPlugins/gles/RemapGeometryVisitor.cpp diff --git a/src/osgPlugins/gles/AABBonBoneVisitor.cpp b/src/osgPlugins/gles/AABBonBoneVisitor.cpp index 14ff98f77..0ea5302f7 100644 --- a/src/osgPlugins/gles/AABBonBoneVisitor.cpp +++ b/src/osgPlugins/gles/AABBonBoneVisitor.cpp @@ -62,7 +62,7 @@ void ComputeAABBOnBoneVisitor::computeBoundingBoxOnBones() { } // Compare initial and actual boundingBox if (no change) => no box on bone - if(bb == osg::BoundingBox() || bb._min.x() == bb._max.x() || bb._min.y() == bb._max.y() || bb._min.z() == bb._max.z()) { + if(bb == osg::BoundingBox() || (bb._min.x() == bb._max.x() && bb._min.y() == bb._max.y() && bb._min.z() == bb._max.z())) { continue; } diff --git a/src/osgPlugins/gles/CMakeLists.txt b/src/osgPlugins/gles/CMakeLists.txt index 2f0e70829..559b460f0 100644 --- a/src/osgPlugins/gles/CMakeLists.txt +++ b/src/osgPlugins/gles/CMakeLists.txt @@ -5,9 +5,9 @@ SET(TARGET_SRC BindPerVertexVisitor.cpp DetachPrimitiveVisitor.cpp GeometryIndexSplitter.cpp - GeometrySplitterVisitor.cpp SubGeometry.cpp OpenGLESGeometryOptimizer.cpp + RemapGeometryVisitor.cpp RigAnimationVisitor.cpp RigAttributesVisitor.cpp TriangleMeshSmoother.cpp @@ -25,9 +25,11 @@ SET(TARGET_H DrawArrayVisitor EdgeIndexFunctor GeometryArray + GeometryCleaner GeometryIndexSplitter GeometryInspector - GeometrySplitterVisitor + GeometryMapper + RemapGeometryVisitor GeometryUniqueVisitor glesUtil IndexMeshVisitor diff --git a/src/osgPlugins/gles/GeometryCleaner b/src/osgPlugins/gles/GeometryCleaner new file mode 100644 index 000000000..41310281a --- /dev/null +++ b/src/osgPlugins/gles/GeometryCleaner @@ -0,0 +1,138 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) Sketchfab + * + * This application is open source and may be redistributed and/or modified + * freely and without restriction, both in commercial and non commercial + * applications, as long as this copyright notice is maintained. + * + * This application 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. + * +*/ + +#ifndef GEOMETRY_CLEANER +#define GEOMETRY_CLEANER + +#include +#include +#include + +#include "GeometryMapper" +#include "SubGeometry" + + +class GeometryCleaner : public GeometryMapper +{ +public: + + const GeometryList& process(osg::Geometry& geometry) { + _clean.clear(); + + if(dynamic_cast(&geometry)) { + // a morph geometry may have a degenerated primitive in one target but not all targets + // let's leave them unmodified + _clean.push_back(&geometry); + } + else if(dynamic_cast(&geometry)) { + // skipping rigged geometry for now + _clean.push_back(&geometry); + } + else { + osg::Vec3Array* positions = dynamic_cast(geometry.getVertexArray()); + SubGeometry cleaned(geometry, + clean(*positions, getTriangles(geometry), 3), + clean(*positions, getLines(geometry), 2), + clean(*positions, getWireframe(geometry), 2), + clean(*positions, getPoints(geometry), 1)); + _clean.push_back(cleaned.geometry()); + } + + return _clean; + } + + osg::DrawElements* getTriangles(osg::Geometry& geometry) { + for(unsigned int i = 0 ; i < geometry.getNumPrimitiveSets() ; ++ i) { + osg::DrawElements* primitive = geometry.getPrimitiveSet(i)->getDrawElements(); + if(primitive && primitive->getMode() == osg::PrimitiveSet::TRIANGLES) { + return primitive; + } + } + return 0; + } + + osg::DrawElements* getLines(osg::Geometry& geometry) { + for(unsigned int i = 0 ; i < geometry.getNumPrimitiveSets() ; ++ i) { + osg::DrawElements* primitive = geometry.getPrimitiveSet(i)->getDrawElements(); + if(primitive && primitive->getMode() == osg::PrimitiveSet::LINES) { + bool wireframe(false); + if(!primitive->getUserValue("wireframe", wireframe) || !wireframe) + return primitive; + } + } + return 0; + } + + osg::DrawElements* getWireframe(osg::Geometry& geometry) { + for(unsigned int i = 0 ; i < geometry.getNumPrimitiveSets() ; ++ i) { + osg::DrawElements* primitive = geometry.getPrimitiveSet(i)->getDrawElements(); + if(primitive && primitive->getMode() == osg::PrimitiveSet::LINES) { + bool wireframe(false); + if(primitive->getUserValue("wireframe", wireframe) && wireframe) + return primitive; + } + } + return 0; + } + + osg::DrawElements* getPoints(osg::Geometry& geometry) { + for(unsigned int i = 0 ; i < geometry.getNumPrimitiveSets() ; ++ i) { + osg::DrawElements* primitive = geometry.getPrimitiveSet(i)->getDrawElements(); + if(primitive && primitive->getMode() == osg::PrimitiveSet::POINTS) { + return primitive; + } + } + return 0; + } + + std::vector clean(const osg::Vec3Array& positions, osg::DrawElements* elements, const unsigned int size) { + std::vector indices; + + if(!elements) return indices; + + for(unsigned int i = 0 ; i < elements->getNumIndices() ; i += size) { + if(size == 3) { + unsigned int v1 = elements->index(i), + v2 = elements->index(i + 1), + v3 = elements->index(i + 2); + osg::Vec3 p1 = positions[v1], + p2 = positions[v2], + p3 = positions[v3]; + + osg::Vec3f cross = (p2 - p1) ^ (p3 - p1); + if(cross.length()) { + indices.push_back(v1); + indices.push_back(v2); + indices.push_back(v3); + } + } + else if (size == 2) { + unsigned int v1 = elements->index(i), + v2 = elements->index(i + 1); + if(!(positions[v1] == positions[v2])) { + indices.push_back(v1); + indices.push_back(v2); + } + } + else { + indices.push_back(elements->index(i)); + } + } + + return indices; + } + + + GeometryList _clean; +}; + +#endif diff --git a/src/osgPlugins/gles/GeometryIndexSplitter b/src/osgPlugins/gles/GeometryIndexSplitter index 0ce5d77a0..f43c7e8a9 100644 --- a/src/osgPlugins/gles/GeometryIndexSplitter +++ b/src/osgPlugins/gles/GeometryIndexSplitter @@ -25,15 +25,81 @@ #include #include "glesUtil" +#include "GeometryMapper" #include "GeometryArray" #include "TriangleMeshGraph" #include "SubGeometry" #include "Line" -class GeometryIndexSplitter +class GeometryIndexSplitter : public GeometryMapper { protected: + class Cluster { + public: + Cluster(unsigned int maxAllowedIndex): + maxIndex(maxAllowedIndex) + { + } + + bool full() const { + return subvertices.size() >= maxIndex; + } + + bool fullOfTriangles() const { + // consider worse case i.e. no triangle vertex is already in the cluster + // so need room for 3 indices + return subvertices.size() + 3 >= maxIndex; + } + + bool fullOfLines() const { + return subvertices.size() + 2 >= maxIndex; + } + + bool contains(unsigned int v1, unsigned int v2) const { + return contains(v1) && contains(v2); + } + + bool contains(unsigned int v1) const { + return subvertices.count(v1); + } + + void addTriangle(unsigned int v1, unsigned int v2, unsigned v3) { + subtriangles.push_back(v1); + subtriangles.push_back(v2); + subtriangles.push_back(v3); + + subvertices.insert(v1); + subvertices.insert(v2); + subvertices.insert(v3); + } + + void addLine(unsigned int v1, unsigned int v2) { + sublines.push_back(v1); + sublines.push_back(v2); + + subvertices.insert(v1); + subvertices.insert(v2); + } + + void addPoint(unsigned int v1) { + subpoints.push_back(v1); + + subvertices.insert(v1); + } + + void addWire(unsigned int v1, unsigned int v2) { + subwireframe.push_back(v1); + subwireframe.push_back(v2); + } + + public: + const unsigned int maxIndex; + IndexVector subtriangles, subwireframe, sublines, subpoints; + IndexSet subvertices; + }; + + class IndexCache : public IndexDeque { public: IndexCache(unsigned int size=64) : _size(size) @@ -48,18 +114,29 @@ protected: }; public: - typedef std::vector< osg::ref_ptr > GeometryList; - GeometryIndexSplitter(unsigned int maxAllowedIndex): _maxAllowedIndex(maxAllowedIndex) {} + const GeometryList& process(osg::Geometry& geometry) { + _geometryList.clear(); + split(geometry); + return _geometryList; + } + bool split(osg::Geometry&); - unsigned int findCandidate(const IndexVector&); - unsigned int findCandidate(const IndexVector&, const IndexVector&); - void setTriangleCluster(const TriangleMeshGraph&, unsigned int, unsigned int, IndexVector&, IndexSet&, unsigned int&); - void extract_primitives(const IndexSet&, const osg::DrawElements*, IndexVector&, unsigned int); + template + typename C::value_type getNext(C& primitives, typename C::value_type default_value) { + if(primitives.empty()) { + return default_value; + } + typename C::value_type next = *primitives.begin(); + primitives.erase(primitives.begin()); + return next; + } + + unsigned int findCandidate(IndexSet&, const IndexCache&, const TriangleMeshGraph&); protected: bool needToSplit(const osg::Geometry&) const; @@ -68,7 +145,6 @@ protected: template void setBufferBoundingBox(T*) const; - void setValidIndices(std::set&, const osg::DrawElements*) const; public: const unsigned int _maxAllowedIndex; diff --git a/src/osgPlugins/gles/GeometryIndexSplitter.cpp b/src/osgPlugins/gles/GeometryIndexSplitter.cpp index 5c3cecd1d..d2452ff0b 100644 --- a/src/osgPlugins/gles/GeometryIndexSplitter.cpp +++ b/src/osgPlugins/gles/GeometryIndexSplitter.cpp @@ -11,8 +11,8 @@ bool GeometryIndexSplitter::split(osg::Geometry& geometry) { attachBufferBoundingBox(geometry); osg::DrawElements *wire_primitive = 0, - *line_primitive = 0, - *point_primitive = 0; + *line_primitive = 0, + *point_primitive = 0; for(unsigned int i = 0 ; i < geometry.getNumPrimitiveSets() ; ++ i) { osg::DrawElements* primitive = (geometry.getPrimitiveSet(i) ? geometry.getPrimitiveSet(i)->getDrawElements() : 0); if(primitive) { @@ -31,29 +31,34 @@ bool GeometryIndexSplitter::split(osg::Geometry& geometry) { } } + TriangleMeshGraph graph(geometry, false); + // only wireframe can be processed directly as they simply "duplicate" triangle or edge data; // lines/points may reference points not used for triangles so we keep a set of primitives // that remain to process - LineSet source_lines; - IndexSet source_points; + IndexSet triangles; + LineSet lines, wires; + IndexSet points; + for(unsigned int i = 0 ; i < graph.getNumTriangles() ; ++ i) { + triangles.insert(i); + } if(line_primitive) { for(unsigned int i = 0 ; i < line_primitive->getNumIndices() ; i += 2) { - source_lines.insert(Line(line_primitive->index(i), line_primitive->index(i + 1))); + lines.insert(Line(line_primitive->index(i), line_primitive->index(i + 1))); + } + } + if(wire_primitive) { + for(unsigned int i = 0 ; i < wire_primitive->getNumIndices() ; i += 2) { + wires.insert(Line(wire_primitive->index(i), wire_primitive->index(i + 1))); } } if(point_primitive) { for(unsigned int i = 0 ; i < point_primitive->getNumIndices() ; ++ i) { - source_points.insert(point_primitive->index(i)); + points.insert(point_primitive->index(i)); } } - TriangleMeshGraph graph(geometry, false); - unsigned int remaining_triangles = graph.getNumTriangles(), - cluster = 0; - IndexVector clusters(remaining_triangles, 0); - IndexCache cache; - // assign a cluster id for each triangle // 1. bootstrap cluster by selecting first remaining triangle // 2. while cluster size is < max cluster size @@ -64,95 +69,75 @@ bool GeometryIndexSplitter::split(osg::Geometry& geometry) { // 3. insert wireframe edges corresponding to selected triangles // 4. extract subgeometry - while(remaining_triangles || !source_lines.empty() || !source_points.empty()) { - IndexVector subtriangles, subwireframe, sublines, subpoints; - IndexSet cluster_vertices; + while(triangles.size() || lines.size() || points.size()) { + Cluster cluster(_maxAllowedIndex); + IndexCache cache; + unsigned int candidate = std::numeric_limits::max(); - ++ cluster; + // let's consider that every insert needs the place for a full new primitive for simplicity + while(!cluster.fullOfTriangles() && + (candidate = findCandidate(triangles, cache, graph)) != std::numeric_limits::max()) { + cache.push_back(candidate); + Triangle t = graph.triangle(candidate); + cluster.addTriangle(t.v1(), t.v2(), t.v3()); + } - if(remaining_triangles) { - // find first unmarked triangle (as remaining_triangles > 0 there *must* be at least one) - cache.push_back(findCandidate(clusters)); - setTriangleCluster(graph, cache.back(), cluster, clusters, cluster_vertices, remaining_triangles); + while(!cluster.fullOfLines() && lines.size()) { + Line line = getNext(lines, Line(std::numeric_limits::max(), std::numeric_limits::max())); + cluster.addLine(line._a, line._b); + } - while(remaining_triangles && cluster_vertices.size() < _maxAllowedIndex) { - unsigned int candidate = std::numeric_limits::max(); + while(!cluster.full() && points.size()) { + unsigned int point = getNext(points, std::numeric_limits::max()); + cluster.addPoint(point); + } - for(IndexCache::const_reverse_iterator cached = cache.rbegin() ; cached != cache.rend() ; ++ cached) { - candidate = findCandidate(graph.triangleNeighbors(*cached), clusters); - if(candidate != std::numeric_limits::max()) break; + // update lines/points: if all vertices referenced by a point/line primitive are + // already extracted, let's insert it in the subgeometry and update the set of + // primitives still remaining Lines may e.g. reference one vertex in cluster A and + // the other in cluster B hence need specific care + if(line_primitive) { + for(LineSet::iterator line = lines.begin() ; line != lines.end() ; ) { + if(cluster.contains(line->_a, line->_b)) { + cluster.addLine(line->_a, line->_b); + lines.erase(line ++); } - - if(candidate == std::numeric_limits::max()) { - // do we have room for a triangle having all vertices not in the cluster? - if(!(cluster_vertices.size() + 2 < _maxAllowedIndex)) { - break; - } - - candidate = findCandidate(clusters); - } - - cache.push_back(candidate); - setTriangleCluster(graph, candidate, cluster, clusters, cluster_vertices, remaining_triangles); - } - - // build list of cluster triangles - for(unsigned int triangle = 0 ; triangle < clusters.size() ; ++ triangle) { - if(clusters[triangle] == cluster) { - const Triangle& t = graph.triangle(triangle); - subtriangles.push_back(t.v1()); - subtriangles.push_back(t.v2()); - subtriangles.push_back(t.v3()); - } - } - - // update lines/points: if all vertices referenced by a point/line primitive are - // already extracted, let's insert it in the subgeometry and update the set of - // primitives still remaining Lines may e.g. reference one vertex in cluster A and - // the other in cluster B hence need specific care - if(line_primitive) { - extract_primitives(cluster_vertices, line_primitive, sublines, 2); - for(unsigned int i = 0 ; i < sublines.size() / 2 ; i += 2) { - source_lines.erase(Line(sublines[i], sublines[i + 1])); - } - } - - if(point_primitive) { - extract_primitives(cluster_vertices, point_primitive, subpoints, 1); - for(unsigned int i = 0 ; i < subpoints.size() ; ++ i) { - source_points.erase(subpoints[i]); + else { + ++ line; } } } - // let's consider that every new lines adds 2 vertices for simplicity - while(!source_lines.empty() && cluster_vertices.size() - 1 < _maxAllowedIndex) { - Line line = *source_lines.begin(); - source_lines.erase(source_lines.begin()); - cluster_vertices.insert(line._a); - cluster_vertices.insert(line._b); - sublines.push_back(line._a); - sublines.push_back(line._b); - } - - while(!source_points.empty() && cluster_vertices.size() < _maxAllowedIndex) { - unsigned int point = *source_points.begin(); - source_points.erase(source_points.begin()); - cluster_vertices.insert(point); - subpoints.push_back(point); + if(point_primitive) { + // find all cluster vertices that should also have a point primitive + for(IndexSet::iterator subvertex = cluster.subvertices.begin() ; subvertex != cluster.subvertices.end() ; ++ subvertex) { + unsigned int index = *subvertex; + if(points.find(index) != points.end()) { + cluster.addPoint(index); + points.erase(index); + } + } } // finally extract wireframe (may originate from triangles or lines but necessarily have // to reference vertices that are *all* in the geometry) if(wire_primitive) { - extract_primitives(cluster_vertices, wire_primitive, subwireframe, 2); + for(LineSet::iterator wire = wires.begin() ; wire != wires.end() ; ) { + if(cluster.contains(wire->_a, wire->_b)) { + cluster.addWire(wire->_a, wire->_b); + wires.erase(wire ++); + } + else { + ++ wire; + } + } } _geometryList.push_back(SubGeometry(geometry, - subtriangles, - sublines, - subwireframe, - subpoints).geometry()); + cluster.subtriangles, + cluster.sublines, + cluster.subwireframe, + cluster.subpoints).geometry()); } osg::notify(osg::NOTICE) << "geometry " << &geometry << " " << geometry.getName() @@ -164,60 +149,20 @@ bool GeometryIndexSplitter::split(osg::Geometry& geometry) { } -unsigned int GeometryIndexSplitter::findCandidate(const IndexVector& clusters) { - for(unsigned int i = 0 ; i < clusters.size() ; ++ i) { - if(!clusters[i]) { - return i; - } - } - return std::numeric_limits::max(); -} - - -unsigned int GeometryIndexSplitter::findCandidate(const IndexVector& candidates, const IndexVector& clusters) { - for(IndexVector::const_iterator candidate = candidates.begin() ; candidate != candidates.end() ; ++ candidate) { - if(!clusters[*candidate]) { - return *candidate; - } - } - return std::numeric_limits::max(); -} - - -void GeometryIndexSplitter::setTriangleCluster(const TriangleMeshGraph& graph, - unsigned int triangle, - unsigned int cluster, - IndexVector& clusters, - IndexSet& cluster_vertices, - unsigned int& remaining) { - clusters[triangle] = cluster; - const Triangle& t = graph.triangle(triangle); - cluster_vertices.insert(t.v1()); - cluster_vertices.insert(t.v2()); - cluster_vertices.insert(t.v3()); - remaining --; -} - - -void GeometryIndexSplitter::extract_primitives(const IndexSet& vertices, - const osg::DrawElements* elements, - IndexVector& indices, - unsigned int primitive_size) { - for(unsigned int i = 0 ; i < elements->getNumIndices() ; i += primitive_size) { - bool is_included = true; - for(unsigned int j = 0 ; j < primitive_size ; ++ j) { - if(!vertices.count(elements->index(i + j))) { - is_included = false; - break; - } - } - - if(is_included) { - for(unsigned int j = 0 ; j < primitive_size ; ++ j) { - indices.push_back(elements->index(i + j)); +unsigned int GeometryIndexSplitter::findCandidate(IndexSet& triangles, const IndexCache& cache, const TriangleMeshGraph& graph) { + // look for unclustered neighboring triangles + for(IndexCache::const_reverse_iterator cached = cache.rbegin() ; cached != cache.rend() ; ++ cached) { + IndexVector candidates = graph.triangleNeighbors(*cached); + for(IndexVector::const_iterator candidate = candidates.begin() ; candidate != candidates.end() ; ++ candidate) { + if(triangles.count(*candidate)) { + triangles.erase(*candidate); + return *candidate; } } } + + //fallback on any unclustered triangle + return getNext(triangles, std::numeric_limits::max()); } @@ -276,10 +221,3 @@ void GeometryIndexSplitter::setBufferBoundingBox(T* buffer) const { buffer->setUserValue("ufr", ufr); } } - - -void GeometryIndexSplitter::setValidIndices(std::set& indices, const osg::DrawElements* primitive) const { - for(unsigned int j = 0 ; j < primitive->getNumIndices() ; ++ j) { - indices.insert(primitive->index(j)); - } -} diff --git a/src/osgPlugins/gles/GeometryInspector b/src/osgPlugins/gles/GeometryInspector index beea59194..cbd9a248e 100644 --- a/src/osgPlugins/gles/GeometryInspector +++ b/src/osgPlugins/gles/GeometryInspector @@ -7,6 +7,7 @@ #include #include "GeometryUniqueVisitor" +#include "glesUtil" #include #include @@ -34,8 +35,7 @@ public: osgAnimation::MorphGeometry::MorphTargetList targets = morphGeometry.getMorphTargetList(); unsigned int count = 0; for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target, ++ count) { - osg::ref_ptr geometry = new osg::Geometry(*target->getGeometry()); - geometry->setPrimitiveSetList(morphGeometry.getPrimitiveSetList()); + glesUtil::TargetGeometry geometry(*target, morphGeometry); std::ostringstream oss; if(geometry->getName().empty()) { oss << "/tmp/noname_" << _processed.size(); diff --git a/src/osgPlugins/gles/GeometryMapper b/src/osgPlugins/gles/GeometryMapper new file mode 100644 index 000000000..4bf8674ea --- /dev/null +++ b/src/osgPlugins/gles/GeometryMapper @@ -0,0 +1,31 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) Sketchfab + * + * This application is open source and may be redistributed and/or modified + * freely and without restriction, both in commercial and non commercial + * applications, as long as this copyright notice is maintained. + * + * This application 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. + * +*/ + +#ifndef GEOMETRY_MAPPER +#define GEOMETRY_MAPPER + +#include + +#include +#include + +typedef std::vector< osg::ref_ptr > GeometryList; + +class GeometryMapper { +public: + + // map one geometry to a list of geometries + // to be used with RemapGeometryVisitor + virtual const GeometryList& process(osg::Geometry&) = 0; +}; + +#endif diff --git a/src/osgPlugins/gles/OpenGLESGeometryOptimizer b/src/osgPlugins/gles/OpenGLESGeometryOptimizer index 751a9f2bd..c8bdf58fc 100644 --- a/src/osgPlugins/gles/OpenGLESGeometryOptimizer +++ b/src/osgPlugins/gles/OpenGLESGeometryOptimizer @@ -16,26 +16,32 @@ #include #include //std::max -#include "AnimationCleanerVisitor" -#include "RigAnimationVisitor" +//animation: #include "AABBonBoneVisitor" +#include "AnimationCleanerVisitor" #include "DisableAnimationVisitor" +#include "LimitMorphTargetCount" +#include "MostInfluencedGeometryByBone" +#include "RigAnimationVisitor" +#include "RigAttributesVisitor" + +// geometry: #include "BindPerVertexVisitor" #include "DetachPrimitiveVisitor" #include "DrawArrayVisitor" -#include "GeometrySplitterVisitor" #include "IndexMeshVisitor" #include "PreTransformVisitor" +#include "RemapGeometryVisitor" #include "SmoothNormalVisitor" #include "TangentSpaceVisitor" #include "TriangleStripVisitor" #include "UnIndexMeshVisitor" #include "WireframeVisitor" -#include "AABBonBoneVisitor" -#include "AnimationCleanerVisitor" -#include "MostInfluencedGeometryByBone" -#include "LimitMorphTargetCount" -#include "RigAttributesVisitor" + +#include "GeometryIndexSplitter" +#include "GeometryCleaner" + +// debug #include "GeometryInspector" @@ -165,6 +171,12 @@ protected: node->accept(indexer); } + void makeCleanGeometry(osg::Node* node) { + GeometryCleaner cleaner; + RemapGeometryVisitor remapper(cleaner, _exportNonGeometryDrawables); + node->accept(remapper); + } + void makeSmoothNormal(osg::Node* node) { SmoothNormalVisitor smoother(osg::PI / 4.f, true); node->accept(smoother); @@ -176,8 +188,9 @@ protected: } void makeSplit(osg::Node* node) { - GeometrySplitterVisitor splitter(_maxIndexValue, _exportNonGeometryDrawables ); - node->accept(splitter); + GeometryIndexSplitter splitter(_maxIndexValue); + RemapGeometryVisitor remapper(splitter, _exportNonGeometryDrawables); + node->accept(remapper); } void makeTriStrip(osg::Node* node) { diff --git a/src/osgPlugins/gles/OpenGLESGeometryOptimizer.cpp b/src/osgPlugins/gles/OpenGLESGeometryOptimizer.cpp index 5c10f69fb..82b0a2ca1 100644 --- a/src/osgPlugins/gles/OpenGLESGeometryOptimizer.cpp +++ b/src/osgPlugins/gles/OpenGLESGeometryOptimizer.cpp @@ -26,6 +26,12 @@ osg::Node* OpenGLESGeometryOptimizer::optimize(osg::Node& node) { // index (merge exact duplicates + uses simple triangles & lines i.e. no strip/fan/loop) makeIndexMesh(model.get()); + // clean (remove degenerated data) + std::string authoringTool; + if(model->getUserValue("authoring_tool", authoringTool) && authoringTool == "Tilt Brush") { + makeCleanGeometry(model.get()); + } + // smooth vertex normals (if geometry has no normal compute smooth normals) makeSmoothNormal(model.get()); diff --git a/src/osgPlugins/gles/RemapGeometryVisitor b/src/osgPlugins/gles/RemapGeometryVisitor new file mode 100644 index 000000000..0a803b160 --- /dev/null +++ b/src/osgPlugins/gles/RemapGeometryVisitor @@ -0,0 +1,51 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) Sketchfab + * + * This application is open source and may be redistributed and/or modified + * freely and without restriction, both in commercial and non commercial + * applications, as long as this copyright notice is maintained. + * + * This application 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. + * +*/ + +#ifndef REMAP_GEOMETRY_VISITOR +#define REMAP_GEOMETRY_VISITOR + +#include + +#include +#include +#include + +#include "GeometryUniqueVisitor" +#include "GeometryMapper" + + +class RemapGeometryVisitor : public GeometryUniqueVisitor { +public: + typedef std::vector< osg::ref_ptr > GeometryList; + typedef std::vector< osg::ref_ptr > DrawableList; + typedef std::map GeometryMap; + + RemapGeometryVisitor(GeometryMapper& mapper, bool exportNonGeometryDrawables=false): + GeometryUniqueVisitor("RemapGeometryVisitor"), + _mapper(mapper), + _exportNonGeometryDrawables(exportNonGeometryDrawables) + {} + + void apply(osg::Geode&); + void process(osg::Geometry&); + +protected: + bool isProcessed(osg::Geometry*); + void setProcessed(osg::Geometry*, const GeometryList&); + +protected: + GeometryMapper& _mapper; + std::map _remap; + bool _exportNonGeometryDrawables; +}; + +#endif diff --git a/src/osgPlugins/gles/RemapGeometryVisitor.cpp b/src/osgPlugins/gles/RemapGeometryVisitor.cpp new file mode 100644 index 000000000..e389394a0 --- /dev/null +++ b/src/osgPlugins/gles/RemapGeometryVisitor.cpp @@ -0,0 +1,72 @@ +#include "RemapGeometryVisitor" +#include "glesUtil" + + +void RemapGeometryVisitor::apply(osg::Geode& geode) { + GeometryUniqueVisitor::apply(geode); + GeometryList remappedGeometries; + DrawableList nonGeometryDrawables; + + for(unsigned int i = 0 ; i < geode.getNumDrawables() ; ++ i) { + osg::Geometry* geometry = geode.getDrawable(i)->asGeometry(); + if(geometry) { + if(osgAnimation::RigGeometry* rigGeometry = dynamic_cast(geometry)) { + GeometryMap::iterator lookup = _remap.find(rigGeometry->getSourceGeometry()); + if(lookup != _remap.end() && !lookup->second.empty()) { + + // convert now static rigGeometry into simple Geometry + for(GeometryList::iterator mapped = lookup->second.begin() ; mapped != lookup->second.end() ; ++ mapped) { + if(glesUtil::hasPositiveWeights(mapped->get())) { + osgAnimation::RigGeometry* mappedRig = new osgAnimation::RigGeometry(*rigGeometry); + mappedRig->setSourceGeometry(mapped->get()); + remappedGeometries.push_back(mappedRig); + } + else { + remappedGeometries.push_back(mapped->get()); + } + } + + } + } + else { + GeometryMap::iterator lookup = _remap.find(geometry); + if(lookup != _remap.end() && !lookup->second.empty()) { + remappedGeometries.insert(remappedGeometries.end(), lookup->second.begin(), lookup->second.end()); + } + } + } + else { + nonGeometryDrawables.push_back(geode.getDrawable(i)); + } + } + + // remove all drawables + geode.removeDrawables(0, geode.getNumDrawables()); + // insert splitted geometries + for(unsigned int i = 0 ; i < remappedGeometries.size() ; ++ i) { + geode.addDrawable(remappedGeometries[i].get()); + } + + if(_exportNonGeometryDrawables) { + // insert other drawables (e.g. osgText) + for(unsigned int i = 0 ; i < nonGeometryDrawables.size() ; ++ i) { + geode.addDrawable(nonGeometryDrawables[i].get()); + } + } +} + + +void RemapGeometryVisitor::process(osg::Geometry& geometry) { + const GeometryList& mapped = _mapper.process(geometry); + setProcessed(&geometry, mapped); +} + + +bool RemapGeometryVisitor::isProcessed(osg::Geometry* node) { + return _remap.find(node) != _remap.end(); +} + + +void RemapGeometryVisitor::setProcessed(osg::Geometry* node, const GeometryList& list) { + _remap.insert(std::pair(node, GeometryList(list))); +} diff --git a/src/osgPlugins/gles/SmoothNormalVisitor b/src/osgPlugins/gles/SmoothNormalVisitor index 086c28239..50596c2a6 100644 --- a/src/osgPlugins/gles/SmoothNormalVisitor +++ b/src/osgPlugins/gles/SmoothNormalVisitor @@ -5,6 +5,7 @@ #include "GeometryUniqueVisitor" #include "TriangleMeshSmoother" +#include "glesUtil" class SmoothNormalVisitor : public GeometryUniqueVisitor { @@ -25,20 +26,41 @@ public: } void process(osgAnimation::MorphGeometry& morphGeometry) { - TriangleMeshSmoother(morphGeometry, 0, true, TriangleMeshSmoother::smooth_all); - osgAnimation::MorphGeometry::MorphTargetList targets = morphGeometry.getMorphTargetList(); - for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target) { - // check normal orientation using the same primitives as parent geometry - osg::Geometry::PrimitiveSetList& primitives = target->getGeometry()->getPrimitiveSetList(); - target->getGeometry()->setPrimitiveSetList(morphGeometry.getPrimitiveSetList()); + bool needSmoothing = needMorphGeometrySmoothing(morphGeometry); - TriangleMeshSmoother(*target->getGeometry(), 0, true, TriangleMeshSmoother::smooth_all); + if(needSmoothing) { + TriangleMeshSmoother(morphGeometry, 0, true, TriangleMeshSmoother::smooth_all); - target->getGeometry()->setPrimitiveSetList(primitives); + osgAnimation::MorphGeometry::MorphTargetList targets = morphGeometry.getMorphTargetList(); + for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target) { + // check normal orientation using the same primitives as parent geometry + glesUtil::TargetGeometry geometry(*target, morphGeometry); + if(geometry && !geometry->getNormalArray()) { + TriangleMeshSmoother(*geometry, 0, true, TriangleMeshSmoother::smooth_all); + } + } } } protected: + bool needMorphGeometrySmoothing(osgAnimation::MorphGeometry& morphGeometry) { + if(!morphGeometry.getNormalArray()) { + return true; + } + + osgAnimation::MorphGeometry::MorphTargetList targets = morphGeometry.getMorphTargetList(); + + for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target) { + osg::Geometry* geometry = target->getGeometry(); + if(geometry && !geometry->getNormalArray()) { + return true; + } + } + + return false; + } + + float _creaseAngle; bool _comparePosition; }; diff --git a/src/osgPlugins/gles/TangentSpaceVisitor.cpp b/src/osgPlugins/gles/TangentSpaceVisitor.cpp index 874d85657..aa7264a63 100644 --- a/src/osgPlugins/gles/TangentSpaceVisitor.cpp +++ b/src/osgPlugins/gles/TangentSpaceVisitor.cpp @@ -1,26 +1,13 @@ #include "TangentSpaceVisitor" - +#include "glesUtil" void TangentSpaceVisitor::process(osgAnimation::MorphGeometry& morphGeometry) { process(static_cast(morphGeometry)); osgAnimation::MorphGeometry::MorphTargetList& targets = morphGeometry.getMorphTargetList(); for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target) { - osg::Geometry* geometry = target->getGeometry(); - bool useParentMorphTexCoord = geometry->getTexCoordArrayList().empty(); - - if(useParentMorphTexCoord) { - // tangent space require tex coords; in case a target has no tex coords, we try to - // bind the parent geometry tex coords - geometry->setTexCoordArrayList(morphGeometry.getTexCoordArrayList()); - } - + glesUtil::TargetGeometry geometry(*target, morphGeometry); process(*geometry); - - if(useParentMorphTexCoord) { - // drop parent tex coords after tangent space computation - geometry->setTexCoordArrayList(osg::Geometry::ArrayList()); - } } } @@ -36,6 +23,9 @@ void TangentSpaceVisitor::process(osg::Geometry& geometry) { geometry.getVertexAttribArray(tangentIndex)->setUserValue("tangent", true); return; } + else { + OSG_WARN << "Anomaly: [TangentSpaceVisitor] Missing tangent array at specificied index." << std::endl; + } } if (!geometry.getTexCoordArray(_textureUnit)){ @@ -56,21 +46,6 @@ void TangentSpaceVisitor::process(osg::Geometry& geometry) { osg::ref_ptr generator = new osgUtil::TangentSpaceGenerator; generator->generate(&geometry, _textureUnit); - // keep original normal array - if (!geometry.getNormalArray()) { - if (generator->getNormalArray()) { - osg::Vec3Array* vec3Normals = new osg::Vec3Array(); - osg::Vec4Array* vec4Normals = generator->getNormalArray(); - for (unsigned int i = 0; i < vec4Normals->size(); i++) { - osg::Vec3 n = osg::Vec3((*vec4Normals)[i][0], - (*vec4Normals)[i][1], - (*vec4Normals)[i][2]); - vec3Normals->push_back(n); - } - geometry.setNormalArray(vec3Normals, osg::Array::BIND_PER_VERTEX); - } - } - if (generator->getTangentArray()) { osg::Vec4Array* normal = generator->getNormalArray(); osg::Vec4Array* tangent = generator->getTangentArray(); diff --git a/src/osgPlugins/gles/TriangleMeshSmoother.cpp b/src/osgPlugins/gles/TriangleMeshSmoother.cpp index 7215544f7..536844758 100644 --- a/src/osgPlugins/gles/TriangleMeshSmoother.cpp +++ b/src/osgPlugins/gles/TriangleMeshSmoother.cpp @@ -244,14 +244,16 @@ void TriangleMeshSmoother::updateGeometryPrimitives() { } } - osg::DrawElementsUInt* triangles = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES); - for(unsigned int i = 0 ; i < _graph->getNumTriangles() ; ++ i) { - const Triangle& triangle = _graph->triangle(i); - triangles->push_back(triangle.v1()); - triangles->push_back(triangle.v2()); - triangles->push_back(triangle.v3()); + if(_graph->getNumTriangles()) { + osg::DrawElementsUInt* triangles = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES); + for(unsigned int i = 0 ; i < _graph->getNumTriangles() ; ++ i) { + const Triangle& triangle = _graph->triangle(i); + triangles->push_back(triangle.v1()); + triangles->push_back(triangle.v2()); + triangles->push_back(triangle.v3()); + } + primitives.push_back(triangles); } - primitives.push_back(triangles); _geometry.setPrimitiveSetList(primitives); } diff --git a/src/osgPlugins/gles/glesUtil b/src/osgPlugins/gles/glesUtil index bf6faffef..746232bc0 100644 --- a/src/osgPlugins/gles/glesUtil +++ b/src/osgPlugins/gles/glesUtil @@ -25,7 +25,7 @@ namespace glesUtil { using namespace std; using namespace osg; typedef std::vector IndexList; - + typedef osgAnimation::MorphGeometry::MorphTargetList MorphTargetList; inline bool hasPositiveWeights(const osg::Geometry* geometry) { const osg::Vec4Array* weights = 0; @@ -53,6 +53,52 @@ namespace glesUtil { } + class TargetGeometry { + public: + TargetGeometry(osgAnimation::MorphGeometry::MorphTarget& target, + osgAnimation::MorphGeometry& morph): + _geometry(0) + { + _geometry = target.getGeometry(); + _geometry->setPrimitiveSetList(morph.getPrimitiveSetList()); + + _hasTexCoord = _geometry->getTexCoordArrayList().size(); + if(!_hasTexCoord) { + _geometry->setTexCoordArrayList(morph.getTexCoordArrayList()); + } + } + + osg::Geometry* operator->() { + return _geometry; + } + + operator osg::Geometry*() { + return _geometry; + } + + operator osg::Geometry&() { + return *_geometry; + } + + operator bool() { + return _geometry != 0; + } + + ~TargetGeometry() { + if(!_hasTexCoord) { + // drop parent tex coords after tangent space computation + _geometry->setTexCoordArrayList(osg::Geometry::ArrayList()); + } + _geometry->setPrimitiveSetList(osg::Geometry::PrimitiveSetList()); + } + + protected: + osg::Geometry* _geometry; + bool _hasTexCoord; + }; + + + // A helper class that gathers up all the attribute arrays of an // osg::Geometry object that are BIND_PER_VERTEX and runs an // ArrayVisitor on them. @@ -61,6 +107,20 @@ namespace glesUtil { typedef std::vector ArrayList; GeometryArrayGatherer(osg::Geometry& geometry) { + addGeometryVertexAttributes(geometry); + _targetAttributesIndex = _arrayList.size(); + + if(osgAnimation::MorphGeometry* morphGeometry = dynamic_cast(&geometry)) { + MorphTargetList targets = morphGeometry->getMorphTargetList(); + for (MorphTargetList::iterator iterator = targets.begin(); iterator != targets.end(); ++ iterator) { + if(iterator->getGeometry()) { + addTargetVertexAttributes(*iterator->getGeometry()); + } + } + } + } + + void addGeometryVertexAttributes(osg::Geometry& geometry) { add(geometry.getVertexArray()); add(geometry.getNormalArray()); add(geometry.getColorArray()); @@ -74,6 +134,10 @@ namespace glesUtil { } } + void addTargetVertexAttributes(osg::Geometry& target) { + add(target.getVertexArray()); + } + void add(osg::Array* array) { if (array) { _arrayList.push_back(array); @@ -81,12 +145,16 @@ namespace glesUtil { } void accept(osg::ArrayVisitor& av) { - for(ArrayList::iterator itr = _arrayList.begin() ; itr != _arrayList.end(); ++ itr) { + unsigned int geometryAttributesIndex = 0; + for(ArrayList::iterator itr = _arrayList.begin() ; + geometryAttributesIndex < _targetAttributesIndex && itr != _arrayList.end(); + ++ geometryAttributesIndex, ++ itr) { (*itr)->accept(av); } } ArrayList _arrayList; + unsigned int _targetAttributesIndex; }; @@ -349,8 +417,8 @@ namespace glesUtil { void remapTargetVertices(Remapper remapper, Geometry& geom) { if(osgAnimation::MorphGeometry *morphGeometry = dynamic_cast(&geom)) { - osgAnimation::MorphGeometry::MorphTargetList targetList = morphGeometry->getMorphTargetList(); - for (osgAnimation::MorphGeometry::MorphTargetList::iterator ti = targetList.begin(); ti != targetList.end(); ++ti) { + MorphTargetList targetList = morphGeometry->getMorphTargetList(); + for (MorphTargetList::iterator ti = targetList.begin(); ti != targetList.end(); ++ti) { osgAnimation::MorphGeometry::MorphTarget *morphTarget = &(*ti); osg::Geometry *target = morphTarget->getGeometry(); GeometryArrayGatherer gatherer(*target); From c84b667fa5dc051c73f58d1f84b9b13ecac4a5a7 Mon Sep 17 00:00:00 2001 From: Marc Helbling Date: Fri, 20 Jan 2017 15:09:26 +0100 Subject: [PATCH 05/35] Updates osgjs from sketchfab * updates uservalue serialization (avoid creating multie UserDataContainer for a same object) * removes vec4ubarray specific serialization (serialization should not enforce the previous color transformation) --- src/osgPlugins/osgjs/Animation.cpp | 2 +- src/osgPlugins/osgjs/ReaderWriterJSON.cpp | 2 +- src/osgPlugins/osgjs/WriteVisitor | 34 +++- src/osgPlugins/osgjs/WriteVisitor.cpp | 199 ++++++++++++---------- 4 files changed, 144 insertions(+), 93 deletions(-) diff --git a/src/osgPlugins/osgjs/Animation.cpp b/src/osgPlugins/osgjs/Animation.cpp index 8c384b085..40af1ed47 100644 --- a/src/osgPlugins/osgjs/Animation.cpp +++ b/src/osgPlugins/osgjs/Animation.cpp @@ -45,7 +45,7 @@ bool addJSONChannel(const std::string& channelType, T* channel, bool packByCoord osg::ref_ptr json = new JSONObject; std::string jsonType = channelType + (packByCoords ? "Packed" : ""); - translateObject(json.get(), channel); + writer->translateObject(json.get(), channel); json->getMaps()["Name"] = new JSONValue(channel->getName()); json->getMaps()["TargetName"] = new JSONValue(channel->getTargetName()); diff --git a/src/osgPlugins/osgjs/ReaderWriterJSON.cpp b/src/osgPlugins/osgjs/ReaderWriterJSON.cpp index cdf929d34..c22abb172 100644 --- a/src/osgPlugins/osgjs/ReaderWriterJSON.cpp +++ b/src/osgPlugins/osgjs/ReaderWriterJSON.cpp @@ -125,7 +125,7 @@ public: writer.setBaseName(basename); writer.useExternalBinaryArray(options.useExternalBinaryArray); writer.mergeAllBinaryFiles(options.mergeAllBinaryFiles); - writer.inlineImages(options.inlineImages); + writer.setInlineImages(options.inlineImages); writer.setMaxTextureDimension(options.resizeTextureUpToPowerOf2); writer.setVarint(options.varint); writer.setBaseLodURL(options.baseLodURL); diff --git a/src/osgPlugins/osgjs/WriteVisitor b/src/osgPlugins/osgjs/WriteVisitor index 7f92ca5b7..7cef22551 100644 --- a/src/osgPlugins/osgjs/WriteVisitor +++ b/src/osgPlugins/osgjs/WriteVisitor @@ -29,8 +29,10 @@ #include #include +#include + #include -# + #include #include #include @@ -47,8 +49,9 @@ #define WRITER_VERSION 9 +class WriteVisitor; + osg::Array* getTangentSpaceArray(osg::Geometry& geometry); -void translateObject(JSONObject* json, osg::Object* osg); void getStringifiedUserValue(osg::Object* o, std::string& name, std::string& value); template bool getStringifiedUserValue(osg::Object* o, std::string& name, std::string& value); @@ -59,8 +62,9 @@ class WriteVisitor : public osg::NodeVisitor public: typedef std::vector > StateSetStack; typedef std::pair KeyValue; + typedef std::map, osg::ref_ptr > OsgObjectToJSONObject; - std::map, osg::ref_ptr > _maps; + OsgObjectToJSONObject _maps; std::vector > _parents; osg::ref_ptr _root; StateSetStack _stateset; @@ -74,6 +78,20 @@ public: std::map _specificBuffers; std::map _buffers; + JSONObject* getJSON(osg::Object* object) const { + OsgObjectToJSONObject::const_iterator lookup = _maps.find(object); + if(lookup != _maps.end()) { + return lookup->second->getShadowObject(); + } + return 0; + } + + void setJSON(osg::Object* object, JSONObject* json) { + if(json) { + _maps[object] = json; + } + } + std::ofstream& getBufferFile(const std::string& name) { if(_buffers.find(name) == _buffers.end()) { _buffers[name] = new std::ofstream(name.c_str(), std::ios::binary); @@ -238,6 +256,10 @@ public: return getBinaryFilename(flag); } + void translateObject(JSONObject* json, osg::Object* osg); + JSONObject* createJSONOsgSimUserData(osgSim::ShapeAttributeList*); + JSONObject* createJSONUserDataContainer(osg::UserDataContainer*); + JSONObject* createJSONPagedLOD(osg::PagedLOD* plod); JSONObject* createJSONStateSet(osg::StateSet* ss); JSONObject* createJSONTexture(osg::Texture* sa); @@ -650,10 +672,14 @@ public: _parents.pop_back(); } + std::string getBaseName() const { return _baseName; } + bool getInlineImages() const { return _inlineImages; } + int getMaxTextureDimension() const { return _maxTextureDimension; } + void setBaseName(const std::string& basename) { _baseName = basename; } void useExternalBinaryArray(bool use) { _useExternalBinaryArray = use; } void mergeAllBinaryFiles(bool use) { _mergeAllBinaryFiles = use; } - void inlineImages(bool use) { _inlineImages = use; } + void setInlineImages(bool use) { _inlineImages = use; } void setVarint(bool use) { _varint = use; } void setMaxTextureDimension(int use) { _maxTextureDimension = use; } void addSpecificBuffer(const std::string& bufferFlag) { diff --git a/src/osgPlugins/osgjs/WriteVisitor.cpp b/src/osgPlugins/osgjs/WriteVisitor.cpp index d5bb0b0d7..e062f8bde 100644 --- a/src/osgPlugins/osgjs/WriteVisitor.cpp +++ b/src/osgPlugins/osgjs/WriteVisitor.cpp @@ -11,8 +11,6 @@ #include #include -#include - #include #include @@ -76,82 +74,6 @@ osg::ref_ptr buildRigBoneMap(osgAnimation::RigGeometry& rigGeometry) } -void translateObject(JSONObject* json, osg::Object* osg) -{ - if (!osg->getName().empty()) { - json->getMaps()["Name"] = new JSONValue(osg->getName()); - } - - osgSim::ShapeAttributeList* osgSim_userdata = dynamic_cast(osg->getUserData()); - if (osgSim_userdata) { - JSONObject* jsonUDC = new JSONObject(); - jsonUDC->addUniqueID(); - - JSONArray* jsonUDCArray = new JSONArray(); - jsonUDC->getMaps()["Values"] = jsonUDCArray; - for (unsigned int i = 0; i < osgSim_userdata->size(); i++) { - const osgSim::ShapeAttribute& attr = (*osgSim_userdata)[i]; - JSONObject* jsonEntry = new JSONObject(); - jsonEntry->getMaps()["Name"] = new JSONValue(attr.getName()); - osg::ref_ptr > value; - switch(attr.getType()) { - case osgSim::ShapeAttribute::INTEGER: - { - std::stringstream ss; - ss << attr.getInt(); - value = new JSONValue(ss.str()); - } - break; - case osgSim::ShapeAttribute::DOUBLE: - { - std::stringstream ss; - ss << attr.getDouble(); - value = new JSONValue(ss.str()); - } - break; - case osgSim::ShapeAttribute::STRING: - { - std::stringstream ss; - ss << attr.getString(); - value = new JSONValue(ss.str()); - } - break; - case osgSim::ShapeAttribute::UNKNOWN: - default: - break; - } - jsonEntry->getMaps()["Value"] = value; - jsonUDCArray->getArray().push_back(jsonEntry); - } - json->getMaps()["UserDataContainer"] = jsonUDC; - - } else if (osg->getUserDataContainer()) { - JSONObject* jsonUDC = new JSONObject(); - jsonUDC->addUniqueID(); - - if (!osg->getUserDataContainer()->getName().empty()) { - jsonUDC->getMaps()["Name"] = new JSONValue(osg->getUserDataContainer()->getName()); - } - JSONArray* jsonUDCArray = new JSONArray(); - jsonUDC->getMaps()["Values"] = jsonUDCArray; - for (unsigned int i = 0; i < osg->getUserDataContainer()->getNumUserObjects(); i++) { - osg::Object* o = osg->getUserDataContainer()->getUserObject(i); - std::string name, value; - getStringifiedUserValue(o, name, value); - if(!name.empty() && !value.empty()) - { - JSONObject* jsonEntry = new JSONObject(); - jsonEntry->getMaps()["Name"] = new JSONValue(name); - jsonEntry->getMaps()["Value"] = new JSONValue(value); - jsonUDCArray->getArray().push_back(jsonEntry); - } - - } - json->getMaps()["UserDataContainer"] = jsonUDC; - } -} - - void getStringifiedUserValue(osg::Object* o, std::string& name, std::string& value) { if(getStringifiedUserValue(o, name, value)) return; if(getStringifiedUserValue(o, name, value)) return; @@ -352,6 +274,108 @@ JSONObject* createImage(osg::Image* image, bool inlineImages, int maxTextureDime } + +JSONObject* WriteVisitor::createJSONOsgSimUserData(osgSim::ShapeAttributeList* osgSimData) { + JSONObject* jsonUDC = new JSONObject(); + jsonUDC->addUniqueID(); + + JSONArray* jsonUDCArray = new JSONArray(); + jsonUDC->getMaps()["Values"] = jsonUDCArray; + for (unsigned int i = 0; i < osgSimData->size(); i++) { + const osgSim::ShapeAttribute& attr = (*osgSimData)[i]; + JSONObject* jsonEntry = new JSONObject(); + jsonEntry->getMaps()["Name"] = new JSONValue(attr.getName()); + osg::ref_ptr > value; + switch(attr.getType()) { + case osgSim::ShapeAttribute::INTEGER: + { + std::stringstream ss; + ss << attr.getInt(); + value = new JSONValue(ss.str()); + } + break; + case osgSim::ShapeAttribute::DOUBLE: + { + std::stringstream ss; + ss << attr.getDouble(); + value = new JSONValue(ss.str()); + } + break; + case osgSim::ShapeAttribute::STRING: + { + std::stringstream ss; + ss << attr.getString(); + value = new JSONValue(ss.str()); + } + break; + case osgSim::ShapeAttribute::UNKNOWN: + default: + break; + } + jsonEntry->getMaps()["Value"] = value; + jsonUDCArray->getArray().push_back(jsonEntry); + } + return jsonUDC; +} + + +JSONObject* WriteVisitor::createJSONUserDataContainer(osg::UserDataContainer* container) { + JSONObject* jsonUDC = new JSONObject(); + jsonUDC->addUniqueID(); + + if (!container->getName().empty()) { + jsonUDC->getMaps()["Name"] = new JSONValue(container->getName()); + } + JSONArray* jsonUDCArray = new JSONArray(); + jsonUDC->getMaps()["Values"] = jsonUDCArray; + for (unsigned int i = 0; i < container->getNumUserObjects(); i++) { + osg::Object* o = container->getUserObject(i); + std::string name, value; + getStringifiedUserValue(o, name, value); + if(!name.empty() && !value.empty()) + { + JSONObject* jsonEntry = new JSONObject(); + jsonEntry->getMaps()["Name"] = new JSONValue(name); + jsonEntry->getMaps()["Value"] = new JSONValue(value); + jsonUDCArray->getArray().push_back(jsonEntry); + } + } + return jsonUDC; +} + + +void WriteVisitor::translateObject(JSONObject* json, osg::Object* osg) +{ + if (!osg->getName().empty()) { + json->getMaps()["Name"] = new JSONValue(osg->getName()); + } + + JSONObject* jsonUDC = 0; + + osgSim::ShapeAttributeList* osgSimData = dynamic_cast(osg->getUserData()); + if (osgSimData) { + jsonUDC = this->getJSON(osgSimData); + if(!jsonUDC) { + jsonUDC = createJSONOsgSimUserData(osgSimData); + this->setJSON(osgSimData, jsonUDC); + } + } + else if (osg::UserDataContainer* container = osg->getUserDataContainer()) { + jsonUDC = this->getJSON(container); + if(!jsonUDC) { + jsonUDC = createJSONUserDataContainer(container); + this->setJSON(container, jsonUDC); + } + } + + if(jsonUDC) { + json->getMaps()["UserDataContainer"] = jsonUDC; + } +} + + + + JSONObject* WriteVisitor::createJSONBufferArray(osg::Array* array, osg::Object* parent) { if (_maps.find(array) != _maps.end()) @@ -765,12 +789,16 @@ JSONObject* WriteVisitor::createJSONLight(osg::Light* light) return jsonLight.release(); } -template JSONObject* createImageFromTexture(osg::Texture* texture, JSONObject* jsonTexture, bool inlineImages, - int maxTextureDimension, const std::string &baseName = "") +template +JSONObject* createImageFromTexture(osg::Texture* texture, JSONObject* jsonTexture, WriteVisitor* writer) { + bool inlineImages = writer->getInlineImages(); + int maxTextureDimension = writer->getMaxTextureDimension(); + const std::string baseName = writer->getBaseName(); + T* text = dynamic_cast( texture); if (text) { - translateObject(jsonTexture,text); + writer->translateObject(jsonTexture,text); JSONObject* image = createImage(text->getImage(), inlineImages, maxTextureDimension, baseName); if (image) jsonTexture->getMaps()["File"] = image; @@ -902,24 +930,21 @@ JSONObject* WriteVisitor::createJSONTexture(osg::Texture* texture) { - JSONObject* obj = createImageFromTexture(texture, jsonTexture.get(), this->_inlineImages, - this->_maxTextureDimension, this->_baseName); + JSONObject* obj = createImageFromTexture(texture, jsonTexture.get(), this); if (obj) { return obj; } } { - JSONObject* obj = createImageFromTexture(texture, jsonTexture.get(), this->_inlineImages, - this->_maxTextureDimension, this->_baseName); + JSONObject* obj = createImageFromTexture(texture, jsonTexture.get(), this); if (obj) { return obj; } } { - JSONObject* obj = createImageFromTexture(texture, jsonTexture.get(), this->_inlineImages, - this->_maxTextureDimension, this->_baseName); + JSONObject* obj = createImageFromTexture(texture, jsonTexture.get(), this); if (obj) { return obj; } From ed596c333574f61f765bb8afbabd379d5d733220 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 20 Jan 2017 17:06:55 +0000 Subject: [PATCH 06/35] Quietened down some verbose debug messages --- src/osg/BufferObject.cpp | 6 +++--- src/osg/StateAttribute.cpp | 4 ++-- src/osgPlugins/png/ReaderWriterPNG.cpp | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/osg/BufferObject.cpp b/src/osg/BufferObject.cpp index df36f123b..cad59303f 100644 --- a/src/osg/BufferObject.cpp +++ b/src/osg/BufferObject.cpp @@ -1104,7 +1104,7 @@ void BufferObject::resizeGLObjectBuffers(unsigned int maxSize) void BufferObject::releaseGLObjects(State* state) const { - OSG_INFO<<"BufferObject::releaseGLObjects("<getContextID(); @@ -1260,7 +1260,7 @@ void BufferData::resizeGLObjectBuffers(unsigned int maxSize) void BufferData::releaseGLObjects(State* state) const { - OSG_INFO<<"BufferData::releaseGLObjects("<releaseGLObjects(state); @@ -1369,7 +1369,7 @@ PixelBufferObject::PixelBufferObject(osg::Image* image): setTarget(GL_PIXEL_UNPACK_BUFFER_ARB); setUsage(GL_STREAM_DRAW_ARB); - OSG_INFO<<"Constructing PixelBufferObject for image="<setNumChildrenRequiringUpdateTraversal((*itr)->getNumChildrenRequiringUpdateTraversal()+delta); } diff --git a/src/osgPlugins/png/ReaderWriterPNG.cpp b/src/osgPlugins/png/ReaderWriterPNG.cpp index 9e06425af..8190a4b4d 100644 --- a/src/osgPlugins/png/ReaderWriterPNG.cpp +++ b/src/osgPlugins/png/ReaderWriterPNG.cpp @@ -210,10 +210,10 @@ class ReaderWriterPNG : public osgDB::ReaderWriter pinfo->Depth = depth; } - OSG_INFO<<"width="<8 && getCpuByteOrder()==osg::LittleEndian) From e5b493289de666c94a80dda70c4124c839782eb2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 20 Jan 2017 17:24:49 +0000 Subject: [PATCH 07/35] Quitened down debug messages --- src/osg/VertexArrayState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osg/VertexArrayState.cpp b/src/osg/VertexArrayState.cpp index 23b847f4f..9f474fc0f 100644 --- a/src/osg/VertexArrayState.cpp +++ b/src/osg/VertexArrayState.cpp @@ -18,7 +18,7 @@ using namespace osg; #if 1 -#define VAS_NOTICE OSG_INFO +#define VAS_NOTICE OSG_DEBUG #else #define VAS_NOTICE OSG_NOTICE #endif From 33f7500a593180c258e30752c055d6ae94836c18 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 20 Jan 2017 17:31:09 +0000 Subject: [PATCH 08/35] Quitened down verbose debug messages --- src/osg/BufferObject.cpp | 2 +- src/osg/StateAttribute.cpp | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/osg/BufferObject.cpp b/src/osg/BufferObject.cpp index cad59303f..9e2199911 100644 --- a/src/osg/BufferObject.cpp +++ b/src/osg/BufferObject.cpp @@ -246,7 +246,7 @@ void GLBufferObject::compileBuffer() void GLBufferObject::deleteGLObject() { - OSG_INFO<<"GLBufferObject::deleteGLObject() "<<_glObjectID<glDeleteBuffers(1, &_glObjectID); diff --git a/src/osg/StateAttribute.cpp b/src/osg/StateAttribute.cpp index 0dc99d5a6..e239fb3aa 100644 --- a/src/osg/StateAttribute.cpp +++ b/src/osg/StateAttribute.cpp @@ -44,7 +44,7 @@ void StateAttribute::removeParent(osg::StateSet* object) void StateAttribute::setUpdateCallback(StateAttributeCallback* uc) { - OSG_INFO<<"StateAttribute::Setting Update callbacks"<setNumChildrenRequiringUpdateTraversal((*itr)->getNumChildrenRequiringUpdateTraversal()+delta); } } @@ -71,7 +67,7 @@ void StateAttribute::setUpdateCallback(StateAttributeCallback* uc) void StateAttribute::setEventCallback(StateAttributeCallback* ec) { - OSG_INFO<<"StateAttribute::Setting Event callbacks"< Date: Fri, 20 Jan 2017 20:57:03 +0100 Subject: [PATCH 09/35] RemoveEmptyNodesVisitor: remove redundant code for Geode handling --- include/osgUtil/Optimizer | 1 - src/osgUtil/Optimizer.cpp | 17 ----------------- 2 files changed, 18 deletions(-) diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index 75328b933..4113f4589 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -360,7 +360,6 @@ class OSGUTIL_EXPORT Optimizer RemoveEmptyNodesVisitor(Optimizer* optimizer=0): BaseOptimizerVisitor(optimizer, REMOVE_REDUNDANT_NODES) {} - virtual void apply(osg::Geode& geode); virtual void apply(osg::Group& group); void removeEmptyNodes(); diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 997ac55f2..31854ebbf 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -1329,23 +1329,6 @@ bool Optimizer::CombineStaticTransformsVisitor::removeTransforms(osg::Node* node // RemoveEmptyNodes. //////////////////////////////////////////////////////////////////////////// -void Optimizer::RemoveEmptyNodesVisitor::apply(osg::Geode& geode) -{ - for(int i=geode.getNumDrawables()-1;i>=0;--i) - { - osg::Geometry* geom = geode.getDrawable(i)->asGeometry(); - if (geom && geom->empty() && isOperationPermissibleForObject(geom)) - { - geode.removeDrawables(i,1); - } - } - - if (geode.getNumParents()>0) - { - if (geode.getNumDrawables()==0 && isOperationPermissibleForObject(&geode)) _redundantNodeList.insert(&geode); - } -} - void Optimizer::RemoveEmptyNodesVisitor::apply(osg::Group& group) { if (group.getNumParents()>0) From 4457df9a8ae60d6b85a0808da27e0c441fa75d0c Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 20 Jan 2017 20:58:05 +0100 Subject: [PATCH 10/35] RemoveEmptyNodesVisitor: add missing isOperationPermissible check --- src/osgUtil/Optimizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 31854ebbf..4f442d4cd 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -1372,7 +1372,7 @@ void Optimizer::RemoveEmptyNodesVisitor::removeEmptyNodes() strcmp(parent->className(),"MultiSwitch")!=0) { parent->removeChild(nodeToRemove.get()); - if (parent->getNumChildren()==0) newEmptyGroups.insert(*pitr); + if (parent->getNumChildren()==0 && isOperationPermissibleForObject(parent)) newEmptyGroups.insert(parent); } } } From dc2689f7797d2477f4c8b4a2d5404ef83d4a1ba4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 20 Jan 2017 21:08:02 +0100 Subject: [PATCH 11/35] TextureVisitor: remove redundant code for Geode handling --- include/osgUtil/Optimizer | 1 - src/osgUtil/Optimizer.cpp | 27 --------------------------- 2 files changed, 28 deletions(-) diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index 4113f4589..032952259 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -626,7 +626,6 @@ class OSGUTIL_EXPORT Optimizer _changeClientImageStorage(changeClientImageStorage), _valueClientImageStorage(valueClientImageStorage), _changeAnisotropy(changeAnisotropy), _valueAnisotropy(valueAnisotropy) {} - virtual void apply(osg::Geode& node); virtual void apply(osg::Node& node); void apply(osg::StateSet& stateset); diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 4f442d4cd..42ad887d7 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -2968,33 +2968,6 @@ void Optimizer::TextureVisitor::apply(osg::Node& node) traverse(node); } -void Optimizer::TextureVisitor::apply(osg::Geode& geode) -{ - if (!isOperationPermissibleForObject(&geode)) return; - - osg::StateSet* ss = geode.getStateSet(); - - if (ss && isOperationPermissibleForObject(ss)) - { - apply(*ss); - } - - for(unsigned int i=0;igetStateSet(); - if (ss && - isOperationPermissibleForObject(drawable) && - isOperationPermissibleForObject(ss)) - { - apply(*ss); - } - } - } -} - void Optimizer::TextureVisitor::apply(osg::StateSet& stateset) { for(unsigned int i=0;i Date: Fri, 20 Jan 2017 21:25:32 +0100 Subject: [PATCH 12/35] TextureAtlasVisitor: fix handling of Drawables that are directly in the scene graph not attached to a Geode --- include/osgUtil/Optimizer | 3 +-- src/osgUtil/Optimizer.cpp | 51 ++++++++++----------------------------- 2 files changed, 14 insertions(+), 40 deletions(-) diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index 032952259..0a7c97748 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -814,8 +814,7 @@ class OSGUTIL_EXPORT Optimizer virtual void reset(); virtual void apply(osg::Node& node); - - virtual void apply(osg::Geode& geode); + virtual void apply(osg::Drawable& node); void optimize(); diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 42ad887d7..179d74b6e 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -4093,56 +4093,31 @@ void Optimizer::TextureAtlasVisitor::apply(osg::Node& node) if (pushedStateState) popStateSet(); } -void Optimizer::TextureAtlasVisitor::apply(osg::Geode& geode) +void Optimizer::TextureAtlasVisitor::apply(osg::Drawable& node) { - if (!isOperationPermissibleForObject(&geode)) return; - - osg::StateSet* ss = geode.getStateSet(); - - - bool pushedGeodeStateState = false; + bool pushedStateState = false; + osg::StateSet* ss = node.getStateSet(); if (ss && ss->getDataVariance()==osg::Object::STATIC) { - if (isOperationPermissibleForObject(ss)) + if (isOperationPermissibleForObject(&node) && + isOperationPermissibleForObject(ss)) { - pushedGeodeStateState = pushStateSet(ss); + pushedStateState = pushStateSet(ss); } } - for(unsigned int i=0;igetStateSet(); - if (ss && ss->getDataVariance()==osg::Object::STATIC) - { - if (isOperationPermissibleForObject(drawable) && - isOperationPermissibleForObject(ss)) - { - pushedDrawableStateState = pushStateSet(ss); - } - } - - if (!_statesetStack.empty()) - { - for(StateSetStack::iterator ssitr = _statesetStack.begin(); - ssitr != _statesetStack.end(); - ++ssitr) - { - _statesetMap[*ssitr].insert(drawable); - } - } - - if (pushedDrawableStateState) popStateSet(); + _statesetMap[*ssitr].insert(&node); } - } - if (pushedGeodeStateState) popStateSet(); + if (pushedStateState) popStateSet(); } void Optimizer::TextureAtlasVisitor::optimize() From ff1a9a195a3217fd1632b4540a1747ea680f9987 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 20 Jan 2017 21:48:45 +0100 Subject: [PATCH 13/35] StaticObjectDetectionVisitor: make use of apply(Drawable) visitor function --- include/osgUtil/Optimizer | 5 +---- src/osgUtil/Optimizer.cpp | 18 +++--------------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index 0a7c97748..d0a1937b5 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -847,15 +847,12 @@ class OSGUTIL_EXPORT Optimizer BaseOptimizerVisitor(optimizer, STATIC_OBJECT_DETECTION) {} virtual void apply(osg::Node& node); - - virtual void apply(osg::Geode& geode); + virtual void apply(osg::Drawable& drawable); protected: void applyStateSet(osg::StateSet& stateset); - void applyDrawable(osg::Drawable& drawable); - }; /** For all geometry apply settings.*/ diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 179d74b6e..9c7d525ac 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -4405,14 +4405,11 @@ void Optimizer::StaticObjectDetectionVisitor::apply(osg::Node& node) traverse(node); } -void Optimizer::StaticObjectDetectionVisitor::apply(osg::Geode& geode) +void Optimizer::StaticObjectDetectionVisitor::apply(osg::Drawable& drawable) { - if (geode.getStateSet()) applyStateSet(*geode.getStateSet()); + if (drawable.getStateSet()) applyStateSet(*drawable.getStateSet()); - for(unsigned int i=0; i Date: Fri, 20 Jan 2017 22:43:58 +0100 Subject: [PATCH 14/35] FlattenStaticTransformsVisitor: fix handling of Drawables that are directly in the scene graph not attached to a Geode --- include/osgUtil/Optimizer | 2 +- src/osgUtil/Optimizer.cpp | 25 +++++++++---------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index d0a1937b5..665eafb91 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -275,7 +275,7 @@ class OSGUTIL_EXPORT Optimizer BaseOptimizerVisitor(optimizer, FLATTEN_STATIC_TRANSFORMS) {} virtual void apply(osg::Node& geode); - virtual void apply(osg::Geode& geode); + virtual void apply(osg::Drawable& drawable); virtual void apply(osg::Billboard& geode); virtual void apply(osg::ProxyNode& node); virtual void apply(osg::PagedLOD& node); diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 9c7d525ac..ddacb8800 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -1173,26 +1173,19 @@ void Optimizer::FlattenStaticTransformsVisitor::apply(osg::PagedLOD& node) traverse(node); } - -void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Geode& geode) +void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Drawable& drawable) { - if (!_transformStack.empty()) + osg::Geometry *geometry = drawable.asGeometry(); + if((geometry) && (isOperationPermissibleForObject(&drawable))) { - for(unsigned int i=0;iasGeometry(); - if((geometry) && (isOperationPermissibleForObject(&geode)) && (isOperationPermissibleForObject(geometry))) - { - if(geometry->getVertexArray() && geometry->getVertexArray()->referenceCount() > 1) { - geometry->setVertexArray(dynamic_cast(geometry->getVertexArray()->clone(osg::CopyOp::DEEP_COPY_ALL))); - } - if(geometry->getNormalArray() && geometry->getNormalArray()->referenceCount() > 1) { - geometry->setNormalArray(dynamic_cast(geometry->getNormalArray()->clone(osg::CopyOp::DEEP_COPY_ALL))); - } - } - _drawableSet.insert(geode.getDrawable(i)); + if(geometry->getVertexArray() && geometry->getVertexArray()->referenceCount() > 1) { + geometry->setVertexArray(dynamic_cast(geometry->getVertexArray()->clone(osg::CopyOp::DEEP_COPY_ALL))); + } + if(geometry->getNormalArray() && geometry->getNormalArray()->referenceCount() > 1) { + geometry->setNormalArray(dynamic_cast(geometry->getNormalArray()->clone(osg::CopyOp::DEEP_COPY_ALL))); } } + _drawableSet.insert(&drawable); } void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Billboard& billboard) From f229b194962bd5138aad20d70b4e254c158aa791 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 20 Jan 2017 22:47:43 +0100 Subject: [PATCH 15/35] TessellateVisitor: fix handling of Geometries that are directly in the scene graph not attached to a Geode --- include/osgUtil/Optimizer | 4 ++-- src/osgUtil/Optimizer.cpp | 13 +++---------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index 665eafb91..520c0f748 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -403,7 +403,7 @@ class OSGUTIL_EXPORT Optimizer }; - /** Tessellate all geodes, to remove POLYGONS.*/ + /** Tessellate all Geometries, to remove POLYGONS.*/ class OSGUTIL_EXPORT TessellateVisitor : public BaseOptimizerVisitor { public: @@ -414,7 +414,7 @@ class OSGUTIL_EXPORT Optimizer TessellateVisitor(Optimizer* optimizer=0): BaseOptimizerVisitor(optimizer, TESSELLATE_GEOMETRY) {} - virtual void apply(osg::Geode& geode); + virtual void apply(osg::Geometry& geom); }; diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index ddacb8800..6e9e411b6 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -405,17 +405,10 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) //////////////////////////////////////////////////////////////////////////// // Tessellate geometry - eg break complex POLYGONS into triangles, strips, fans.. //////////////////////////////////////////////////////////////////////////// -void Optimizer::TessellateVisitor::apply(osg::Geode& geode) +void Optimizer::TessellateVisitor::apply(osg::Geometry &geom) { - for(unsigned int i=0;i(geode.getDrawable(i)); - if (geom) { - osgUtil::Tessellator Tessellator; - Tessellator.retessellatePolygons(*geom); - } - } - traverse(geode); + osgUtil::Tessellator Tessellator; + Tessellator.retessellatePolygons(geom); } From 833f37ea57f5a7c0f05b10bc8dbf7feb9ae2c2fa Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 20 Jan 2017 22:49:17 +0100 Subject: [PATCH 16/35] StateVisitor: remove redundant code for Geode handling --- include/osgUtil/Optimizer | 2 -- src/osgUtil/Optimizer.cpp | 32 -------------------------------- 2 files changed, 34 deletions(-) diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index 520c0f748..979baa1d0 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -460,8 +460,6 @@ class OSGUTIL_EXPORT Optimizer virtual void apply(osg::Node& node); - virtual void apply(osg::Geode& geode); - void optimize(); protected: diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 6e9e411b6..0c92f984b 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -461,38 +461,6 @@ void Optimizer::StateVisitor::apply(osg::Node& node) traverse(node); } -void Optimizer::StateVisitor::apply(osg::Geode& geode) -{ - if (!isOperationPermissibleForObject(&geode)) return; - - osg::StateSet* ss = geode.getStateSet(); - - - if (ss && ss->getDataVariance()==osg::Object::STATIC) - { - if (isOperationPermissibleForObject(ss)) - { - addStateSet(ss,&geode); - } - } - for(unsigned int i=0;igetStateSet(); - if (ss && ss->getDataVariance()==osg::Object::STATIC) - { - if (isOperationPermissibleForObject(drawable) && - isOperationPermissibleForObject(ss)) - { - addStateSet(ss,drawable); - } - } - } - } -} - void Optimizer::StateVisitor::optimize() { OSG_INFO << "Num of StateSet="<<_statesets.size()<< std::endl; From 4a05caf4f7a614df9b4ca22869b203845958b612 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 20 Jan 2017 23:01:04 +0100 Subject: [PATCH 17/35] MakeFastGeometryVisitor: fix handling of Geometries that are directly in the scene graph not attached to a Geode --- include/osgUtil/Optimizer | 6 ++---- src/osgUtil/Optimizer.cpp | 30 ++++++++---------------------- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index 979baa1d0..7b1bfa82a 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -509,7 +509,7 @@ class OSGUTIL_EXPORT Optimizer CheckGeometryVisitor(Optimizer* optimizer=0): BaseOptimizerVisitor(optimizer, CHECK_GEOMETRY) {} - virtual void apply(osg::Geode& geode) { checkGeode(geode); } + virtual void apply(osg::Geometry& geom); void checkGeode(osg::Geode& geode); @@ -523,9 +523,7 @@ class OSGUTIL_EXPORT Optimizer MakeFastGeometryVisitor(Optimizer* optimizer=0): BaseOptimizerVisitor(optimizer, MAKE_FAST_GEOMETRY) {} - virtual void apply(osg::Geode& geode) { checkGeode(geode); } - - void checkGeode(osg::Geode& geode); + virtual void apply(osg::Geometry& geom); }; diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 0c92f984b..6bfbcc607 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -1732,39 +1732,25 @@ struct LessGeometryPrimitiveType } }; -void Optimizer::CheckGeometryVisitor::checkGeode(osg::Geode& geode) +void Optimizer::CheckGeometryVisitor::apply(osg::Geometry& geom) { - if (isOperationPermissibleForObject(&geode)) + if (isOperationPermissibleForObject(&geom)) { - for(unsigned int i=0;iasGeometry(); - if (geom && isOperationPermissibleForObject(geom)) - { #ifdef GEOMETRYDEPRECATED - geom1829 - ->computeCorrectBindingsAndArraySizes(); + geom + .computeCorrectBindingsAndArraySizes(); #endif - } - } } } -void Optimizer::MakeFastGeometryVisitor::checkGeode(osg::Geode& geode) +void Optimizer::MakeFastGeometryVisitor::apply(osg::Geometry& geom) { // GeometryDeprecated CAN REMOVED - if (isOperationPermissibleForObject(&geode)) + if (isOperationPermissibleForObject(&geom)) { - for(unsigned int i=0;iasGeometry(); - if (geom && isOperationPermissibleForObject(geom)) - { - if (geom->checkForDeprecatedData()) - { - geom->fixDeprecatedData(); - } - } + geom.fixDeprecatedData(); } } } From f13fbff2511a4fcf5b88fa76b6611508174aebf1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 20 Jan 2017 23:02:15 +0100 Subject: [PATCH 18/35] Remove CheckGeometryVisitor which was a no-op --- include/osgUtil/Optimizer | 16 +--------------- src/osgUtil/Optimizer.cpp | 22 ---------------------- 2 files changed, 1 insertion(+), 37 deletions(-) diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index 7b1bfa82a..6a6f09305 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -73,7 +73,7 @@ class OSGUTIL_EXPORT Optimizer COMBINE_ADJACENT_LODS = (1 << 3), SHARE_DUPLICATE_STATE = (1 << 4), MERGE_GEOMETRY = (1 << 5), - CHECK_GEOMETRY = (1 << 6), + CHECK_GEOMETRY = (1 << 6), // deprecated, currently no-op MAKE_FAST_GEOMETRY = (1 << 7), SPATIALIZE_GROUPS = (1 << 8), COPY_SHARED_NODES = (1 << 9), @@ -501,20 +501,6 @@ class OSGUTIL_EXPORT Optimizer }; - class OSGUTIL_EXPORT CheckGeometryVisitor : public BaseOptimizerVisitor - { - public: - - /// default to traversing all children. - CheckGeometryVisitor(Optimizer* optimizer=0): - BaseOptimizerVisitor(optimizer, CHECK_GEOMETRY) {} - - virtual void apply(osg::Geometry& geom); - - void checkGeode(osg::Geode& geode); - - }; - class OSGUTIL_EXPORT MakeFastGeometryVisitor : public BaseOptimizerVisitor { public: diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 6bfbcc607..b3ae72f07 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -50,8 +50,6 @@ using namespace osgUtil; -// #define GEOMETRYDEPRECATED - void Optimizer::reset() { } @@ -290,14 +288,6 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) OSG_INFO<<"MERGE_GEODES took "<delta_s(startTick,endTick)<accept(mgv); - } - if (options & MAKE_FAST_GEOMETRY) { OSG_INFO<<"Optimizer::optimize() doing MAKE_FAST_GEOMETRY"< Date: Tue, 24 Jan 2017 17:36:36 +0000 Subject: [PATCH 19/35] Fixed linking bug caused by repeated Program::addShader()/removeShader() operations invalidating the internal attach/dettech lists. --- src/osg/Program.cpp | 52 +++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/src/osg/Program.cpp b/src/osg/Program.cpp index fca3db308..22e3ca052 100644 --- a/src/osg/Program.cpp +++ b/src/osg/Program.cpp @@ -732,26 +732,42 @@ void Program::PerContextProgram::linkProgram(osg::State& state) if (!_loadedBinary) { - // Detach removed shaders - for( unsigned int i=0; i < _shadersToDetach.size(); ++i ) + const GLsizei shaderMaxCount = 20; + GLsizei shadersCount; + GLuint shaderObjectHandle[shaderMaxCount]; + _extensions->glGetAttachedShaders(_glProgramHandle, shaderMaxCount, &shadersCount, shaderObjectHandle); + + typedef std::map ShaderSet; + ShaderSet shadersRequired; + + for(GLsizei i=0; igetPCS(state); - if (pcs) _extensions->glDetachShader( _glProgramHandle, pcs->getHandle() ); + shadersRequired[shaderObjectHandle[i]]--; } + + for(unsigned int i=0; i < getProgram()->getNumShaders(); ++i) + { + const Shader* shader = getProgram()->getShader( i ); + Shader::PerContextShader* pcs = shader->getPCS(state); + if (pcs) shadersRequired[ pcs->getHandle() ]++; + } + + for(ShaderSet::iterator itr = shadersRequired.begin(); + itr != shadersRequired.end(); + ++itr) + { + if (itr->second>0) + { + _extensions->glAttachShader( _glProgramHandle, itr->first ); + } + else if (itr->second<0) + { + _extensions->glDetachShader( _glProgramHandle, itr->first ); + } + } + } _shadersToDetach.clear(); - - if (!_loadedBinary) - { - // Attach new shaders - for( unsigned int i=0; i < _shadersToAttach.size(); ++i ) - { - Shader::PerContextShader* pcs = _shadersToAttach[i]->getPCS(state); - if (pcs) _extensions->glAttachShader( _glProgramHandle, pcs->getHandle() ); - } - } - //state.checkGLErrors("After attaching shaders."); - _shadersToAttach.clear(); _uniformInfoMap.clear(); @@ -805,12 +821,12 @@ void Program::PerContextProgram::linkProgram(osg::State& state) if( ! _isLinked ) { - OSG_WARN << "glLinkProgram \""<< _program->getName() << "\" FAILED" << std::endl; + OSG_NOTICE << "glLinkProgram "<getName() << "\" FAILED" << std::endl; std::string infoLog; if( getInfoLog(infoLog) ) { - OSG_WARN << "Program \""<< _program->getName() << "\" " + OSG_NOTICE << "Program \""<< _program->getName() << "\" " "infolog:\n" << infoLog << std::endl; } From 9183f275f50c424fee7025571032609d85d74047 Mon Sep 17 00:00:00 2001 From: Laurens Voerman Date: Wed, 25 Jan 2017 17:05:56 +0100 Subject: [PATCH 20/35] Fixed a few old function names. Check extensions trough extermination string - not by function pointer value. Added a few validContext tests to ensure no functions or isExterntionSupported bool is set for an non valid context. Remove duplicates / merge some lines. Removed "GL_APPLE_texture_2D_limited_npot" form isNonPowerOfTwoTextureMipMappedSupported. --- src/osg/GLExtensions.cpp | 189 +++++++++++++++++---------------------- 1 file changed, 84 insertions(+), 105 deletions(-) diff --git a/src/osg/GLExtensions.cpp b/src/osg/GLExtensions.cpp index 7a4b038a3..352472ae9 100644 --- a/src/osg/GLExtensions.cpp +++ b/src/osg/GLExtensions.cpp @@ -476,8 +476,9 @@ GLExtensions::GLExtensions(unsigned int in_contextID): isGLExtensionSupported(contextID,"GL_EXT_texture_cube_map") || (glVersion >= 1.3f)); - isClipControlSupported = isGLExtensionSupported(contextID,"GL_ARB_clip_control") || - (glVersion >= 4.5f); + isClipControlSupported = validContext && + (isGLExtensionSupported(contextID,"GL_ARB_clip_control") || + (glVersion >= 4.5f)); isGlslSupported = validContext && @@ -560,45 +561,47 @@ GLExtensions::GLExtensions(unsigned int in_contextID): setGLExtensionFuncPtr(glUniformMatrix3fv, "glUniformMatrix3fv", "glUniformMatrix3fvARB", validContext); setGLExtensionFuncPtr(glUniformMatrix4fv, "glUniformMatrix4fv", "glUniformMatrix4fvARB", validContext); setGLExtensionFuncPtr(glValidateProgram, "glValidateProgram", "glValidateProgramARB", validContext); - setGLExtensionFuncPtr(glVertexAttrib1d, "glVertexAttrib1d", validContext); + + setGLExtensionFuncPtr(glVertexAttrib1d, "glVertexAttrib1d", "glVertexAttrib1dARB", validContext); setGLExtensionFuncPtr(glVertexAttrib1dv, "glVertexAttrib1dv", validContext); - setGLExtensionFuncPtr(glVertexAttrib1f, "glVertexAttrib1f", validContext); - setGLExtensionFuncPtr(glVertexAttrib1fv, "glVertexAttrib1fv", validContext); - setGLExtensionFuncPtr(glVertexAttrib1s, "glVertexAttrib1s", validContext); + setGLExtensionFuncPtr(glVertexAttrib1f, "glVertexAttrib1f", "glVertexAttrib1fARB", validContext); + setGLExtensionFuncPtr(glVertexAttrib1fv, "glVertexAttrib1fv", "glVertexAttrib1fvARB", validContext); + setGLExtensionFuncPtr(glVertexAttrib1s, "glVertexAttrib1s", "glVertexAttrib1sARB", validContext); setGLExtensionFuncPtr(glVertexAttrib1sv, "glVertexAttrib1sv", validContext); setGLExtensionFuncPtr(glVertexAttrib2d, "glVertexAttrib2d", validContext); - setGLExtensionFuncPtr(glVertexAttrib2dv, "glVertexAttrib2dv", validContext); + setGLExtensionFuncPtr(glVertexAttrib2dv, "glVertexAttrib2dv", "glVertexAttrib2dvARB", validContext); setGLExtensionFuncPtr(glVertexAttrib2f, "glVertexAttrib2f", validContext); - setGLExtensionFuncPtr(glVertexAttrib2fv, "glVertexAttrib2fv", validContext); + setGLExtensionFuncPtr(glVertexAttrib2fv, "glVertexAttrib2fv", "glVertexAttrib2fvARB", validContext); setGLExtensionFuncPtr(glVertexAttrib2s, "glVertexAttrib2s", validContext); setGLExtensionFuncPtr(glVertexAttrib2sv, "glVertexAttrib2sv", validContext); setGLExtensionFuncPtr(glVertexAttrib3d, "glVertexAttrib3d", validContext); - setGLExtensionFuncPtr(glVertexAttrib3dv, "glVertexAttrib3dv", validContext); + setGLExtensionFuncPtr(glVertexAttrib3dv, "glVertexAttrib3dv", "glVertexAttrib3dvARB", validContext); setGLExtensionFuncPtr(glVertexAttrib3f, "glVertexAttrib3f", validContext); - setGLExtensionFuncPtr(glVertexAttrib3fv, "glVertexAttrib3fv", validContext); + setGLExtensionFuncPtr(glVertexAttrib3fv, "glVertexAttrib3fv", "glVertexAttrib3fvARB", validContext); setGLExtensionFuncPtr(glVertexAttrib3s, "glVertexAttrib3s", validContext); setGLExtensionFuncPtr(glVertexAttrib3sv, "glVertexAttrib3sv", validContext); setGLExtensionFuncPtr(glVertexAttrib4Nbv, "glVertexAttrib4Nbv", validContext); setGLExtensionFuncPtr(glVertexAttrib4Niv, "glVertexAttrib4Niv", validContext); setGLExtensionFuncPtr(glVertexAttrib4Nsv, "glVertexAttrib4Nsv", validContext); setGLExtensionFuncPtr(glVertexAttrib4Nub, "glVertexAttrib4Nub", validContext); - setGLExtensionFuncPtr(glVertexAttrib4Nubv, "glVertexAttrib4Nubv", validContext); + setGLExtensionFuncPtr(glVertexAttrib4Nubv, "glVertexAttrib4Nubv", "glVertexAttrib4NubvARB", validContext); setGLExtensionFuncPtr(glVertexAttrib4Nuiv, "glVertexAttrib4Nuiv", validContext); setGLExtensionFuncPtr(glVertexAttrib4Nusv, "glVertexAttrib4Nusv", validContext); setGLExtensionFuncPtr(glVertexAttrib4bv, "glVertexAttrib4bv", validContext); setGLExtensionFuncPtr(glVertexAttrib4d, "glVertexAttrib4d", validContext); - setGLExtensionFuncPtr(glVertexAttrib4dv, "glVertexAttrib4dv", validContext); + setGLExtensionFuncPtr(glVertexAttrib4dv, "glVertexAttrib4dv", "glVertexAttrib4dvARB", validContext); setGLExtensionFuncPtr(glVertexAttrib4f, "glVertexAttrib4f", validContext); - setGLExtensionFuncPtr(glVertexAttrib4fv, "glVertexAttrib4fv", validContext); + setGLExtensionFuncPtr(glVertexAttrib4fv, "glVertexAttrib4fv", "glVertexAttrib4fvARB", validContext); setGLExtensionFuncPtr(glVertexAttrib4iv, "glVertexAttrib4iv", validContext); setGLExtensionFuncPtr(glVertexAttrib4s, "glVertexAttrib4s", validContext); setGLExtensionFuncPtr(glVertexAttrib4sv, "glVertexAttrib4sv", validContext); - setGLExtensionFuncPtr(glVertexAttrib4ubv, "glVertexAttrib4ubv", validContext); + setGLExtensionFuncPtr(glVertexAttrib4ubv, "glVertexAttrib4ubv", "glVertexAttrib4ubvARB", validContext); setGLExtensionFuncPtr(glVertexAttrib4uiv, "glVertexAttrib4uiv", validContext); setGLExtensionFuncPtr(glVertexAttrib4usv, "glVertexAttrib4usv", validContext); + setGLExtensionFuncPtr(glVertexAttribPointer, "glVertexAttribPointer","glVertexAttribPointerARB", validContext); setGLExtensionFuncPtr(glVertexAttribIPointer, "glVertexAttribIPointer","glVertexAttribIPointerARB", validContext); - setGLExtensionFuncPtr(glVertexAttribLPointer, "glVertexAttribLPointer","glVertexAttribPointerARB", validContext); + setGLExtensionFuncPtr(glVertexAttribLPointer, "glVertexAttribLPointer","glVertexAttribLPointerARB", validContext); setGLExtensionFuncPtr(glVertexAttribDivisor, "glVertexAttribDivisor", validContext); // v1.5-only ARB entry points, in case they're needed for fallback @@ -697,7 +700,6 @@ GLExtensions::GLExtensions(unsigned int in_contextID): isVBOSupported = validContext && (OSG_GLES2_FEATURES || OSG_GL3_FEATURES || osg::isGLExtensionSupported(contextID,"GL_ARB_vertex_buffer_object")); isPBOSupported = validContext && (OSG_GLES2_FEATURES || OSG_GL3_FEATURES || osg::isGLExtensionSupported(contextID,"GL_ARB_pixel_buffer_object")); - isUniformBufferObjectSupported = validContext && osg::isGLExtensionSupported(contextID, "GL_ARB_uniform_buffer_object"); isTBOSupported = validContext && osg::isGLExtensionSupported(contextID,"GL_ARB_texture_buffer_object"); isVAOSupported = validContext && (OSG_GL3_FEATURES || osg::isGLExtensionSupported(contextID, "GL_ARB_vertex_array_object", "GL_OES_vertex_array_object")); isTransformFeedbackSupported = validContext && osg::isGLExtensionSupported(contextID, "GL_ARB_transform_feedback2"); @@ -716,7 +718,6 @@ GLExtensions::GLExtensions(unsigned int in_contextID): setGLExtensionFuncPtr(glBlendFuncSeparatei, "glBlendFuncSeparatei", "glBlendFuncSeparateiARB", validContext); - // Vertex Array extensions isSecondaryColorSupported = validContext && isGLExtensionSupported(contextID,"GL_EXT_secondary_color"); isFogCoordSupported = validContext && isGLExtensionSupported(contextID,"GL_EXT_fog_coord"); isMultiTexSupported = validContext && isGLExtensionSupported(contextID,"GL_ARB_multitexture"); @@ -744,40 +745,15 @@ GLExtensions::GLExtensions(unsigned int in_contextID): setGLExtensionFuncPtr(glMultiTexCoord4fv, "glMultiTexCoord4fv","glMultiTexCoord4fvARB", validContext); - setGLExtensionFuncPtr(glMultiTexCoord1d, "glMultiTexCoord1d","glMultiTexCoorddfARB", validContext); + setGLExtensionFuncPtr(glMultiTexCoord1d, "glMultiTexCoord1d","glMultiTexCoord1dARB", validContext); setGLExtensionFuncPtr(glMultiTexCoord1dv, "glMultiTexCoord1dv","glMultiTexCoord1dvARB", validContext); setGLExtensionFuncPtr(glMultiTexCoord2dv, "glMultiTexCoord2dv","glMultiTexCoord2dvARB", validContext); setGLExtensionFuncPtr(glMultiTexCoord3dv, "glMultiTexCoord3dv","glMultiTexCoord3dvARB", validContext); setGLExtensionFuncPtr(glMultiTexCoord4dv, "glMultiTexCoord4dv","glMultiTexCoord4dvARB", validContext); - setGLExtensionFuncPtr(glVertexAttrib1s, "glVertexAttrib1s","glVertexAttrib1sARB", validContext); - setGLExtensionFuncPtr(glVertexAttrib1f, "glVertexAttrib1f","glVertexAttrib1fARB", validContext); - setGLExtensionFuncPtr(glVertexAttrib1d, "glVertexAttrib1d","glVertexAttrib1dARB", validContext); - setGLExtensionFuncPtr(glVertexAttrib1fv, "glVertexAttrib1fv","glVertexAttrib1fvARB", validContext); - setGLExtensionFuncPtr(glVertexAttrib2fv, "glVertexAttrib2fv","glVertexAttrib2fvARB", validContext); - setGLExtensionFuncPtr(glVertexAttrib3fv, "glVertexAttrib3fv","glVertexAttrib3fvARB", validContext); - setGLExtensionFuncPtr(glVertexAttrib4fv, "glVertexAttrib4fv","glVertexAttrib4fvARB", validContext); - setGLExtensionFuncPtr(glVertexAttrib2dv, "glVertexAttrib2dv","glVertexAttrib2dvARB", validContext); - setGLExtensionFuncPtr(glVertexAttrib3dv, "glVertexAttrib3dv","glVertexAttrib3dvARB", validContext); - setGLExtensionFuncPtr(glVertexAttrib4dv, "glVertexAttrib4dv","glVertexAttrib4dvARB", validContext); - setGLExtensionFuncPtr(glVertexAttrib4ubv, "glVertexAttrib4ubv","glVertexAttrib4ubvARB", validContext); - setGLExtensionFuncPtr(glVertexAttrib4Nubv, "glVertexAttrib4Nubv","glVertexAttrib4NubvARB", validContext); - - setGLExtensionFuncPtr(glGenBuffers, "glGenBuffers","glGenBuffersARB", validContext); - setGLExtensionFuncPtr(glBindBuffer, "glBindBuffer","glBindBufferARB", validContext); - setGLExtensionFuncPtr(glBufferData, "glBufferData","glBufferDataARB", validContext); - setGLExtensionFuncPtr(glBufferSubData, "glBufferSubData","glBufferSubDataARB", validContext); - setGLExtensionFuncPtr(glDeleteBuffers, "glDeleteBuffers","glDeleteBuffersARB", validContext); - setGLExtensionFuncPtr(glIsBuffer, "glIsBuffer","glIsBufferARB", validContext); - setGLExtensionFuncPtr(glGetBufferSubData, "glGetBufferSubData","glGetBufferSubDataARB", validContext); - setGLExtensionFuncPtr(glMapBuffer, "glMapBuffer","glMapBufferARB", validContext); - setGLExtensionFuncPtr(glUnmapBuffer, "glUnmapBuffer","glUnmapBufferARB", validContext); - setGLExtensionFuncPtr(glGetBufferParameteriv, "glGetBufferParameteriv","glGetBufferParameterivARB", validContext); - setGLExtensionFuncPtr(glGetBufferPointerv, "glGetBufferPointerv","glGetBufferPointervARB", validContext); - setGLExtensionFuncPtr(glGenOcclusionQueries, "glGenOcclusionQueries","glGenOcclusionQueriesNV", validContext); setGLExtensionFuncPtr(glDeleteOcclusionQueries, "glDeleteOcclusionQueries","glDeleteOcclusionQueriesNV", validContext); - setGLExtensionFuncPtr(glIsOcclusionQuery, "glIsOcclusionQuery","_glIsOcclusionQueryNV", validContext); + setGLExtensionFuncPtr(glIsOcclusionQuery, "glIsOcclusionQuery","glIsOcclusionQueryNV", validContext); setGLExtensionFuncPtr(glBeginOcclusionQuery, "glBeginOcclusionQuery","glBeginOcclusionQueryNV", validContext); setGLExtensionFuncPtr(glEndOcclusionQuery, "glEndOcclusionQuery","glEndOcclusionQueryNV", validContext); setGLExtensionFuncPtr(glGetOcclusionQueryiv, "glGetOcclusionQueryiv","glGetOcclusionQueryivNV", validContext); @@ -802,9 +778,7 @@ GLExtensions::GLExtensions(unsigned int in_contextID): // function pointers setGLExtensionFuncPtr(glSampleMaski, "glSampleMaski", validContext); - // protect against buggy drivers (maybe not necessary) - isSampleMaskiSupported = glSampleMaski!=0; - + isSampleMaskiSupported = validContext && (isOpenGL32upported || isGLExtensionSupported(contextID,"ARB_texture_multisample")); // old styple Vertex/Fragment Programs @@ -839,33 +813,36 @@ GLExtensions::GLExtensions(unsigned int in_contextID): isTextureCompressionS3TCSupported = validContext && (isGLExtensionSupported(contextID,"GL_EXT_texture_compression_s3tc") || isGLExtensionSupported(contextID, "GL_S3_s3tc")); isTextureCompressionPVRTC2BPPSupported = validContext && isGLExtensionSupported(contextID,"GL_IMG_texture_compression_pvrtc"); isTextureCompressionPVRTC4BPPSupported = isTextureCompressionPVRTC2BPPSupported;//covered by same extension - isTextureCompressionETCSupported = isGLExtensionSupported(contextID,"GL_OES_compressed_ETC1_RGB8_texture"); - isTextureCompressionETC2Supported = isGLExtensionSupported(contextID,"GL_ARB_ES3_compatibility"); - isTextureCompressionRGTCSupported = isGLExtensionSupported(contextID,"GL_EXT_texture_compression_rgtc"); - isTextureCompressionPVRTCSupported = isGLExtensionSupported(contextID,"GL_IMG_texture_compression_pvrtc"); + isTextureCompressionETCSupported = validContext && isGLExtensionSupported(contextID,"GL_OES_compressed_ETC1_RGB8_texture"); + isTextureCompressionETC2Supported = validContext && isGLExtensionSupported(contextID,"GL_ARB_ES3_compatibility"); + isTextureCompressionRGTCSupported = validContext && isGLExtensionSupported(contextID,"GL_EXT_texture_compression_rgtc"); + isTextureCompressionPVRTCSupported = validContext && isGLExtensionSupported(contextID,"GL_IMG_texture_compression_pvrtc"); - isTextureMirroredRepeatSupported = builtInSupport || - isGLExtensionOrVersionSupported(contextID,"GL_IBM_texture_mirrored_repeat", 1.4f) || - isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_mirrored_repeat", 1.4f); + isTextureMirroredRepeatSupported = validContext && + (builtInSupport || + isGLExtensionOrVersionSupported(contextID,"GL_IBM_texture_mirrored_repeat", 1.4f) || + isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_mirrored_repeat", 1.4f)); - isTextureEdgeClampSupported = builtInSupport || + isTextureEdgeClampSupported = validContext && + (builtInSupport || isGLExtensionOrVersionSupported(contextID,"GL_EXT_texture_edge_clamp", 1.2f) || - isGLExtensionOrVersionSupported(contextID,"GL_SGIS_texture_edge_clamp", 1.2f); + isGLExtensionOrVersionSupported(contextID,"GL_SGIS_texture_edge_clamp", 1.2f)); - isTextureBorderClampSupported = OSG_GL3_FEATURES || - ((OSG_GL1_FEATURES || OSG_GL2_FEATURES) && isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_border_clamp", 1.3f)) || - (OSG_GLES2_FEATURES && isGLExtensionSupported(contextID,"GL_EXT_texture_border_clamp")); + isTextureBorderClampSupported = validContext && + (OSG_GL3_FEATURES || + ((OSG_GL1_FEATURES || OSG_GL2_FEATURES) && isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_border_clamp", 1.3f)) || + (OSG_GLES2_FEATURES && isGLExtensionSupported(contextID,"GL_EXT_texture_border_clamp"))); - isGenerateMipMapSupported = builtInSupport || isGLExtensionOrVersionSupported(contextID,"GL_SGIS_generate_mipmap", 1.4f); + isGenerateMipMapSupported = validContext && (builtInSupport || isGLExtensionOrVersionSupported(contextID,"GL_SGIS_generate_mipmap", 1.4f)); preferGenerateMipmapSGISForPowerOfTwo = (radeonHardwareDetected||fireGLHardwareDetected) ? false : true; - isTextureMultisampledSupported = isGLExtensionSupported(contextID,"GL_ARB_texture_multisample"); - isShadowSupported = OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_shadow"); - isShadowAmbientSupported = isGLExtensionSupported(contextID,"GL_ARB_shadow_ambient"); - isClientStorageSupported = isGLExtensionSupported(contextID,"GL_APPLE_client_storage"); - isNonPowerOfTwoTextureNonMipMappedSupported = builtInSupport || isGLExtensionSupported(contextID,"GL_OES_texture_npot") || isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_non_power_of_two", 2.0) || isGLExtensionSupported(contextID,"GL_APPLE_texture_2D_limited_npot"); - isNonPowerOfTwoTextureMipMappedSupported = builtInSupport || isNonPowerOfTwoTextureNonMipMappedSupported; - isTextureIntegerEXTSupported = OSG_GL3_FEATURES || isGLExtensionSupported(contextID, "GL_EXT_texture_integer"); + isTextureMultisampledSupported = validContext && (isGLExtensionSupported(contextID,"GL_ARB_texture_multisample")); + isShadowSupported = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_shadow")); + isShadowAmbientSupported = validContext && (isGLExtensionSupported(contextID,"GL_ARB_shadow_ambient")); + isClientStorageSupported = validContext && (isGLExtensionSupported(contextID,"GL_APPLE_client_storage")); + isNonPowerOfTwoTextureMipMappedSupported = validContext && (builtInSupport || isGLExtensionSupported(contextID, "GL_OES_texture_npot") || isGLExtensionOrVersionSupported(contextID, "GL_ARB_texture_non_power_of_two", 2.0)); + isNonPowerOfTwoTextureNonMipMappedSupported = validContext && (isNonPowerOfTwoTextureMipMappedSupported || isGLExtensionSupported(contextID, "GL_APPLE_texture_2D_limited_npot")); + isTextureIntegerEXTSupported = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID, "GL_EXT_texture_integer")); if (rendererString.find("GeForce FX")!=std::string::npos) { @@ -894,19 +871,15 @@ GLExtensions::GLExtensions(unsigned int in_contextID): setGLExtensionFuncPtr(glGetCompressedTexImage,"glGetCompressedTexImage","glGetCompressedTexImageARB", validContext);; setGLExtensionFuncPtr(glTexImage2DMultisample, "glTexImage2DMultisample", "glTexImage2DMultisampleARB", validContext); - setGLExtensionFuncPtr(glTexParameterIiv, "glTexParameterIiv", "glTexParameterIivARB", validContext); - setGLExtensionFuncPtr(glTexParameterIuiv, "glTexParameterIuiv", "glTexParameterIuivARB", validContext); - - - if (glTexParameterIiv == NULL) setGLExtensionFuncPtr(glTexParameterIiv, "glTexParameterIivEXT", validContext); - if (glTexParameterIuiv == NULL) setGLExtensionFuncPtr(glTexParameterIuiv, "glTexParameterIuivEXT", validContext); + setGLExtensionFuncPtr(glTexParameterIiv, "glTexParameterIiv", "glTexParameterIivARB", "glTexParameterIivEXT", validContext); + setGLExtensionFuncPtr(glTexParameterIuiv, "glTexParameterIuiv", "glTexParameterIuivARB", "glTexParameterIuivEXT", validContext); setGLExtensionFuncPtr(glBindImageTexture, "glBindImageTexture", "glBindImageTextureARB", validContext); isTextureMaxLevelSupported = (glVersion >= 1.2f); - isTextureStorageEnabled = isTexStorage2DSupported(); - if ( (ptr = getenv("OSG_GL_TEXTURE_STORAGE")) != 0 && isTexStorage2DSupported()) + isTextureStorageEnabled = validContext && ((glVersion >= 4.2f) || isGLExtensionSupported(contextID, "GL_ARB_texture_storage")); + if ( (ptr = getenv("OSG_GL_TEXTURE_STORAGE")) != 0 && isTextureStorageEnabled) { if (strcmp(ptr,"OFF")==0 || strcmp(ptr,"DISABLE")==0 ) isTextureStorageEnabled = false; else isTextureStorageEnabled = true; @@ -914,10 +887,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID): // Texture3D extensions - isTexture3DFast = OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture3D"); + isTexture3DFast = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture3D")); if (isTexture3DFast) isTexture3DSupported = true; - else isTexture3DSupported = (glVersion >= 1.2f); + else isTexture3DSupported = validContext && (glVersion >= 1.2f); maxTexture3DSize = 0; if (validContext) glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &maxTexture3DSize); @@ -930,7 +903,7 @@ GLExtensions::GLExtensions(unsigned int in_contextID): // Texture2DArray extensions - isTexture2DArraySupported = OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture_array"); + isTexture2DArraySupported = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture_array")); max2DSize = 0; if (validContext) glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max2DSize); @@ -938,25 +911,28 @@ GLExtensions::GLExtensions(unsigned int in_contextID): if (validContext) glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS_EXT, &maxLayerCount); // Blending - isBlendColorSupported = OSG_GLES2_FEATURES || OSG_GL3_FEATURES || - isGLExtensionSupported(contextID,"GL_EXT_blend_color") || - (glVersion >= 1.2f); + isBlendColorSupported = validContext && + (OSG_GLES2_FEATURES || OSG_GL3_FEATURES || + isGLExtensionSupported(contextID,"GL_EXT_blend_color") || + (glVersion >= 1.2f)); setGLExtensionFuncPtr(glBlendColor, "glBlendColor", "glBlendColorEXT", validContext); bool bultInSupport = OSG_GLES2_FEATURES || OSG_GL3_FEATURES; - isBlendEquationSupported = bultInSupport || - isGLExtensionSupported(contextID, "GL_EXT_blend_equation") || - (glVersion >= 1.2f); + isBlendEquationSupported = validContext && + (bultInSupport || + isGLExtensionSupported(contextID, "GL_EXT_blend_equation") || + (glVersion >= 1.2f)); - isBlendEquationSeparateSupported = bultInSupport || - isGLExtensionSupported(contextID, "GL_EXT_blend_equation_separate") || - (glVersion >= 2.0f); + isBlendEquationSeparateSupported = validContext && + (bultInSupport || + isGLExtensionSupported(contextID, "GL_EXT_blend_equation_separate") || + (glVersion >= 2.0f)); - isSGIXMinMaxSupported = isGLExtensionSupported(contextID, "GL_SGIX_blend_alpha_minmax"); - isLogicOpSupported = isGLExtensionSupported(contextID, "GL_EXT_blend_logic_op"); + isSGIXMinMaxSupported = validContext && isGLExtensionSupported(contextID, "GL_SGIX_blend_alpha_minmax"); + isLogicOpSupported = validContext && isGLExtensionSupported(contextID, "GL_EXT_blend_logic_op"); setGLExtensionFuncPtr(glBlendEquation, "glBlendEquation", "glBlendEquationEXT", validContext); setGLExtensionFuncPtr(glBlendEquationSeparate, "glBlendEquationSeparate", "glBlendEquationSeparateEXT", validContext); @@ -971,10 +947,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID): // Stencil` - isStencilWrapSupported = isGLExtensionOrVersionSupported(contextID, "GL_EXT_stencil_wrap", 1.4f); - isStencilTwoSidedSupported = isGLExtensionSupported(contextID, "GL_EXT_stencil_two_side"); - isOpenGL20Supported = (glVersion >= 2.0f); - isSeparateStencilSupported = isGLExtensionSupported(contextID, "GL_ATI_separate_stencil"); + isStencilWrapSupported = validContext && isGLExtensionOrVersionSupported(contextID, "GL_EXT_stencil_wrap", 1.4f); + isStencilTwoSidedSupported = validContext && isGLExtensionSupported(contextID, "GL_EXT_stencil_two_side"); + isOpenGL20Supported = validContext && (glVersion >= 2.0f); + isSeparateStencilSupported = validContext && isGLExtensionSupported(contextID, "GL_ATI_separate_stencil"); // function pointers setGLExtensionFuncPtr(glActiveStencilFace, "glActiveStencilFaceEXT", validContext); @@ -989,9 +965,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID): // ClampColor - isClampColorSupported = OSG_GL3_FEATURES || + isClampColorSupported = validContext && + (OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_color_buffer_float") || - (glVersion >= 2.0f); + (glVersion >= 2.0f)); setGLExtensionFuncPtr(glClampColor, "glClampColor", "glClampColorARB", validContext); @@ -1001,14 +978,15 @@ GLExtensions::GLExtensions(unsigned int in_contextID): // Point - isPointParametersSupported = OSG_GL3_FEATURES || (glVersion >= 1.4f) || + isPointParametersSupported = validContext && + (OSG_GL3_FEATURES || (glVersion >= 1.4f) || isGLExtensionSupported(contextID,"GL_ARB_point_parameters") || isGLExtensionSupported(contextID,"GL_EXT_point_parameters") || - isGLExtensionSupported(contextID,"GL_SGIS_point_parameters"); + isGLExtensionSupported(contextID,"GL_SGIS_point_parameters")); - isPointSpriteSupported = OSG_GL3_FEATURES || isGLExtensionSupported(contextID, "GL_ARB_point_sprite") || isGLExtensionSupported(contextID, "GL_OES_point_sprite") || isGLExtensionSupported(contextID, "GL_NV_point_sprite"); - isPointSpriteCoordOriginSupported = OSG_GL3_FEATURES || (glVersion >= 2.0f); + isPointSpriteSupported = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID, "GL_ARB_point_sprite") || isGLExtensionSupported(contextID, "GL_OES_point_sprite") || isGLExtensionSupported(contextID, "GL_NV_point_sprite")); + isPointSpriteCoordOriginSupported = validContext && (OSG_GL3_FEATURES || (glVersion >= 2.0f)); setGLExtensionFuncPtr(glPointParameteri, "glPointParameteri", "glPointParameteriARB", validContext); @@ -1022,10 +1000,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID): // Multisample - isMultisampleSupported = OSG_GLES2_FEATURES || OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_multisample"); - isMultisampleFilterHintSupported = isGLExtensionSupported(contextID, "GL_NV_multisample_filter_hint"); + isMultisampleSupported = validContext && (OSG_GLES2_FEATURES || OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_multisample")); + isMultisampleFilterHintSupported = validContext && isGLExtensionSupported(contextID, "GL_NV_multisample_filter_hint"); - setGLExtensionFuncPtr(glSampleCoverage, "glSampleCoverageARB", validContext); + setGLExtensionFuncPtr(glSampleCoverage, "glSampleCoverage", "glSampleCoverageARB", validContext); // FrameBufferObject @@ -1068,9 +1046,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID): ( OSG_GLES1_FEATURES || isGLExtensionOrVersionSupported(contextID, "GL_EXT_framebuffer_object",3.0f) ); - isPackedDepthStencilSupported = OSG_GL3_FEATURES || - (isGLExtensionSupported(contextID, "GL_EXT_packed_depth_stencil")) || - (isGLExtensionSupported(contextID, "GL_OES_packed_depth_stencil")); + isPackedDepthStencilSupported = validContext && + (OSG_GL3_FEATURES || + (isGLExtensionSupported(contextID, "GL_EXT_packed_depth_stencil")) || + (isGLExtensionSupported(contextID, "GL_OES_packed_depth_stencil"))); //subroutine osg::setGLExtensionFuncPtr(glGetSubroutineUniformLocation, "glGetSubroutineUniformLocation", validContext); From f5483b0ad66dbe5f96dde39473a11ae47631408a Mon Sep 17 00:00:00 2001 From: Kjell Andersson Date: Thu, 2 Feb 2017 11:46:16 +0100 Subject: [PATCH 21/35] Bug fix to not crash when using shared context and adding / removing windowed views dynamically. The GLExtension object is now reused instead of creating a new when allocating a state on the same ContextID. The static map that stores the GLExtensions is only reset when all references to the extension object are released. --- src/osg/State.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/osg/State.cpp b/src/osg/State.cpp index 030a57e5c..75668a18d 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -142,8 +142,12 @@ State::~State() // delete the GLExtensions object associated with this osg::State. if (_glExtensions) { - GLExtensions::Set(_contextID, 0); _glExtensions = 0; + GLExtensions* glExtensions = GLExtensions::Get(_contextID, false); + if (glExtensions && glExtensions->referenceCount() == 1) { + // the only reference left to the extension is in the static map itself, so we clean it up now + GLExtensions::Set(_contextID, 0); + } } //_texCoordArrayList.clear(); @@ -166,8 +170,7 @@ void State::initializeExtensionProcs() _defineMap.changed = true; } - _glExtensions = new GLExtensions(_contextID); - GLExtensions::Set(_contextID, _glExtensions.get()); + _glExtensions = GLExtensions::Get(_contextID, true); _isSecondaryColorSupported = osg::isGLExtensionSupported(_contextID,"GL_EXT_secondary_color"); _isFogCoordSupported = osg::isGLExtensionSupported(_contextID,"GL_EXT_fog_coord"); From 7b67ef0c6f0bb1f2716cbdc16d630c141c7f3476 Mon Sep 17 00:00:00 2001 From: Laurens Voerman Date: Fri, 3 Feb 2017 10:01:15 +0100 Subject: [PATCH 22/35] split travis-ci apple build into two jobs to avoid job time limit. --- .travis.yml | 10 +++++++++- CMakeLists.txt | 3 +++ src/CMakeLists.txt | 8 +++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index d3bb883ba..2d1a530c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ matrix: dist: trusty language: cpp env: + - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS=ON -DBUILD_OSG_APPLICATIONS=ON" #- LLVM_VERSION=3.8 sudo: false cache: @@ -42,6 +43,12 @@ matrix: # OSX build - os: osx language: cpp + env: + - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=OFF -DBUILD_OSG_PLUGINS=ON -DBUILD_OSG_APPLICATIONS=ON" + - os: osx + language: cpp + env: + - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS=OFF -DBUILD_OSG_APPLICATIONS=OFF" # script: # - mkdir build @@ -50,4 +57,5 @@ matrix: # - make install -j 3 script: - - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then mkdir build && cd build && travis_wait 60 cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../product -DBUILD_OSG_EXAMPLES=ON ../ && make -j3 ; fi + - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then mkdir build && cd build && travis_wait 60 cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../product $CMAKECMD_ARGS ../ ; fi + - if [ -f CMakeCache.txt ]; then make -j3 ; fi diff --git a/CMakeLists.txt b/CMakeLists.txt index 326caa5e7..338d3d43f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -700,6 +700,9 @@ OPTION(BUILD_OSG_APPLICATIONS "Enable to build OSG Applications (e.g. osgviewer) # OSG Examples OPTION(BUILD_OSG_EXAMPLES "Enable to build OSG Examples" OFF) +# OSG Plugins disable option for apple build on travis ci test - full build job runs over time limit of 50 min. +OPTION(BUILD_OSG_PLUGINS "Build OSG Plugins - Disable for compile testing examples on a time limit" ON) +mark_as_advanced(BUILD_OSG_PLUGINS) ################################################################################ # 3rd Party Dependency Stuff IF(WIN32 AND NOT ANDROID) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 401688ef3..97a015d8a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,13 +26,15 @@ FOREACH( mylibfolder osgTerrain osgWidget osgPresentation - osgWrappers/serializers - osgWrappers/deprecated-dotosg - osgPlugins ) ADD_SUBDIRECTORY(${mylibfolder}) ENDFOREACH() +IF(BUILD_OSG_PLUGINS) + ADD_SUBDIRECTORY(osgWrappers/serializers) + ADD_SUBDIRECTORY(osgWrappers/deprecated-dotosg) + ADD_SUBDIRECTORY(osgPlugins) +ENDIF(BUILD_OSG_PLUGINS) From a13b66135f826688acb860fc7f0f0c911435645d Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 3 Feb 2017 17:33:58 +0100 Subject: [PATCH 23/35] Fix handling of in-scenegraph drawables in osgUtil::Simplifier --- include/osgUtil/Simplifier | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/include/osgUtil/Simplifier b/include/osgUtil/Simplifier index 4b19ec81a..27d719ba8 100644 --- a/include/osgUtil/Simplifier +++ b/include/osgUtil/Simplifier @@ -97,16 +97,9 @@ class OSGUTIL_EXPORT Simplifier : public osg::NodeVisitor return getSampleRatio()<1.0; } - virtual void apply(osg::Geode& geode) + virtual void apply(osg::Geometry& geom) { - for(unsigned int i=0;iasGeometry(); - if (geometry) - { - simplify(*geometry); - } - } + simplify(geom); } /** simply the geometry.*/ From 09ca1321029071e3699833172ea8427367e83fde Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 3 Feb 2017 17:34:17 +0100 Subject: [PATCH 24/35] Remove redundant handling of Geode in SharedStateManager --- include/osgDB/SharedStateManager | 1 - src/osgDB/SharedStateManager.cpp | 14 -------------- 2 files changed, 15 deletions(-) diff --git a/include/osgDB/SharedStateManager b/include/osgDB/SharedStateManager index 08c30df81..73cc2117d 100644 --- a/include/osgDB/SharedStateManager +++ b/include/osgDB/SharedStateManager @@ -61,7 +61,6 @@ namespace osgDB { void share(osg::Node *node, OpenThreads::Mutex *mt=0); void apply(osg::Node& node); - void apply(osg::Geode& geode); // Answers the question "Will this state set be eliminated by // the SharedStateManager because an equivalent one has been diff --git a/src/osgDB/SharedStateManager.cpp b/src/osgDB/SharedStateManager.cpp index b95cbd0f7..61cd9458e 100644 --- a/src/osgDB/SharedStateManager.cpp +++ b/src/osgDB/SharedStateManager.cpp @@ -93,20 +93,6 @@ void SharedStateManager::apply(osg::Node& node) if(ss) process(ss, &node); traverse(node); } -void SharedStateManager::apply(osg::Geode& geode) -{ - osg::StateSet* ss = geode.getStateSet(); - if(ss) process(ss, &geode); - for(unsigned int i=0;igetStateSet(); - if(ss) process(ss, drawable); - } - } -} bool SharedStateManager::isShared(osg::StateSet* ss) { From a858b2a2cd3ac0a50f5fea598b4596fc8ed4402a Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 3 Feb 2017 17:39:56 +0100 Subject: [PATCH 25/35] Add a comment explaining some confusing code in UpdateVisitor and EventVisitor --- include/osgGA/EventVisitor | 4 ++-- include/osgUtil/UpdateVisitor | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/osgGA/EventVisitor b/include/osgGA/EventVisitor index 2eb15a633..ff3deece5 100644 --- a/include/osgGA/EventVisitor +++ b/include/osgGA/EventVisitor @@ -106,11 +106,11 @@ class OSGGA_EXPORT EventVisitor : public osg::NodeVisitor handle_callbacks(drawable.getStateSet()); } + // The following overrides are technically redundant as the default implementation would eventually trickle down to + // apply(osg::Node&); - however defining these explicitely should save a couple of virtual function calls virtual void apply(osg::Geode& node) { handle_callbacks_and_traverse(node); } virtual void apply(osg::Billboard& node) { handle_callbacks_and_traverse(node); } - virtual void apply(osg::LightSource& node) { handle_callbacks_and_traverse(node); } - virtual void apply(osg::Group& node) { handle_callbacks_and_traverse(node); } virtual void apply(osg::Transform& node) { handle_callbacks_and_traverse(node); } virtual void apply(osg::Projection& node) { handle_callbacks_and_traverse(node); } diff --git a/include/osgUtil/UpdateVisitor b/include/osgUtil/UpdateVisitor index 011d0022e..1e16a2b1f 100644 --- a/include/osgUtil/UpdateVisitor +++ b/include/osgUtil/UpdateVisitor @@ -73,11 +73,11 @@ class OSGUTIL_EXPORT UpdateVisitor : public osg::NodeVisitor handle_callbacks(drawable.getStateSet()); } + // The following overrides are technically redundant as the default implementation would eventually trickle down to + // apply(osg::Node&); - however defining these explicitely should save a couple of virtual function calls virtual void apply(osg::Geode& node) { handle_callbacks_and_traverse(node); } virtual void apply(osg::Billboard& node) { handle_callbacks_and_traverse(node); } - virtual void apply(osg::LightSource& node) { handle_callbacks_and_traverse(node); } - virtual void apply(osg::Group& node) { handle_callbacks_and_traverse(node); } virtual void apply(osg::Transform& node) { handle_callbacks_and_traverse(node); } virtual void apply(osg::Projection& node) { handle_callbacks_and_traverse(node); } From 853418db9493a3c3a68277aadaa49f0f078a3e3b Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 3 Feb 2017 17:42:21 +0100 Subject: [PATCH 26/35] Remove redundant handling of Geode in DisplayRequirementsVisitor --- include/osgUtil/DisplayRequirementsVisitor | 2 -- src/osgUtil/DisplayRequirementsVisitor.cpp | 12 ------------ 2 files changed, 14 deletions(-) diff --git a/include/osgUtil/DisplayRequirementsVisitor b/include/osgUtil/DisplayRequirementsVisitor index f29d277d7..0c397f931 100644 --- a/include/osgUtil/DisplayRequirementsVisitor +++ b/include/osgUtil/DisplayRequirementsVisitor @@ -48,8 +48,6 @@ class OSGUTIL_EXPORT DisplayRequirementsVisitor : public osg::NodeVisitor virtual void apply(osg::Node& node); - virtual void apply(osg::Geode& geode); - protected: osg::ref_ptr _ds; diff --git a/src/osgUtil/DisplayRequirementsVisitor.cpp b/src/osgUtil/DisplayRequirementsVisitor.cpp index 2d6dfc094..44e9b73e1 100644 --- a/src/osgUtil/DisplayRequirementsVisitor.cpp +++ b/src/osgUtil/DisplayRequirementsVisitor.cpp @@ -71,15 +71,3 @@ void DisplayRequirementsVisitor::apply(Node& node) traverse(node); } - -void DisplayRequirementsVisitor::apply(Geode& geode) -{ - osg::StateSet* geode_stateset = geode.getStateSet(); - if (geode_stateset) applyStateSet(*geode_stateset); - - for(unsigned int i = 0; i < geode.getNumDrawables(); i++ ) - { - osg::StateSet* stateset = geode.getDrawable(i)->getStateSet(); - if (stateset) applyStateSet(*stateset); - } -} From c901694290e86d1cce5f02afb559306ac5113077 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 3 Feb 2017 17:43:42 +0100 Subject: [PATCH 27/35] Fix handling of in-scenegraph Drawables in DrawElementTypeSimplifier --- include/osgUtil/DrawElementTypeSimplifier | 2 +- src/osgUtil/DrawElementTypeSimplifier.cpp | 12 ++---------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/include/osgUtil/DrawElementTypeSimplifier b/include/osgUtil/DrawElementTypeSimplifier index 0af5b5db4..d090eb3d7 100644 --- a/include/osgUtil/DrawElementTypeSimplifier +++ b/include/osgUtil/DrawElementTypeSimplifier @@ -34,7 +34,7 @@ class OSGUTIL_EXPORT DrawElementTypeSimplifierVisitor : public osg::NodeVisitor META_NodeVisitor(osgUtil, DrawElementTypeSimplifierVisitor); - void apply(osg::Geode& node); + void apply(osg::Geometry& geom); }; } diff --git a/src/osgUtil/DrawElementTypeSimplifier.cpp b/src/osgUtil/DrawElementTypeSimplifier.cpp index 0102bc2a5..6397f8e06 100644 --- a/src/osgUtil/DrawElementTypeSimplifier.cpp +++ b/src/osgUtil/DrawElementTypeSimplifier.cpp @@ -66,18 +66,10 @@ void DrawElementTypeSimplifier::simplify(osg::Geometry & geometry) const } } -void DrawElementTypeSimplifierVisitor::apply(osg::Geode& node) +void DrawElementTypeSimplifierVisitor::apply(osg::Geometry& geom) { DrawElementTypeSimplifier dets; - - unsigned int numDrawables = node.getNumDrawables(); - for (unsigned int i = 0; i != numDrawables; ++i) - { - osg::Geometry * geom = dynamic_cast(node.getDrawable(i)); - if (geom) dets.simplify(*geom); - } - - osg::NodeVisitor::apply((osg::Node&)node); + dets.simplify(geom); } } From 9403a4c9490d8c61e8d4dc139a7788c112153d75 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 3 Feb 2017 17:45:22 +0100 Subject: [PATCH 28/35] Fix unused parameter warning --- src/osgPlugins/sdl/ReaderWriterSDL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgPlugins/sdl/ReaderWriterSDL.cpp b/src/osgPlugins/sdl/ReaderWriterSDL.cpp index 6e8c263c9..cae0ceec5 100644 --- a/src/osgPlugins/sdl/ReaderWriterSDL.cpp +++ b/src/osgPlugins/sdl/ReaderWriterSDL.cpp @@ -22,7 +22,7 @@ class ReaderWriterSDL : public osgDB::ReaderWriter virtual const char* className() const { return "SDL Device Integration plugin"; } - virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const + virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* =NULL) const { if (file=="joystick.sdl") { From e48aa118b64868042d0b8dd0932502b0c1258043 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 3 Feb 2017 17:48:18 +0100 Subject: [PATCH 29/35] Fix handling of in-scenegraph Drawables in MeshOptimizers --- include/osgUtil/MeshOptimizers | 4 ++-- src/osgUtil/MeshOptimizers.cpp | 17 ++++------------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/include/osgUtil/MeshOptimizers b/include/osgUtil/MeshOptimizers index e0ddd1e57..1de8eefe4 100644 --- a/include/osgUtil/MeshOptimizers +++ b/include/osgUtil/MeshOptimizers @@ -33,7 +33,7 @@ public: Optimizer::OptimizationOptions options) : BaseOptimizerVisitor(optimizer, options) {} void reset(); - void apply(osg::Geode& geode); + void apply(osg::Geometry& geom); typedef std::set GeometryList; GeometryList& getGeometryList() { return _geometryList; }; protected: @@ -77,7 +77,7 @@ class OSGUTIL_EXPORT VertexCacheMissVisitor : public osg::NodeVisitor public: VertexCacheMissVisitor(unsigned cacheSize = 16); void reset(); - virtual void apply(osg::Geode& geode); + virtual void apply(osg::Geometry& geom); void doGeometry(osg::Geometry& geom); unsigned misses; unsigned triangles; diff --git a/src/osgUtil/MeshOptimizers.cpp b/src/osgUtil/MeshOptimizers.cpp index 7de7753b2..52ff810b7 100644 --- a/src/osgUtil/MeshOptimizers.cpp +++ b/src/osgUtil/MeshOptimizers.cpp @@ -38,13 +38,9 @@ void GeometryCollector::reset() _geometryList.clear(); } -void GeometryCollector::apply(Geode& geode) +void GeometryCollector::apply(Geometry& geom) { - for(unsigned int i = 0; i < geode.getNumDrawables(); ++i ) - { - osg::Geometry* geom = dynamic_cast(geode.getDrawable(i)); - if (geom) _geometryList.insert(geom); - } + _geometryList.insert(&geom); } namespace @@ -890,14 +886,9 @@ void VertexCacheMissVisitor::reset() triangles = 0; } -void VertexCacheMissVisitor::apply(Geode& geode) +void VertexCacheMissVisitor::apply(Geometry& geom) { - for(unsigned int i = 0; i < geode.getNumDrawables(); ++i ) - { - osg::Geometry* geom = dynamic_cast(geode.getDrawable(i)); - if (geom) - doGeometry(*geom); - } + doGeometry(geom); } namespace From 4e1a2d3246f836757367cf897d5ffa005418a689 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 3 Feb 2017 17:51:03 +0100 Subject: [PATCH 30/35] Fix handling of in-scenegraph Drawables in ShaderGenVisitor --- include/osgUtil/ShaderGen | 2 +- src/osgUtil/ShaderGen.cpp | 17 +++-------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/include/osgUtil/ShaderGen b/include/osgUtil/ShaderGen index 9beb717c3..f30a9cd78 100644 --- a/include/osgUtil/ShaderGen +++ b/include/osgUtil/ShaderGen @@ -67,7 +67,7 @@ public: osg::StateSet *getRootStateSet() const { return _rootStateSet.get(); } void apply(osg::Node &node); - void apply(osg::Geode &geode); + void apply(osg::Drawable &drawable); void reset(); diff --git a/src/osgUtil/ShaderGen.cpp b/src/osgUtil/ShaderGen.cpp index dbcc19eeb..41f90e462 100644 --- a/src/osgUtil/ShaderGen.cpp +++ b/src/osgUtil/ShaderGen.cpp @@ -322,24 +322,13 @@ void ShaderGenVisitor::apply(osg::Node &node) _state->popStateSet(); } -void ShaderGenVisitor::apply(osg::Geode &geode) +void ShaderGenVisitor::apply(osg::Drawable &drawable) { - osg::StateSet *stateSet = geode.getStateSet(); + osg::StateSet *stateSet = drawable.getStateSet(); if (stateSet) _state->pushStateSet(stateSet); - for (unsigned int i=0; igetStateSet(); - if (ss) - _state->pushStateSet(ss); - - update(drawable); - - if (ss) - _state->popStateSet(); - } + update(&drawable); if (stateSet) _state->popStateSet(); From e38c3d0303cdfb229820f40246afe943f0304de1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 3 Feb 2017 17:55:32 +0100 Subject: [PATCH 31/35] Fix handling of in-scenegraph Drawables in SmoothingVisitor, TriStripVisitor and GraphicsCostEstimator --- include/osgUtil/SmoothingVisitor | 4 ++-- include/osgUtil/TriStripVisitor | 2 +- src/osg/GraphicsCostEstimator.cpp | 22 ++++++---------------- src/osgUtil/SmoothingVisitor.cpp | 8 ++------ src/osgUtil/TriStripVisitor.cpp | 8 ++------ 5 files changed, 13 insertions(+), 31 deletions(-) diff --git a/include/osgUtil/SmoothingVisitor b/include/osgUtil/SmoothingVisitor index 7afeda8ca..cccbb10d0 100644 --- a/include/osgUtil/SmoothingVisitor +++ b/include/osgUtil/SmoothingVisitor @@ -36,8 +36,8 @@ class OSGUTIL_EXPORT SmoothingVisitor : public osg::NodeVisitor /// smooth geoset by creating per vertex normals. static void smooth(osg::Geometry& geoset, double creaseAngle=osg::PI); - /// apply smoothing method to all geode geosets. - virtual void apply(osg::Geode& geode); + /// apply smoothing method to all geometries. + virtual void apply(osg::Geometry& geom); /// set the maximum angle, in radians, at which angle between adjacent triangles that normals are smoothed /// for edges that greater the shared vertices are duplicated diff --git a/include/osgUtil/TriStripVisitor b/include/osgUtil/TriStripVisitor index b73c60bdf..76ceccf0b 100644 --- a/include/osgUtil/TriStripVisitor +++ b/include/osgUtil/TriStripVisitor @@ -53,7 +53,7 @@ class OSGUTIL_EXPORT TriStripVisitor : public BaseOptimizerVisitor void stripify(); /// Accumulate the Geometry drawables to make into strips. - virtual void apply(osg::Geode& geode); + virtual void apply(osg::Geometry& geom); inline void setCacheSize( unsigned int size ) { diff --git a/src/osg/GraphicsCostEstimator.cpp b/src/osg/GraphicsCostEstimator.cpp index 36fec361e..b5b9895d8 100644 --- a/src/osg/GraphicsCostEstimator.cpp +++ b/src/osg/GraphicsCostEstimator.cpp @@ -205,15 +205,10 @@ public: traverse(node); } - virtual void apply(osg::Geode& geode) + virtual void apply(osg::Geometry& geom) { - apply(geode.getStateSet()); - for(unsigned int i=0; igetStateSet()); - osg::Geometry* geometry = geode.getDrawable(i)->asGeometry(); - if (geometry) apply(geometry); - } + apply(geom.getStateSet()); + apply(&geom); } void apply(osg::StateSet* stateset) @@ -282,15 +277,10 @@ public: traverse(node); } - virtual void apply(osg::Geode& geode) + virtual void apply(osg::Geometry& geom) { - apply(geode.getStateSet()); - for(unsigned int i=0; igetStateSet()); - osg::Geometry* geometry = geode.getDrawable(i)->asGeometry(); - if (geometry) apply(geometry); - } + apply(geom.getStateSet()); + apply(&geom); } void apply(osg::StateSet* stateset) diff --git a/src/osgUtil/SmoothingVisitor.cpp b/src/osgUtil/SmoothingVisitor.cpp index 2112fda6c..89eeb45b5 100644 --- a/src/osgUtil/SmoothingVisitor.cpp +++ b/src/osgUtil/SmoothingVisitor.cpp @@ -702,11 +702,7 @@ void SmoothingVisitor::smooth(osg::Geometry& geom, double creaseAngle) } -void SmoothingVisitor::apply(osg::Geode& geode) +void SmoothingVisitor::apply(osg::Geometry& geom) { - for(unsigned int i = 0; i < geode.getNumDrawables(); i++ ) - { - osg::Geometry* geom = dynamic_cast(geode.getDrawable(i)); - if (geom) smooth(*geom, _creaseAngle); - } + smooth(geom, _creaseAngle); } diff --git a/src/osgUtil/TriStripVisitor.cpp b/src/osgUtil/TriStripVisitor.cpp index 24ae1ea00..074bfb890 100644 --- a/src/osgUtil/TriStripVisitor.cpp +++ b/src/osgUtil/TriStripVisitor.cpp @@ -629,11 +629,7 @@ void TriStripVisitor::stripify() } } -void TriStripVisitor::apply(Geode& geode) +void TriStripVisitor::apply(Geometry& geom) { - for(unsigned int i = 0; i < geode.getNumDrawables(); ++i ) - { - osg::Geometry* geom = dynamic_cast(geode.getDrawable(i)); - if (geom) _geometryList.insert(geom); - } + _geometryList.insert(&geom); } From fdf6d55b9da38e7a77b8557c4562767e89b8e33b Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 3 Feb 2017 18:01:08 +0100 Subject: [PATCH 32/35] Fix handling of in-scenegraph Drawables in osgShadow --- src/osgShadow/OccluderGeometry.cpp | 17 ++++------------- src/osgShadow/ViewDependentShadowMap.cpp | 12 +++--------- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/src/osgShadow/OccluderGeometry.cpp b/src/osgShadow/OccluderGeometry.cpp index 178e17041..4189f0f12 100644 --- a/src/osgShadow/OccluderGeometry.cpp +++ b/src/osgShadow/OccluderGeometry.cpp @@ -77,22 +77,13 @@ public: if (transform.getStateSet()) popState(); } - void apply(osg::Geode& geode) + void apply(osg::Drawable& drawable) { - if (geode.getStateSet()) pushState(geode.getStateSet()); + if (drawable.getStateSet()) pushState(drawable.getStateSet()); - for(unsigned int i=0; igetStateSet()) pushState(drawable->getStateSet()); - - apply(geode.getDrawable(i)); - - if (drawable->getStateSet()) popState(); - } - - if (geode.getStateSet()) popState(); + if (drawable.getStateSet()) popState(); } void pushState(osg::StateSet* stateset) diff --git a/src/osgShadow/ViewDependentShadowMap.cpp b/src/osgShadow/ViewDependentShadowMap.cpp index 6336662aa..f72f2ce15 100644 --- a/src/osgShadow/ViewDependentShadowMap.cpp +++ b/src/osgShadow/ViewDependentShadowMap.cpp @@ -274,20 +274,14 @@ public: popCurrentMask(); } - void apply(osg::Geode& node) + void apply(osg::Drawable& drawable) { - if (isCulled(node)) return; + if (isCulled(drawable)) return; // push the culling mode. pushCurrentMask(); - for(unsigned int i=0; igetBoundingBox()); - } - } + updateBound(drawable.getBoundingBox()); // pop the culling mode. popCurrentMask(); From 6deefe0646c6aa426371042a4951ba58d30e0f98 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 3 Feb 2017 18:10:37 +0100 Subject: [PATCH 33/35] Remove seemingly redundant handling of Geode in GLObjectsVisitor --- include/osgUtil/GLObjectsVisitor | 5 ----- src/osgUtil/GLObjectsVisitor.cpp | 22 ---------------------- 2 files changed, 27 deletions(-) diff --git a/include/osgUtil/GLObjectsVisitor b/include/osgUtil/GLObjectsVisitor index e2a075145..b9a130f3e 100644 --- a/include/osgUtil/GLObjectsVisitor +++ b/include/osgUtil/GLObjectsVisitor @@ -94,11 +94,6 @@ class OSGUTIL_EXPORT GLObjectsVisitor : public osg::NodeVisitor /** Simply traverse using standard NodeVisitor traverse method.*/ virtual void apply(osg::Node& node); - /** For each Geode visited set the display list usage according to the - * _displayListMode. - */ - virtual void apply(osg::Geode& node); - void apply(osg::Drawable& drawable); void apply(osg::StateSet& stateset); diff --git a/src/osgUtil/GLObjectsVisitor.cpp b/src/osgUtil/GLObjectsVisitor.cpp index 3731cfd34..b194b7990 100644 --- a/src/osgUtil/GLObjectsVisitor.cpp +++ b/src/osgUtil/GLObjectsVisitor.cpp @@ -53,28 +53,6 @@ void GLObjectsVisitor::apply(osg::Node& node) } } -void GLObjectsVisitor::apply(osg::Geode& node) -{ - bool programSetBefore = _lastCompiledProgram.valid(); - - if (node.getStateSet()) - { - apply(*(node.getStateSet())); - } - - traverse(node); - - bool programSetAfter = _lastCompiledProgram.valid(); - if (!programSetBefore && programSetAfter) - { - osg::State* state = _renderInfo.getState(); - osg::GLExtensions* extensions = state->get(); - extensions->glUseProgram(0); - state->setLastAppliedProgramObject(0); - _lastCompiledProgram = 0; - } -} - void GLObjectsVisitor::apply(osg::Drawable& drawable) { if (_drawablesAppliedSet.count(&drawable)!=0) return; From 378809f3a8f0f85a831b01c6d083f733d12ea78b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 13 Feb 2017 16:53:37 +0000 Subject: [PATCH 34/35] Added osgvolume command line option "--bg r g b a" to enable customization of the window background colour --- examples/osgvolume/osgvolume.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/osgvolume/osgvolume.cpp b/examples/osgvolume/osgvolume.cpp index e0df891b9..0390ca9f0 100644 --- a/examples/osgvolume/osgvolume.cpp +++ b/examples/osgvolume/osgvolume.cpp @@ -431,6 +431,7 @@ int main( int argc, char **argv ) arguments.getApplicationUsage()->addCommandLineOption("--sd ","Short hand for --sequence-length"); arguments.getApplicationUsage()->addCommandLineOption("--sdwm ","Set the SampleDensityWhenMovingProperty to specified value"); arguments.getApplicationUsage()->addCommandLineOption("--lod","Enable techniques to reduce the level of detail when moving."); + arguments.getApplicationUsage()->addCommandLineOption("--bg r g b a","Set the window background color(r,g,b,a) with each component the 0 to 1.0 range"); // arguments.getApplicationUsage()->addCommandLineOption("--raw ","read a raw image data"); // construct the viewer. @@ -457,7 +458,6 @@ int main( int argc, char **argv ) // add stateset manipulator viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); - viewer.getCamera()->setClearColor(osg::Vec4(0.0f,0.0f,0.0f,0.0f)); // if user request help write it out to cout. if (arguments.read("-h") || arguments.read("--help")) @@ -470,6 +470,10 @@ int main( int argc, char **argv ) while (arguments.read("-o",outputFile)) {} + osg::Vec4 bgColor(0.0f,0.0f, 0.0f, 0.0f); + while(arguments.read("--bg", bgColor.r(), bgColor.g(), bgColor.b(), bgColor.a())) {} + viewer.getCamera()->setClearColor(bgColor); + osg::ref_ptr transferFunction; std::string tranferFunctionFile; From d3a925e675c7a5f58202da3d83ba9c4acecbd562 Mon Sep 17 00:00:00 2001 From: blobfish Date: Tue, 14 Feb 2017 23:46:27 -0500 Subject: [PATCH 35/35] osgManipulator: Constraint: snap_point_to_grid wants Vec3d instead of Vec3 --- src/osgManipulator/Constraint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgManipulator/Constraint.cpp b/src/osgManipulator/Constraint.cpp index b62a4d90d..9e8660648 100644 --- a/src/osgManipulator/Constraint.cpp +++ b/src/osgManipulator/Constraint.cpp @@ -33,7 +33,7 @@ osg::Vec3d snap_point_to_grid(const osg::Vec3d& point, const osg::Vec3d& origin, scale[1] = spacing[1] ? round_to_nearest_int((point[1] - origin[1]) / spacing[1]) : 1.0; scale[2] = spacing[2] ? round_to_nearest_int((point[2] - origin[2]) / spacing[2]) : 1.0; osg::Vec3d snappedPoint = origin; - snappedPoint += osg::Vec3(scale[0]*spacing[0],scale[1]*spacing[1],scale[2]*spacing[2]); + snappedPoint += osg::Vec3d(scale[0]*spacing[0],scale[1]*spacing[1],scale[2]*spacing[2]); return snappedPoint; }