diff --git a/VisualStudio/osgUtil/osgUtil.dsp b/VisualStudio/osgUtil/osgUtil.dsp index 95a8cbaed..a7352108c 100755 --- a/VisualStudio/osgUtil/osgUtil.dsp +++ b/VisualStudio/osgUtil/osgUtil.dsp @@ -239,6 +239,10 @@ SOURCE=..\..\src\osgUtil\SmoothingVisitor.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osgUtil\Statistics.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osgUtil\TangentSpaceGenerator.cpp # End Source File # Begin Source File diff --git a/examples/osgcamera/osgcamera.cpp b/examples/osgcamera/osgcamera.cpp index fdcd22fa4..e287f0922 100644 --- a/examples/osgcamera/osgcamera.cpp +++ b/examples/osgcamera/osgcamera.cpp @@ -36,10 +36,73 @@ int main( int argc, char **argv ) viewer.setCameraManipulator(new osgGA::TrackballManipulator()); viewer.getCamera()->setClearColor(osg::Vec4f(0.6f,0.6f,0.8f,1.0f)); +#if 1 + + osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); + if (!wsi) + { + osg::notify(osg::NOTICE)<<"View::setUpViewAcrossAllScreens() : Error, no WindowSystemInterface available, cannot create windows."<getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height); + + osg::ref_ptr traits = new osg::GraphicsContext::Traits; + traits->x = 0; + traits->y = 0; + traits->width = width; + traits->height = height; +#if 0 + traits->windowDecoration = false; +#else + traits->windowDecoration = true; +#endif + traits->doubleBuffer = true; + traits->sharedContext = 0; + + osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits.get()); + + osgViewer::GraphicsWindow* gw = dynamic_cast(gc.get()); + if (gw) + { + osg::notify(osg::NOTICE)<<" GraphicsWindow has been created successfully."<getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, width, height ); + } + else + { + osg::notify(osg::NOTICE)<<" GraphicsWindow has not been created successfully."< camera = new osg::Camera; + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport((i*width)/numCameras,(i*height)/numCameras, width/numCameras, height/numCameras)); + GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + + viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::scale(aspectRatioScale,1.0,1.0)); + } + + viewer.setUpRenderingSupport(); + viewer.assignSceneDataToCameras(); + +#else + viewer.setUpViewAcrossAllScreens(); + +#endif + viewer.realize(); - bool limitNumberOfFrames = true; + gw->requestWarpPointer(100,100); + + bool limitNumberOfFrames = false; unsigned int numFrames = 0; unsigned int maxFrames = 10; diff --git a/examples/osghangglide/GliderManipulator.cpp b/examples/osghangglide/GliderManipulator.cpp index 2cb3b2bd0..a8d421aaa 100644 --- a/examples/osghangglide/GliderManipulator.cpp +++ b/examples/osghangglide/GliderManipulator.cpp @@ -7,7 +7,7 @@ using namespace osgGA; GliderManipulator::GliderManipulator() { _modelScale = 0.01f; - _velocity = 0.0f; + _velocity = 0.2f; _yawMode = YAW_AUTOMATICALLY_WHEN_BANKED; _distance = 1.0f; @@ -74,7 +74,7 @@ void GliderManipulator::init(const GUIEventAdapter& ea,GUIActionAdapter& us) us.requestContinuousUpdate(false); - _velocity = 0.0f; + _velocity = 0.2f; if (ea.getEventType()!=GUIEventAdapter::RESIZE) { diff --git a/examples/osghangglide/osghangglide.cpp b/examples/osghangglide/osghangglide.cpp index 3cd5776f2..830f23379 100644 --- a/examples/osghangglide/osghangglide.cpp +++ b/examples/osghangglide/osghangglide.cpp @@ -143,10 +143,71 @@ int main( int argc, char **argv ) viewer.setSceneData( rootnode ); - // set up the value with sensible default event handlers. - viewer.setUpViewAcrossAllScreens(); +#if 0 + + osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); + if (!wsi) + { + osg::notify(osg::NOTICE)<<"View::setUpViewAcrossAllScreens() : Error, no WindowSystemInterface available, cannot create windows."<getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height); + + width -= 500; + height -= 500; + + osg::ref_ptr traits = new osg::GraphicsContext::Traits; + traits->x = 500; + traits->y = 500; + traits->width = width; + traits->height = height; +#if 0 + traits->windowDecoration = false; +#else + traits->windowDecoration = true; +#endif + traits->doubleBuffer = true; + traits->sharedContext = 0; + + osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits.get()); + + osgViewer::GraphicsWindow* gw = dynamic_cast(gc.get()); + if (gw) + { + osg::notify(osg::NOTICE)<<" GraphicsWindow has been created successfully."<getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, width, height ); + } + else + { + osg::notify(osg::NOTICE)<<" GraphicsWindow has not been created successfully."< camera = new osg::Camera; + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport((i*width)/numCameras,(i*height)/numCameras, width/numCameras, height/numCameras)); + GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + + viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::scale(aspectRatioScale,1.0,1.0)); + } + + viewer.setUpRenderingSupport(); + viewer.assignSceneDataToCameras(); + +#else + + viewer.setUpViewAcrossAllScreens(); + +#endif - // create the windows and run the threads. viewer.realize(); while( !viewer.done() ) diff --git a/examples/osgparametric/osgparametric.cpp b/examples/osgparametric/osgparametric.cpp index e91f4d05d..f659fa6e3 100644 --- a/examples/osgparametric/osgparametric.cpp +++ b/examples/osgparametric/osgparametric.cpp @@ -11,6 +11,7 @@ #include #include +#include #include @@ -57,10 +58,26 @@ char vertexShaderSource_texture[] = "\n" " gl_TexCoord[0] = gl_Vertex; \n" " vec4 vert = gl_Vertex; \n" - " vert.z = texture2D( vertexTexture, gl_TexCoord[0].xy).x*0.0001; \n" + " vert.z = texture2D( vertexTexture, gl_TexCoord[0].xy).x*0.1; \n" " gl_Position = gl_ModelViewProjectionMatrix * vert;\n" "}\n"; +////////////////////////////////////////////////////////////////// +// vertex shader using texture read +char vertexShaderSource_texture2[] = + "uniform sampler2D vertexTexture; \n" + "uniform sampler2D vertexTexture2; \n" + "uniform float osg_FrameTime;\n" + "\n" + "void main(void) \n" + "{ \n" + "\n" + " gl_TexCoord[0] = gl_Vertex; \n" + " vec4 vert = gl_Vertex; \n" + " float r = 1.0 + 0.5 * sin(osg_FrameTime);\n" + " vert.z = (texture2D( vertexTexture, gl_TexCoord[0].xy).x * (1-r) + texture2D( vertexTexture2, gl_TexCoord[0].xy).x * r)*0.1; \n" + " gl_Position = gl_ModelViewProjectionMatrix * vert;\n" + "}\n"; ////////////////////////////////////////////////////////////////// // fragment shader @@ -73,7 +90,33 @@ char fragmentShaderSource[] = " gl_FragColor = texture2D( baseTexture, gl_TexCoord[0].xy); \n" "}\n"; - +#if 0 +char fragmentShaderNormalSource[] = + "uniform sampler2D baseTexture; \n" + "uniform sampler2D vertexTexture; \n" + "\n" + "void main(void) \n" + "{ \n" + " const float dx = 0.0010; \n" + " const float dy = 0.0010; \n" + " float dz_dx = texture2D( vertexTexture, gl_TexCoord[0].xy + vec2(dx,0.0)).x - texture2D( vertexTexture, gl_TexCoord[0].xy + vec2(-dx,0.0)).x; \n" + " float dz_dy = texture2D( vertexTexture, gl_TexCoord[0].xy + vec2(0.0,dy)).x - texture2D( vertexTexture, gl_TexCoord[0].xy + vec2(0.0,-dy)).x; \n" + " vec3 normal = normalize(vec3(-dz_dx, -dz_dy, dx*50));\n" + " \n" + " gl_FragColor = vec4(normal.z,normal.z,normal.z,1.0); \n" + "}\n"; +#else +char fragmentShaderNormalSource[] = + "uniform sampler2D baseTexture; \n" + "uniform sampler2D vertexTexture; \n" + "\n" + "void main(void) \n" + "{ \n" + " vec3 normal = normalize(texture2D( baseTexture, gl_TexCoord[0].xy).xyz);\n" + " \n" + " gl_FragColor = vec4(normal.z,normal.z,normal.z,1.0); \n" + "}\n"; +#endif class UniformVarying : public osg::Uniform::Callback { @@ -85,7 +128,7 @@ class UniformVarying : public osg::Uniform::Callback } }; -osg::Node* createModel(const std::string& shader, const std::string& textureFileName, const std::string& terrainFileName) +osg::Node* createModel(const std::string& shader, const std::string& textureFileName, const std::string& terrainFileName, const std::string& terrainFileName2, unsigned int cacheSize, unsigned int maxSize, bool joinStrips, const std::string& mesh) { osg::Geode* geode = new osg::Geode; @@ -131,8 +174,6 @@ osg::Node* createModel(const std::string& shader, const std::string& textureFile } else if (shader=="texture") { - osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource_texture); - program->addShader(vertex_shader); osg::Image* image = 0; @@ -166,17 +207,54 @@ osg::Node* createModel(const std::string& shader, const std::string& textureFile vertexTexture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::NEAREST); vertexTexture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::NEAREST); + vertexTexture->setInternalFormat(GL_LUMINANCE_FLOAT32_ATI); + + vertexTexture->setResizeNonPowerOfTwoHint(false); stateset->setTextureAttributeAndModes(1,vertexTexture); osg::Uniform* vertexTextureSampler = new osg::Uniform("vertexTexture",1); stateset->addUniform(vertexTextureSampler); + if (!terrainFileName2.empty()) + { + osg::Image* image2 = osgDB::readImageFile(terrainFileName2); + osg::Texture2D* vertexTexture2 = new osg::Texture2D(image2); + + + vertexTexture2->setFilter(osg::Texture::MIN_FILTER,osg::Texture::NEAREST); + vertexTexture2->setFilter(osg::Texture::MAG_FILTER,osg::Texture::NEAREST); + + vertexTexture2->setInternalFormat(GL_LUMINANCE_FLOAT32_ATI); + + vertexTexture2->setResizeNonPowerOfTwoHint(false); + stateset->setTextureAttributeAndModes(2,vertexTexture2); + + osg::Uniform* vertexTextureSampler2 = new osg::Uniform("vertexTexture2",2); + stateset->addUniform(vertexTextureSampler2); + + } + } - osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource); - program->addShader(fragment_shader); + if (terrainFileName2.empty()) + { + osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderNormalSource); + program->addShader(fragment_shader); + osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource_texture); + program->addShader(vertex_shader); + } + else + { + + osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource); + program->addShader(fragment_shader); + + osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource_texture2); + program->addShader(vertex_shader); + } + osg::Texture2D* texture = new osg::Texture2D(osgDB::readImageFile(textureFileName)); stateset->setTextureAttributeAndModes(0,texture); @@ -209,20 +287,215 @@ osg::Node* createModel(const std::string& shader, const std::string& textureFile geom->setVertexArray(vertices); - for(iy=0; iyaddPrimitiveSet(elements); + elements->dirty(); + + for(unsigned int is=0; issize() > maxSize) + { + osg::notify(osg::NOTICE)<<"elements->size() = "<size()<size(); + + index=0; + elements = new osg::DrawElementsUInt(GL_TRIANGLES); + geom->addPrimitiveSet(elements); + elements->dirty(); + + } + + if (rightToLeft) + { + + index = iy * num_x + is; + + for(unsigned int ix = 0; ixsize(); + osg::notify(osg::NOTICE)<<"elements->size() = "<size()<dirty(); + unsigned int element_no = 0; + for(iy=0; iyaddPrimitiveSet(elements); + osg::notify(osg::NOTICE)<<"elements->size() = "<size()<addPrimitiveSet(elements); } + else + { - // geom->setUseVertexBufferObjects(true); + if (cacheSize) + { + bool needToJoin = false; + unsigned int index=0; + osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_TRIANGLE_STRIP); + geom->addPrimitiveSet(elements); + elements->dirty(); + + for(unsigned int is=0; issize() > maxSize) + { + osg::notify(osg::NOTICE)<<"elements->size() = "<size()<size(); + + needToJoin = false; + index=0; + elements = new osg::DrawElementsUInt(GL_TRIANGLE_STRIP); + geom->addPrimitiveSet(elements); + elements->dirty(); + + } + + if (needToJoin) (*elements).push_back(elements->back()); + + if (rightToLeft) + { + + index = iy * num_x + is; + + if (needToJoin) (*elements).push_back(index + num_x); + + for(unsigned int ix = 0; ixsize(); + } + else + { + osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_TRIANGLE_STRIP); + elements->dirty(); + geom->addPrimitiveSet(elements); + bool needToJoin = false; + unsigned int index=0; + for(iy=0; iysetUseVertexBufferObjects(true); +#else + geom->setUseVertexBufferObjects(false); +#endif return geode; } @@ -252,6 +525,21 @@ int main(int argc, char *argv[]) std::string terrainFileName(""); while(arguments.read("-d",terrainFileName)) {} + std::string terrainFileName2(""); + while(arguments.read("-d2",terrainFileName2)) {} + + unsigned int cacheSize = 0; + while(arguments.read("--cache",cacheSize)) {} + + unsigned int maxSize = 2048; + while(arguments.read("--max",maxSize)) {} + + std::string mesh("strip"); + while(arguments.read("--mesh",mesh)) {} + + bool joinStrips = false; + while(arguments.read("--join")) { joinStrips = true; } + // get details on keyboard and mouse bindings used by the viewer. viewer.getUsage(*arguments.getApplicationUsage()); @@ -273,7 +561,7 @@ int main(int argc, char *argv[]) } // load the nodes from the commandline arguments. - osg::Node* model = createModel(shader,textureFileName,terrainFileName); + osg::Node* model = createModel(shader,textureFileName,terrainFileName,terrainFileName2, cacheSize, maxSize, joinStrips,mesh); if (!model) { return 1; diff --git a/examples/osgshaderterrain/osgshaderterrain.cpp b/examples/osgshaderterrain/osgshaderterrain.cpp index 829dbe4c5..b6ea65d88 100644 --- a/examples/osgshaderterrain/osgshaderterrain.cpp +++ b/examples/osgshaderterrain/osgshaderterrain.cpp @@ -31,442 +31,7 @@ // for the grid data.. #include "../osghangglide/terrain_coords.h" -// class to create the forest and manage the movement between various techniques. -class ForestTechniqueManager : public osg::Referenced -{ -public: - - ForestTechniqueManager() {} - - class Tree : public osg::Referenced - { - public: - - Tree(): - _color(255,255,255,255), - _width(1.0f), - _height(1.0f), - _type(0) {} - - Tree(const osg::Vec3& position, const osg::Vec4ub& color, float width, float height, unsigned int type): - _position(position), - _color(color), - _width(width), - _height(height), - _type(type) {} - - osg::Vec3 _position; - osg::Vec4ub _color; - float _width; - float _height; - unsigned int _type; - }; - - typedef std::vector< osg::ref_ptr > TreeList; - - class Cell : public osg::Referenced - { - public: - typedef std::vector< osg::ref_ptr > CellList; - - Cell():_parent(0) {} - Cell(osg::BoundingBox& bb):_parent(0), _bb(bb) {} - - void addCell(Cell* cell) { cell->_parent=this; _cells.push_back(cell); } - - void addTree(Tree* tree) { _trees.push_back(tree); } - - void addTrees(const TreeList& trees) { _trees.insert(_trees.end(),trees.begin(),trees.end()); } - - void computeBound(); - - bool contains(const osg::Vec3& position) const { return _bb.contains(position); } - - bool divide(unsigned int maxNumTreesPerCell=10); - - bool devide(bool xAxis, bool yAxis, bool zAxis); - - void bin(); - - - Cell* _parent; - osg::BoundingBox _bb; - CellList _cells; - TreeList _trees; - - }; - - float random(float min,float max) { return min + (max-min)*(float)rand()/(float)RAND_MAX; } - int random(int min,int max) { return min + (int)((float)(max-min)*(float)rand()/(float)RAND_MAX); } - - osg::Geode* createTerrain(const osg::Vec3& origin, const osg::Vec3& size); - - void createTreeList(osg::Node* terrain,const osg::Vec3& origin, const osg::Vec3& size,unsigned int numTreesToCreate,TreeList& trees); - - osg::Geometry* createOrthogonalQuadsNoColor( const osg::Vec3& pos, float w, float h ); - - osg::Node* createShaderGraph(Cell* cell,osg::StateSet* stateset); - - osg::Node* createScene(unsigned int numTreesToCreates); - - -}; - -// event handler to capture keyboard events and use them to advance the technique used for rendering -void ForestTechniqueManager::Cell::computeBound() -{ - _bb.init(); - for(CellList::iterator citr=_cells.begin(); - citr!=_cells.end(); - ++citr) - { - (*citr)->computeBound(); - _bb.expandBy((*citr)->_bb); - } - - for(TreeList::iterator titr=_trees.begin(); - titr!=_trees.end(); - ++titr) - { - _bb.expandBy((*titr)->_position); - } -} - -bool ForestTechniqueManager::Cell::divide(unsigned int maxNumTreesPerCell) -{ - - if (_trees.size()<=maxNumTreesPerCell) return false; - - computeBound(); - - float radius = _bb.radius(); - float divide_distance = radius*0.7f; - if (devide((_bb.xMax()-_bb.xMin())>divide_distance,(_bb.yMax()-_bb.yMin())>divide_distance,(_bb.zMax()-_bb.zMin())>divide_distance)) - { - // recusively divide the new cells till maxNumTreesPerCell is met. - for(CellList::iterator citr=_cells.begin(); - citr!=_cells.end(); - ++citr) - { - (*citr)->divide(maxNumTreesPerCell); - } - return true; - } - else - { - return false; - } -} - -bool ForestTechniqueManager::Cell::devide(bool xAxis, bool yAxis, bool zAxis) -{ - if (!(xAxis || yAxis || zAxis)) return false; - - if (_cells.empty()) - _cells.push_back(new Cell(_bb)); - - if (xAxis) - { - unsigned int numCellsToDivide=_cells.size(); - for(unsigned int i=0;i_bb); - - float xCenter = (orig_cell->_bb.xMin()+orig_cell->_bb.xMax())*0.5f; - orig_cell->_bb.xMax() = xCenter; - new_cell->_bb.xMin() = xCenter; - - _cells.push_back(new_cell); - } - } - - if (yAxis) - { - unsigned int numCellsToDivide=_cells.size(); - for(unsigned int i=0;i_bb); - - float yCenter = (orig_cell->_bb.yMin()+orig_cell->_bb.yMax())*0.5f; - orig_cell->_bb.yMax() = yCenter; - new_cell->_bb.yMin() = yCenter; - - _cells.push_back(new_cell); - } - } - - if (zAxis) - { - unsigned int numCellsToDivide=_cells.size(); - for(unsigned int i=0;i_bb); - - float zCenter = (orig_cell->_bb.zMin()+orig_cell->_bb.zMax())*0.5f; - orig_cell->_bb.zMax() = zCenter; - new_cell->_bb.zMin() = zCenter; - - _cells.push_back(new_cell); - } - } - - bin(); - - return true; - -} - -void ForestTechniqueManager::Cell::bin() -{ - // put trees in apprpriate cells. - TreeList treesNotAssigned; - for(TreeList::iterator titr=_trees.begin(); - titr!=_trees.end(); - ++titr) - { - Tree* tree = titr->get(); - bool assigned = false; - for(CellList::iterator citr=_cells.begin(); - citr!=_cells.end() && !assigned; - ++citr) - { - if ((*citr)->contains(tree->_position)) - { - (*citr)->addTree(tree); - assigned = true; - } - } - if (!assigned) treesNotAssigned.push_back(tree); - } - - // put the unassigned trees back into the original local tree list. - _trees.swap(treesNotAssigned); - - - // prune empty cells. - CellList cellsNotEmpty; - for(CellList::iterator citr=_cells.begin(); - citr!=_cells.end(); - ++citr) - { - if (!((*citr)->_trees.empty())) - { - cellsNotEmpty.push_back(*citr); - } - } - _cells.swap(cellsNotEmpty); - - -} - - -void ForestTechniqueManager::createTreeList(osg::Node* terrain,const osg::Vec3& origin, const osg::Vec3& size,unsigned int numTreesToCreate,TreeList& trees) -{ - - float max_TreeHeight = sqrtf(size.length2()/(float)numTreesToCreate); - float max_TreeWidth = max_TreeHeight*0.5f; - - float min_TreeHeight = max_TreeHeight*0.3f; - float min_TreeWidth = min_TreeHeight*0.5f; - - trees.reserve(trees.size()+numTreesToCreate); - - - for(unsigned int i=0;i_position.set(random(origin.x(),origin.x()+size.x()),random(origin.y(),origin.y()+size.y()),origin.z()); - tree->_color.set(random(128,255),random(128,255),random(128,255),255); - tree->_width = random(min_TreeWidth,max_TreeWidth); - tree->_height = random(min_TreeHeight,max_TreeHeight); - tree->_type = 0; - - if (terrain) - { - osgUtil::IntersectVisitor iv; - osg::ref_ptr segDown = new osg::LineSegment; - - segDown->set(tree->_position,tree->_position+osg::Vec3(0.0f,0.0f,size.z())); - iv.addLineSegment(segDown.get()); - - terrain->accept(iv); - - if (iv.hits()) - { - osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segDown.get()); - if (!hitList.empty()) - { - osg::Vec3 ip = hitList.front().getWorldIntersectPoint(); - osg::Vec3 np = hitList.front().getWorldIntersectNormal(); - tree->_position = ip; - } - } - } - - trees.push_back(tree); - } -} - -osg::Geometry* ForestTechniqueManager::createOrthogonalQuadsNoColor( const osg::Vec3& pos, float w, float h) -{ - // set up the coords - osg::Vec3Array& v = *(new osg::Vec3Array(8)); - osg::Vec2Array& t = *(new osg::Vec2Array(8)); - - float rotation = random(0.0f,osg::PI/2.0f); - float sw = sinf(rotation)*w*0.5f; - float cw = cosf(rotation)*w*0.5f; - - v[0].set(pos.x()-sw,pos.y()-cw,pos.z()+0.0f); - v[1].set(pos.x()+sw,pos.y()+cw,pos.z()+0.0f); - v[2].set(pos.x()+sw,pos.y()+cw,pos.z()+h); - v[3].set(pos.x()-sw,pos.y()-cw,pos.z()+h); - - v[4].set(pos.x()-cw,pos.y()+sw,pos.z()+0.0f); - v[5].set(pos.x()+cw,pos.y()-sw,pos.z()+0.0f); - v[6].set(pos.x()+cw,pos.y()-sw,pos.z()+h); - v[7].set(pos.x()-cw,pos.y()+sw,pos.z()+h); - - t[0].set(0.0f,0.0f); - t[1].set(1.0f,0.0f); - t[2].set(1.0f,1.0f); - t[3].set(0.0f,1.0f); - - t[4].set(0.0f,0.0f); - t[5].set(1.0f,0.0f); - t[6].set(1.0f,1.0f); - t[7].set(0.0f,1.0f); - - osg::Geometry *geom = new osg::Geometry; - - geom->setVertexArray( &v ); - - geom->setTexCoordArray( 0, &t ); - - geom->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,8) ); - - return geom; -} - -class ShaderGeometry : public osg::Drawable -{ - public: - ShaderGeometry() { setUseDisplayList(false); } - - /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ - ShaderGeometry(const ShaderGeometry& ShaderGeometry,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY): - osg::Drawable(ShaderGeometry,copyop) {} - - META_Object(osg,ShaderGeometry) - - typedef std::vector PositionSizeList; - - virtual void drawImplementation(osg::RenderInfo& renderInfo) const - { - for(PositionSizeList::const_iterator itr = _trees.begin(); - itr != _trees.end(); - ++itr) - { - glColor4fv(itr->ptr()); - _geometry->draw(renderInfo); - } - } - - virtual osg::BoundingBox computeBound() const - { - osg::BoundingBox geom_box = _geometry->getBound(); - osg::BoundingBox bb; - for(PositionSizeList::const_iterator itr = _trees.begin(); - itr != _trees.end(); - ++itr) - { - bb.expandBy(geom_box.corner(0)*(*itr)[3] + - osg::Vec3( (*itr)[0], (*itr)[1], (*itr)[2] )); - bb.expandBy(geom_box.corner(7)*(*itr)[3] + - osg::Vec3( (*itr)[0], (*itr)[1], (*itr)[2] )); - } - return bb; - } - - void setGeometry(osg::Geometry* geometry) - { - _geometry = geometry; - } - - void addTree(ForestTechniqueManager::Tree& tree) - { - _trees.push_back(osg::Vec4(tree._position.x(), tree._position.y(), tree._position.z(), tree._height)); - } - - osg::ref_ptr _geometry; - - PositionSizeList _trees; - - protected: - - virtual ~ShaderGeometry() {} - -}; - -osg::Geometry* shared_geometry = 0; - -osg::Node* ForestTechniqueManager::createShaderGraph(Cell* cell,osg::StateSet* stateset) -{ - if (shared_geometry==0) - { - shared_geometry = createOrthogonalQuadsNoColor(osg::Vec3(0.0f,0.0f,0.0f),1.0f,1.0f); - //shared_geometry->setUseDisplayList(false); - } - - - bool needGroup = !(cell->_cells.empty()); - bool needTrees = !(cell->_trees.empty()); - - osg::Geode* geode = 0; - osg::Group* group = 0; - - if (needTrees) - { - geode = new osg::Geode; - - ShaderGeometry* shader_geometry = new ShaderGeometry; - shader_geometry->setGeometry(shared_geometry); - - - for(TreeList::iterator itr=cell->_trees.begin(); - itr!=cell->_trees.end(); - ++itr) - { - Tree& tree = **itr; - shader_geometry->addTree(tree); - - } - - geode->setStateSet(stateset); - geode->addDrawable(shader_geometry); - } - - if (needGroup) - { - group = new osg::Group; - for(Cell::CellList::iterator itr=cell->_cells.begin(); - itr!=cell->_cells.end(); - ++itr) - { - group->addChild(createShaderGraph(itr->get(),stateset)); - } - - if (geode) group->addChild(geode); - - } - if (group) return group; - else return geode; -} - -osg::Node* ForestTechniqueManager::createScene(unsigned int /*numTreesToCreates*/) +osg::Node* createScene() { osg::Group* scene = new osg::Group; @@ -557,7 +122,7 @@ osg::Node* ForestTechniqueManager::createScene(unsigned int /*numTreesToCreates* osg::Program* program = new osg::Program; stateset->setAttribute(program); -#if 1 +#if 0 // use inline shaders /////////////////////////////////////////////////////////////////// @@ -576,7 +141,7 @@ osg::Node* ForestTechniqueManager::createScene(unsigned int /*numTreesToCreates* " texcoord.x *= terrainScaleDown.x;\n" " texcoord.y *= terrainScaleDown.y;\n" "\n" - " vec4 position;\n" + " vec4 position;\n"ttm-> " position.x = gl_Vertex.x;\n" " position.y = gl_Vertex.y;\n" " position.z = texture2D(terrainTexture, texcoord).r;\n" @@ -671,62 +236,6 @@ osg::Node* ForestTechniqueManager::createScene(unsigned int /*numTreesToCreates* std::cout<<"done."< cell = new Cell; - cell->addTrees(trees); - cell->divide(); - std::cout<<"done."<setWrap( osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP ); - tex->setWrap( osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP ); - tex->setImage(osgDB::readImageFile("Images/tree0.rgba")); - tex->setResizeNonPowerOfTwoHint(false); - - osg::StateSet *dstate = new osg::StateSet; - { - dstate->setTextureAttributeAndModes(1, tex, osg::StateAttribute::ON ); - - dstate->setAttributeAndModes( new osg::BlendFunc, osg::StateAttribute::ON ); - - osg::AlphaFunc* alphaFunc = new osg::AlphaFunc; - alphaFunc->setFunction(osg::AlphaFunc::GEQUAL,0.05f); - dstate->setAttributeAndModes( alphaFunc, osg::StateAttribute::ON ); - - dstate->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); - - dstate->setRenderingHint( osg::StateSet::TRANSPARENT_BIN ); - } - - - { - osg::StateSet* stateset = new osg::StateSet; - - stateset->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON ); - stateset->setRenderingHint( osg::StateSet::TRANSPARENT_BIN ); - - { - osg::Program* program = new osg::Program; - stateset->setAttribute(program); - - // get shaders from source - program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, osgDB::findDataFile("shaders/forest2.vert"))); - program->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, osgDB::findDataFile("shaders/forest2.frag"))); - } - - std::cout<<"Creating billboard based forest..."; - scene->addChild(createShaderGraph(cell.get(),stateset)); - - } -#endif - return scene; } @@ -784,14 +293,9 @@ int main( int argc, char **argv ) // construct the viewer. osgProducer::Viewer viewer(arguments); - float numTreesToCreates = 10000; - arguments.read("--trees",numTreesToCreates); - // set up the value with sensible default event handlers. viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS); - osg::ref_ptr ttm = new ForestTechniqueManager; - // get details on keyboard and mouse bindings used by the viewer. viewer.getUsage(*arguments.getApplicationUsage()); @@ -812,7 +316,7 @@ int main( int argc, char **argv ) return 1; } - osg::Node* node = ttm->createScene((unsigned int)numTreesToCreates); + osg::Node* node = createScene(); // add model to viewer. viewer.setSceneData( node ); diff --git a/include/osg/AutoTransform b/include/osg/AutoTransform index 2329dcf35..338ff18b4 100644 --- a/include/osg/AutoTransform +++ b/include/osg/AutoTransform @@ -17,6 +17,7 @@ #include #include #include +#include namespace osg { @@ -60,8 +61,6 @@ class OSG_EXPORT AutoTransform : public Transform float getAutoUpdateEyeMovementTolerance() const { return _autoUpdateEyeMovementTolerance; } - - enum AutoRotateMode { NO_ROTATION, @@ -88,25 +87,24 @@ class OSG_EXPORT AutoTransform : public Transform protected : virtual ~AutoTransform() {} + + Vec3 _position; + Vec3 _pivotPoint; + float _autoUpdateEyeMovementTolerance; + + AutoRotateMode _autoRotateMode; + + bool _autoScaleToScreen; - - Vec3 _position; - Vec3 _pivotPoint; - float _autoUpdateEyeMovementTolerance; - - AutoRotateMode _autoRotateMode; - - bool _autoScaleToScreen; - - mutable Quat _rotation; - mutable Vec3 _scale; - mutable bool _firstTimeToInitEyePoint; - mutable osg::Vec3 _previousEyePoint; - mutable osg::Vec3 _previousLocalUp; - mutable int _previousWidth; - mutable int _previousHeight; - mutable osg::Matrix _previousProjection; - mutable osg::Vec3 _previousPosition; + mutable Quat _rotation; + mutable Vec3 _scale; + mutable bool _firstTimeToInitEyePoint; + mutable osg::Vec3 _previousEyePoint; + mutable osg::Vec3 _previousLocalUp; + mutable Viewport::value_type _previousWidth; + mutable Viewport::value_type _previousHeight; + mutable osg::Matrix _previousProjection; + mutable osg::Vec3 _previousPosition; void computeMatrix() const; diff --git a/include/osg/Camera b/include/osg/Camera index 4c171604d..afc87437f 100644 --- a/include/osg/Camera +++ b/include/osg/Camera @@ -310,7 +310,7 @@ class OSG_EXPORT Camera : public Transform, public CullSettings /** Set the GraphicsContext that provides the mechansim for managing the OpenGL graphics context associated with this camera.*/ - void setGraphicsContext(GraphicsContext* context) { _graphicsContext = context; } + void setGraphicsContext(GraphicsContext* context); /** Get the GraphicsContext.*/ GraphicsContext* getGraphicsContext() { return _graphicsContext.get(); } diff --git a/include/osg/GraphicsContext b/include/osg/GraphicsContext index b494c60a4..8d5525649 100644 --- a/include/osg/GraphicsContext +++ b/include/osg/GraphicsContext @@ -19,6 +19,9 @@ namespace osg { +// forward declare osg::Camera +class Camera; + /** Base class for providing Windowing API agnostic access to creating and managing graphics context.*/ class OSG_EXPORT GraphicsContext : public Referenced { @@ -74,10 +77,10 @@ class OSG_EXPORT GraphicsContext : public Referenced sharedContext(0) {} // graphics context orginal and size - unsigned int x; - unsigned int y; - unsigned int width; - unsigned int height; + int x; + int y; + int width; + int height; // window decoration and baviour std::string windowName; @@ -258,12 +261,30 @@ class OSG_EXPORT GraphicsContext : public Referenced virtual void swapBuffersImplementation() = 0; + /** resized method should be called when the underlying window has been resized and the GraphicsWindow and associated Cameras must + be updated to keep in sync with the new size. */ + void resized(int x, int y, int width, int height); + + typedef std::list< osg::Camera* > Cameras; + + /** Get the the list of cameras associated with this graphics context.*/ + Cameras& getCameras() { return _cameras; } + + /** Get the the const list of cameras associated with this graphics context.*/ + const Cameras& getCameras() const { return _cameras; } + protected: GraphicsContext(); virtual ~GraphicsContext(); + + void addCamera(osg::Camera* camera); + void removeCamera(osg::Camera* camera); + + Cameras _cameras; + friend class osg::Camera; ref_ptr _traits; ref_ptr _state; diff --git a/include/osg/PrimitiveSet b/include/osg/PrimitiveSet index c886094c7..835b93092 100644 --- a/include/osg/PrimitiveSet +++ b/include/osg/PrimitiveSet @@ -200,13 +200,15 @@ class OSG_EXPORT PrimitiveSet : public Object PrimitiveSet(Type primType=PrimitiveType,GLenum mode=0): _primitiveType(primType), _mode(mode), - _modifiedCount(0) {} + _modifiedCount(0), + _rangeModifiedCount(0) {} PrimitiveSet(const PrimitiveSet& prim,const CopyOp& copyop=CopyOp::SHALLOW_COPY): Object(prim,copyop), _primitiveType(prim._primitiveType), _mode(prim._mode), - _modifiedCount(0) {} + _modifiedCount(0), + _rangeModifiedCount(0) {} virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } virtual const char* libraryName() const { return "osg"; } @@ -245,6 +247,8 @@ class OSG_EXPORT PrimitiveSet : public Object * for all graphics contexts. */ virtual void releaseGLObjects(State* /*state*/=0) const {} + virtual void computeRange() const {} + protected: virtual ~PrimitiveSet() {} @@ -252,7 +256,7 @@ class OSG_EXPORT PrimitiveSet : public Object Type _primitiveType; GLenum _mode; unsigned int _modifiedCount; - + mutable unsigned int _rangeModifiedCount; struct ObjectIDModifiedCountPair { @@ -435,10 +439,34 @@ class OSG_EXPORT DrawElementsUByte : public PrimitiveSet, public VectorGLubyte virtual void releaseGLObjects(State* state=0) const; + virtual void computeRange() const + { + if (empty()) + { + _minIndex = 0; + _maxIndex = 0; + _rangeModifiedCount = _modifiedCount; + return; + } + + _minIndex = front(); + _maxIndex = _minIndex; + + for(vector_type::const_iterator itr=begin(); itr!=end(); ++itr) + { + if (*itr<_minIndex) _minIndex = *itr; + if (*itr>_maxIndex) _maxIndex = *itr; + } + _rangeModifiedCount = _modifiedCount; + } + protected: virtual ~DrawElementsUByte(); + mutable unsigned int _minIndex; + mutable unsigned int _maxIndex; + mutable GLObjectList _vboList; }; @@ -491,10 +519,34 @@ class OSG_EXPORT DrawElementsUShort : public PrimitiveSet, public VectorGLushort virtual void releaseGLObjects(State* state=0) const; + virtual void computeRange() const + { + if (empty()) + { + _minIndex = 0; + _maxIndex = 0; + _rangeModifiedCount = _modifiedCount; + return; + } + + _minIndex = front(); + _maxIndex = _minIndex; + + for(vector_type::const_iterator itr=begin(); itr!=end(); ++itr) + { + if (*itr<_minIndex) _minIndex = *itr; + if (*itr>_maxIndex) _maxIndex = *itr; + } + _rangeModifiedCount = _modifiedCount; + } + protected: virtual ~DrawElementsUShort(); + mutable unsigned int _minIndex; + mutable unsigned int _maxIndex; + mutable GLObjectList _vboList; }; @@ -545,10 +597,34 @@ class OSG_EXPORT DrawElementsUInt : public PrimitiveSet, public VectorGLuint virtual void releaseGLObjects(State* state=0) const; + virtual void computeRange() const + { + if (empty()) + { + _minIndex = 0; + _maxIndex = 0; + _rangeModifiedCount = _modifiedCount; + return; + } + + _minIndex = front(); + _maxIndex = _minIndex; + + for(vector_type::const_iterator itr=begin(); itr!=end(); ++itr) + { + if (*itr<_minIndex) _minIndex = *itr; + if (*itr>_maxIndex) _maxIndex = *itr; + } + _rangeModifiedCount = _modifiedCount; + } + protected: virtual ~DrawElementsUInt(); + mutable unsigned int _minIndex; + mutable unsigned int _maxIndex; + mutable GLObjectList _vboList; }; diff --git a/include/osg/View b/include/osg/View index f164a5f58..214654935 100644 --- a/include/osg/View +++ b/include/osg/View @@ -59,8 +59,8 @@ class OSG_EXPORT View : public virtual osg::Referenced } osg::ref_ptr _camera; - osg::Matrixd _projectionOffset; - osg::Matrixd _viewOffset; + osg::Matrixd _projectionOffset; + osg::Matrixd _viewOffset; }; bool addSlave(osg::Camera* camera) { return addSlave(camera, osg::Matrix::identity(), osg::Matrix::identity()); } @@ -73,8 +73,12 @@ class OSG_EXPORT View : public virtual osg::Referenced Slave& getSlave(unsigned int pos) { return _slaves[pos]; } const Slave& getSlave(unsigned int pos) const { return _slaves[pos]; } + + Slave* findSlaveForCamera(osg::Camera* camera); void updateSlaves(); + + void updateSlave(unsigned int i); protected : diff --git a/include/osg/Viewport b/include/osg/Viewport index 62c132589..db33df4d3 100644 --- a/include/osg/Viewport +++ b/include/osg/Viewport @@ -23,9 +23,15 @@ namespace osg { class OSG_EXPORT Viewport : public StateAttribute { public : + +#if 0 + typedef int value_type; +#else + typedef double value_type; +#endif Viewport(); - Viewport(int x,int y,int width,int height): + Viewport(value_type x,value_type y,value_type width,value_type height): _x(x), _y(y), _width(width), @@ -58,14 +64,15 @@ class OSG_EXPORT Viewport : public StateAttribute return 0; // passed all the above comparison macro's, must be equal. } - inline void setViewport(int x,int y,int width,int height) + inline void setViewport(value_type x,value_type y,value_type width,value_type height) { _x = x; _y = y; _width = width; _height = height; } - + +#if 0 void getViewport(int& x,int& y,int& width,int& height) const { x = _x; @@ -74,24 +81,32 @@ class OSG_EXPORT Viewport : public StateAttribute height = _height; } - inline int& x() { return _x; } - inline int x() const { return _x; } + void getViewport(double& x,double& y,double& width,double& height) const + { + x = _x; + y = _y; + width = _width; + height = _height; + } +#endif + inline value_type& x() { return _x; } + inline value_type x() const { return _x; } - inline int& y() { return _y; } - inline int y() const { return _y; } + inline value_type& y() { return _y; } + inline value_type y() const { return _y; } - inline int& width() { return _width; } - inline int width() const { return _width; } + inline value_type& width() { return _width; } + inline value_type width() const { return _width; } - inline int& height() { return _height; } - inline int height() const { return _height; } + inline value_type& height() { return _height; } + inline value_type height() const { return _height; } - inline bool valid() const { return _width!=0 && _height!=0; } + inline bool valid() const { return _width>0 && _height>0; } /** Return the aspectRatio of the viewport, which is equal to width/height. * If height is zero, the potental division by zero is avoided by simply returning 1.0f. */ - inline float aspectRatio() const { if (_height!=0) return (float)_width/(float)_height; else return 1.0f; } + inline double aspectRatio() const { if (_height!=0) return (double)_width/(double)_height; else return 1.0; } /** Compute the Window Matrix which takes projected coords into Window coordinates. * To convert local coordinates into window coordinates use v_window = v_local * MVPW matrix, @@ -101,7 +116,7 @@ class OSG_EXPORT Viewport : public StateAttribute */ inline const osg::Matrix computeWindowMatrix() const { - return osg::Matrix::translate(1.0f,1.0f,1.0f)*osg::Matrix::scale(0.5f*width(),0.5f*height(),0.5f)*osg::Matrix::translate(x(),y(),0.0f); + return osg::Matrix::translate(1.0,1.0,1.0)*osg::Matrix::scale(0.5*width(),0.5*height(),0.5f)*osg::Matrix::translate(x(),y(),0.0f); } virtual void apply(State& state) const; @@ -110,10 +125,10 @@ class OSG_EXPORT Viewport : public StateAttribute virtual ~Viewport(); - int _x; - int _y; - int _width; - int _height; + value_type _x; + value_type _y; + value_type _width; + value_type _height; }; diff --git a/include/osgGA/EventQueue b/include/osgGA/EventQueue index bd4159804..50165c67f 100644 --- a/include/osgGA/EventQueue +++ b/include/osgGA/EventQueue @@ -64,10 +64,10 @@ class OSGGA_EXPORT EventQueue : public osg::Referenced /** Method for adapting window resize event, placing this event on the back of the event queue. */ - void windowResize(int x, int y, unsigned int width, unsigned int height) { windowResize(x,y,width,height,getTime()); } + void windowResize(int x, int y, int width, int height) { windowResize(x,y,width,height,getTime()); } /** Method for adapting window resize event, placing this event on the back of the event queue, with specified time. */ - void windowResize(int x, int y, unsigned int width, unsigned int height, double time); + void windowResize(int x, int y, int width, int height, double time); /** Method for adapting mouse scroll wheel events, placing this event on the back of the event queue. */ diff --git a/include/osgGA/GUIEventAdapter b/include/osgGA/GUIEventAdapter index 6ab551f73..c15ee3a61 100644 --- a/include/osgGA/GUIEventAdapter +++ b/include/osgGA/GUIEventAdapter @@ -274,7 +274,7 @@ public: /** set window rectangle. */ - void setWindowRectangle(int x, int y, unsigned int width, unsigned int height, bool updateMouseRange = true); + void setWindowRectangle(int x, int y, int width, int height, bool updateMouseRange = true); /** get window x origin.*/ int getWindowX() const { return _windowX; } @@ -283,10 +283,10 @@ public: int getWindowY() const { return _windowY; } /** get window width.*/ - unsigned int getWindowWidth() const { return _windowWidth; } + int getWindowWidth() const { return _windowWidth; } /** get window height.*/ - unsigned int getWindowHeight() const { return _windowHeight; } + int getWindowHeight() const { return _windowHeight; } /** set key pressed. */ diff --git a/include/osgUtil/SceneView b/include/osgUtil/SceneView index 6316eebd9..0f6064ee2 100644 --- a/include/osgUtil/SceneView +++ b/include/osgUtil/SceneView @@ -99,16 +99,6 @@ class OSGUTIL_EXPORT SceneView : public osg::Object, public osg::CullSettings /** Get the const viewport. */ const osg::Viewport* getViewport() const { return (_camera->getViewport()!=0) ? _camera->getViewport() : 0; } - /** Get the viewport of the scene view. */ - void getViewport(int& x,int& y,int& width,int& height) const - { - if (_camera->getViewport()!=0) - _camera->getViewport()->getViewport(x,y,width,height); - else - x = y = width = height = 0; - - } - /** Set the DisplaySettings. */ inline void setDisplaySettings(osg::DisplaySettings* vs) { _displaySettings = vs; } @@ -178,9 +168,9 @@ class OSGUTIL_EXPORT SceneView : public osg::Object, public osg::CullSettings osg::State* getState() { return _renderInfo.getState(); } const osg::State* getState() const { return _renderInfo.getState(); } - void setView(osg::View* view) { _renderInfo.setView(view); } - osg::View* getView() { return _renderInfo.getView(); } - const osg::View* getView() const { return _renderInfo.getView(); } + void setView(osg::View* view) { _camera->setView(view); } + osg::View* getView() { return _camera->getView(); } + const osg::View* getView() const { return _camera->getView(); } void setRenderInfo(osg::RenderInfo& renderInfo) { _renderInfo = renderInfo; } osg::RenderInfo& getRenderInfo() { return _renderInfo; } @@ -315,16 +305,10 @@ class OSGUTIL_EXPORT SceneView : public osg::Object, public osg::CullSettings /** Set the draw buffer value used at the start of each frame draw. Note, overridden in quad buffer stereo mode */ - void setDrawBufferValue( GLenum drawBufferValue ) - { - _drawBufferValue = drawBufferValue; - } + void setDrawBufferValue( GLenum drawBufferValue ) { _camera->setDrawBuffer(drawBufferValue); } /** Get the draw buffer value used at the start of each frame draw. */ - GLenum getDrawBufferValue() const - { - return _drawBufferValue; - } + GLenum getDrawBufferValue() const { return _camera->getDrawBuffer(); } /** FusionDistanceMode is used only when working in stereo.*/ @@ -504,7 +488,7 @@ class OSGUTIL_EXPORT SceneView : public osg::Object, public osg::CullSettings osg::ref_ptr _frameStamp; - osg::ref_ptr _camera; + osg::ref_ptr _camera; osg::ref_ptr _globalStateSet; osg::ref_ptr _light; @@ -517,8 +501,6 @@ class OSGUTIL_EXPORT SceneView : public osg::Object, public osg::CullSettings bool _prioritizeTextures; - GLenum _drawBufferValue; - bool _requiresFlush; int _activeUniforms; diff --git a/include/osgUtil/Statistics b/include/osgUtil/Statistics index 2520c7ff2..5b5c38d72 100644 --- a/include/osgUtil/Statistics +++ b/include/osgUtil/Statistics @@ -51,10 +51,7 @@ class Statistics : public osg::PrimitiveFunctor typedef std::map PrimitiveCountMap; - Statistics() - { - reset(); - }; + Statistics(); enum StatsType { @@ -68,25 +65,7 @@ class Statistics : public osg::PrimitiveFunctor STAT_RESTART // hint to restart the stats }; - void reset() - { - numDrawables=0; - nummat=0; - depth=0; - stattype=STAT_NONE; - nlights=0; - nbins=0; - nimpostor=0; - - _vertexCount=0; - _primitiveCount.clear(); - - _currentPrimitiveFunctorMode=0; - - _primitives_count.clear(); - _total_primitives_count=0; - _number_of_vertexes=0; - } + void reset(); void setType(StatsType t) {stattype=t;} @@ -94,42 +73,12 @@ class Statistics : public osg::PrimitiveFunctor virtual void setVertexArray(unsigned int count,const osg::Vec2*) { _vertexCount += count; } virtual void setVertexArray(unsigned int count,const osg::Vec4*) { _vertexCount += count; } - virtual void drawArrays(GLenum mode,GLint,GLsizei count) - { - PrimitivePair& prim = _primitiveCount[mode]; - ++prim.first; - prim.second+=count; - _primitives_count[mode] += _calculate_primitives_number_by_mode(mode, count); - } - virtual void drawElements(GLenum mode,GLsizei count,const GLubyte*) - { - PrimitivePair& prim = _primitiveCount[mode]; - ++prim.first; - prim.second+=count; - _primitives_count[mode] += _calculate_primitives_number_by_mode(mode, count); - } - virtual void drawElements(GLenum mode,GLsizei count,const GLushort*) - { - PrimitivePair& prim = _primitiveCount[mode]; - ++prim.first; - prim.second+=count; - _primitives_count[mode] += _calculate_primitives_number_by_mode(mode, count); - } - virtual void drawElements(GLenum mode,GLsizei count,const GLuint*) - { - PrimitivePair& prim = _primitiveCount[mode]; - ++prim.first; - prim.second+=count; - _primitives_count[mode] += _calculate_primitives_number_by_mode(mode, count); - } + virtual void drawArrays(GLenum mode,GLint,GLsizei count); + virtual void drawElements(GLenum mode,GLsizei count,const GLubyte*); + virtual void drawElements(GLenum mode,GLsizei count,const GLushort*); + virtual void drawElements(GLenum mode,GLsizei count,const GLuint*); - virtual void begin(GLenum mode) - { - _currentPrimitiveFunctorMode=mode; - PrimitivePair& prim = _primitiveCount[mode]; - ++prim.first; - _number_of_vertexes = 0; - } + virtual void begin(GLenum mode); inline void vertex() { @@ -137,6 +86,7 @@ class Statistics : public osg::PrimitiveFunctor ++prim.second; _number_of_vertexes++; } + virtual void vertex(float,float,float) { vertex(); } virtual void vertex(const osg::Vec3&) { vertex(); } virtual void vertex(const osg::Vec2&) { vertex(); } @@ -144,13 +94,7 @@ class Statistics : public osg::PrimitiveFunctor virtual void vertex(float,float) { vertex(); } virtual void vertex(float,float,float,float) { vertex(); } - virtual void end() - { - _primitives_count[_currentPrimitiveFunctorMode] += - _calculate_primitives_number_by_mode(_currentPrimitiveFunctorMode, _number_of_vertexes); - - _vertexCount += _number_of_vertexes; - } + virtual void end(); void addDrawable() { numDrawables++;} void addMatrix() { nummat++;} @@ -162,37 +106,7 @@ class Statistics : public osg::PrimitiveFunctor void setBinNo(int n) { _binNo=n;} - void add(const Statistics& stats) - { - numDrawables += stats.numDrawables; - nummat += stats.nummat; - depth += stats.depth; - nlights += stats.nlights; - nbins += stats.nbins; - nimpostor += stats.nimpostor; - - _vertexCount += stats._vertexCount; - // _primitiveCount += stats._primitiveCount; - for(PrimitiveValueMap::const_iterator pitr = stats._primitiveCount.begin(); - pitr != stats._primitiveCount.end(); - ++pitr) - { - _primitiveCount[pitr->first].first += pitr->second.first; - _primitiveCount[pitr->first].second += pitr->second.second; - } - - _currentPrimitiveFunctorMode += stats._currentPrimitiveFunctorMode; - - for(PrimitiveCountMap::const_iterator citr = stats._primitives_count.begin(); - citr != stats._primitives_count.end(); - ++citr) - { - _primitives_count[citr->first] += citr->second; - } - - _total_primitives_count += stats._total_primitives_count; - _number_of_vertexes += stats._number_of_vertexes; - } + void add(const Statistics& stats); public: @@ -221,19 +135,19 @@ class Statistics : public osg::PrimitiveFunctor inline unsigned int Statistics::_calculate_primitives_number_by_mode(GLenum mode, GLsizei count) { - switch (mode) + switch (mode) { - case GL_POINTS: - case GL_LINE_LOOP: - case GL_POLYGON: return count; - case GL_LINES: return count / 2; - case GL_LINE_STRIP: return count - 1; - case GL_TRIANGLES: return count / 3; - case GL_TRIANGLE_STRIP: - case GL_TRIANGLE_FAN: return count - 2; - case GL_QUADS: return count / 4; - case GL_QUAD_STRIP: return count / 2 - 1; - default: return 0; + case GL_POINTS: + case GL_LINE_LOOP: + case GL_POLYGON: return count; + case GL_LINES: return count / 2; + case GL_LINE_STRIP: return count - 1; + case GL_TRIANGLES: return count / 3; + case GL_TRIANGLE_STRIP: + case GL_TRIANGLE_FAN: return count - 2; + case GL_QUADS: return count / 4; + case GL_QUAD_STRIP: return count / 2 - 1; + default: return 0; } } @@ -246,188 +160,27 @@ public: typedef std::set DrawableSet; typedef std::set StateSetSet; - StatsVisitor(): - osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), - _numInstancedGroup(0), - _numInstancedSwitch(0), - _numInstancedLOD(0), - _numInstancedTransform(0), - _numInstancedGeode(0), - _numInstancedDrawable(0), - _numInstancedGeometry(0), - _numInstancedStateSet(0) {} + StatsVisitor(); - void reset() - { - _numInstancedGroup = 0; - _numInstancedSwitch = 0; - _numInstancedLOD = 0; - _numInstancedTransform = 0; - _numInstancedGeode = 0; - _numInstancedDrawable = 0; - _numInstancedGeometry = 0; - _numInstancedStateSet = 0; - - _groupSet.clear(); - _transformSet.clear(); - _lodSet.clear(); - _switchSet.clear(); - _geodeSet.clear(); - _drawableSet.clear(); - _geometrySet.clear(); - _statesetSet.clear(); - - _uniqueStats.reset(); - _instancedStats.reset(); - } + void reset(); - void apply(osg::Node& node) - { - if (node.getStateSet()) - { - ++_numInstancedStateSet; - _statesetSet.insert(node.getStateSet()); - } - traverse(node); - } + void apply(osg::Node& node); - void apply(osg::Group& node) - { - if (node.getStateSet()) - { - ++_numInstancedStateSet; - _statesetSet.insert(node.getStateSet()); - } + void apply(osg::Group& node); + + void apply(osg::Transform& node); + + void apply(osg::LOD& node); + + void apply(osg::Switch& node); + + void apply(osg::Geode& node); + + void apply(osg::Drawable& drawable); + + void totalUpStats(); - ++_numInstancedGroup; - _groupSet.insert(&node); - traverse(node); - } - - void apply(osg::Transform& node) - { - if (node.getStateSet()) - { - ++_numInstancedStateSet; - _statesetSet.insert(node.getStateSet()); - } - - ++_numInstancedTransform; - _transformSet.insert(&node); - traverse(node); - } - - void apply(osg::LOD& node) - { - if (node.getStateSet()) - { - ++_numInstancedStateSet; - _statesetSet.insert(node.getStateSet()); - } - - ++_numInstancedLOD; - _lodSet.insert(&node); - traverse(node); - } - - void apply(osg::Switch& node) - { - if (node.getStateSet()) - { - ++_numInstancedStateSet; - _statesetSet.insert(node.getStateSet()); - } - - ++_numInstancedSwitch; - _switchSet.insert(&node); - traverse(node); - } - - void apply(osg::Geode& node) - { - if (node.getStateSet()) - { - ++_numInstancedStateSet; - _statesetSet.insert(node.getStateSet()); - } - - ++_numInstancedGeode; - _geodeSet.insert(&node); - - for(unsigned int i=0; i(&drawable); - if (geometry) - { - ++_numInstancedGeometry; - _geometrySet.insert(geometry); - } - } - - void totalUpStats() - { - _uniqueStats.reset(); - - for(DrawableSet::iterator itr = _drawableSet.begin(); - itr != _drawableSet.end(); - ++itr) - { - (*itr)->accept(_uniqueStats); - } - } - - void print(std::ostream& out) - { - - unsigned int unique_primitives = 0; - osgUtil::Statistics::PrimitiveCountMap::iterator pcmitr; - for(pcmitr = _uniqueStats.GetPrimitivesBegin(); - pcmitr != _uniqueStats.GetPrimitivesEnd(); - ++pcmitr) - { - unique_primitives += pcmitr->second; - } - - unsigned int instanced_primitives = 0; - for(pcmitr = _instancedStats.GetPrimitivesBegin(); - pcmitr != _instancedStats.GetPrimitivesEnd(); - ++pcmitr) - { - instanced_primitives += pcmitr->second; - } - - out<<"Object Type\t#Unique\t#Instanced"< _startRenderingBarrier; osg::ref_ptr _endRenderingDispatchBarrier; + + osg::observer_ptr _cameraWithFocus; }; diff --git a/src/osg/AutoTransform.cpp b/src/osg/AutoTransform.cpp index 53666797b..df280e953 100644 --- a/src/osg/AutoTransform.cpp +++ b/src/osg/AutoTransform.cpp @@ -102,8 +102,8 @@ void AutoTransform::accept(NodeVisitor& nv) if (cs) { - int width = _previousWidth; - int height = _previousHeight; + Viewport::value_type width = _previousWidth; + Viewport::value_type height = _previousHeight; osg::Viewport* viewport = cs->getViewport(); if (viewport) diff --git a/src/osg/Camera.cpp b/src/osg/Camera.cpp index 898aad7a3..26317cbb9 100644 --- a/src/osg/Camera.cpp +++ b/src/osg/Camera.cpp @@ -50,13 +50,27 @@ Camera::Camera(const Camera& camera,const CopyOp& copyop): _bufferAttachmentMap(camera._bufferAttachmentMap), _postDrawCallback(camera._postDrawCallback) { + // need to copy/share graphics context? } Camera::~Camera() { + if (_graphicsContext.valid()) _graphicsContext->removeCamera(this); } +void Camera::setGraphicsContext(GraphicsContext* context) +{ + if (_graphicsContext == context) return; + + if (_graphicsContext.valid()) _graphicsContext->removeCamera(this); + + _graphicsContext = context; + + if (_graphicsContext.valid()) _graphicsContext->addCamera(this); +} + + bool Camera::isRenderToTextureCamera() const { return (!_bufferAttachmentMap.empty()); diff --git a/src/osg/GraphicsContext.cpp b/src/osg/GraphicsContext.cpp index 2eb3433c9..be8638ad5 100644 --- a/src/osg/GraphicsContext.cpp +++ b/src/osg/GraphicsContext.cpp @@ -13,7 +13,11 @@ #include +#include +#include + #include + #include #include @@ -362,3 +366,105 @@ void GraphicsContext::runOperations() } } } + +void GraphicsContext::addCamera(osg::Camera* camera) +{ + _cameras.push_back(camera); +} + +void GraphicsContext::removeCamera(osg::Camera* camera) +{ + for(Cameras::iterator itr = _cameras.begin(); + itr != _cameras.end(); + ++itr) + { + if (*itr == camera) + { + _cameras.erase(itr); + return; + } + } +} + +void GraphicsContext::resized(int x, int y, int width, int height) +{ + if (!_traits) return; + + double widthChangeRatio = double(width) / double(_traits->width); + double heigtChangeRatio = double(height) / double(_traits->height); + double aspectRatioChange = widthChangeRatio / heigtChangeRatio; + + for(Cameras::iterator itr = _cameras.begin(); + itr != _cameras.end(); + ++itr) + { + Camera* camera = (*itr); + Viewport* viewport = camera->getViewport(); + if (viewport) + { + if (viewport->x()==0 && viewport->y()==0 && + viewport->width()>=_traits->width && viewport->height()>=_traits->height) + { + viewport->setViewport(0,0,width,height); + } + else + { + viewport->x() = static_cast(double(viewport->x())*widthChangeRatio); + viewport->y() = static_cast(double(viewport->y())*heigtChangeRatio); + viewport->width() = static_cast(double(viewport->width())*widthChangeRatio); + viewport->height() = static_cast(double(viewport->height())*heigtChangeRatio); + } + } + + // if aspect ratio adjusted change the project matrix to suit. + if (aspectRatioChange != 1.0) + { + osg::View* view = camera->getView(); + osg::View::Slave* slave = view ? view->findSlaveForCamera(camera) : 0; + + if (slave && camera->getReferenceFrame()==osg::Transform::RELATIVE_RF) + { + slave->_projectionOffset *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0); + } + else + { +#if 0 + osg::Matrixd& pm = camera->getProjectionMatrix(); + bool orthographicCamera = (pm(0,3)==0.0) && (pm(1,3)==0.0) && (pm(2,3)==0.0) && (pm(3,3)==1.0); + + if (orthographicCamera) + { + double left, right, bottom, top, zNear, zFar; + camera->getProjectionMatrixAsOrtho(left, right, bottom, top, zNear, zFar); + + double mid = (right+left)*0.5; + double halfWidth = (right-left)*0.5; + left = mid - halfWidth * aspectRatioChange; + right = mid + halfWidth * aspectRatioChange; + camera->setProjectionMatrixAsOrtho(left, right, bottom, top, zNear, zFar); + } + else + { + double left, right, bottom, top, zNear, zFar; + camera->getProjectionMatrixAsFrustum(left, right, bottom, top, zNear, zFar); + + double mid = (right+left)*0.5; + double halfWidth = (right-left)*0.5; + left = mid - halfWidth * aspectRatioChange; + right = mid + halfWidth * aspectRatioChange; + camera->setProjectionMatrixAsFrustum(left, right, bottom, top, zNear, zFar); + } +#else + camera->getProjectionMatrix() *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0); +#endif + } + + } + + } + + _traits->x = x; + _traits->y = y; + _traits->width = width; + _traits->height = height; +} diff --git a/src/osg/View.cpp b/src/osg/View.cpp index b4c452fa1..4d4227750 100644 --- a/src/osg/View.cpp +++ b/src/osg/View.cpp @@ -43,20 +43,26 @@ View::~View() void View::updateSlaves() { - if (!_camera) return; - - for(Slaves::iterator itr = _slaves.begin(); - itr != _slaves.end(); - ++itr) + for(unsigned int i=0; i<_slaves.size(); ++i) + { + updateSlave(i); + } +} + +void View::updateSlave(unsigned int i) +{ + if (i >= _slaves.size() || !_camera) return; + + Slave& slave = _slaves[i]; + + if (slave._camera->getReferenceFrame()==osg::Transform::RELATIVE_RF) { - Slave& slave = *itr; slave._camera->setProjectionMatrix(_camera->getProjectionMatrix() * slave._projectionOffset); slave._camera->setViewMatrix(_camera->getViewMatrix() * slave._viewOffset); - slave._camera->inheritCullSettings(*_camera); - if (_camera->getInheritanceMask() & osg::CullSettings::CLEAR_COLOR) slave._camera->setClearColor(_camera->getClearColor()); } - + slave._camera->inheritCullSettings(*_camera); + if (_camera->getInheritanceMask() & osg::CullSettings::CLEAR_COLOR) slave._camera->setClearColor(_camera->getClearColor()); } bool View::addSlave(osg::Camera* camera, const osg::Matrix& projectionOffset, const osg::Matrix& viewOffset) @@ -64,20 +70,12 @@ bool View::addSlave(osg::Camera* camera, const osg::Matrix& projectionOffset, co if (!camera) return false; camera->setView(this); - camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); - if (_camera.valid()) - { - camera->setProjectionMatrix(projectionOffset * _camera->getProjectionMatrix()); - camera->setViewMatrix(viewOffset * _camera->getViewMatrix()); - camera->inheritCullSettings(*_camera); - - if (_camera->getInheritanceMask() & osg::CullSettings::CLEAR_COLOR) camera->setClearColor(_camera->getClearColor()); - } - + unsigned int i = _slaves.size(); + _slaves.push_back(Slave(camera, projectionOffset, viewOffset)); - // osg::notify(osg::NOTICE)<<"Added camera"<setCullCallback(0); _slaves.erase(_slaves.begin()+pos); - - osg::notify(osg::NOTICE)<<"Removed camera"<(_x),static_cast(_y), + static_cast(_width),static_cast(_height) ); } diff --git a/src/osgGA/EventQueue.cpp b/src/osgGA/EventQueue.cpp index b118ef6a1..179a0bf5e 100644 --- a/src/osgGA/EventQueue.cpp +++ b/src/osgGA/EventQueue.cpp @@ -78,7 +78,7 @@ bool EventQueue::copyEvents(Events& events) const } -void EventQueue::windowResize(int x, int y, unsigned int width, unsigned int height, double time) +void EventQueue::windowResize(int x, int y, int width, int height, double time) { _accumulateEventState->setWindowRectangle(x, y, width, height, !_useFixedMouseInputRange); diff --git a/src/osgGA/GUIEventAdapter.cpp b/src/osgGA/GUIEventAdapter.cpp index b2a7ff733..29d45224f 100644 --- a/src/osgGA/GUIEventAdapter.cpp +++ b/src/osgGA/GUIEventAdapter.cpp @@ -70,7 +70,7 @@ GUIEventAdapter::~GUIEventAdapter() { } -void GUIEventAdapter::setWindowRectangle(int x, int y, unsigned int width, unsigned int height, bool updateMouseRange) +void GUIEventAdapter::setWindowRectangle(int x, int y, int width, int height, bool updateMouseRange) { _windowX = x; _windowY = y; diff --git a/src/osgGA/TrackballManipulator.cpp b/src/osgGA/TrackballManipulator.cpp index f9e184010..0f7850455 100644 --- a/src/osgGA/TrackballManipulator.cpp +++ b/src/osgGA/TrackballManipulator.cpp @@ -232,8 +232,7 @@ bool TrackballManipulator::calcMovement() float dx = _ga_t0->getXnormalized()-_ga_t1->getXnormalized(); float dy = _ga_t0->getYnormalized()-_ga_t1->getYnormalized(); - - + // return if there is no movement. if (dx==0.0f && dy==0.0f) { diff --git a/src/osgPlugins/ive/Viewport.cpp b/src/osgPlugins/ive/Viewport.cpp index f0b92de0a..78de3a90d 100644 --- a/src/osgPlugins/ive/Viewport.cpp +++ b/src/osgPlugins/ive/Viewport.cpp @@ -51,10 +51,10 @@ void Viewport::read(DataInputStream* in){ throw Exception("Viewport::read(): Could not cast this osg::Viewport to an osg::Object."); // Read Viewport's properties - x() = (GLenum)in->readInt(); - y() = (GLenum)in->readInt(); - width() = (GLenum)in->readInt(); - height() = (GLenum)in->readInt(); + x() = in->readInt(); + y() = in->readInt(); + width() = in->readInt(); + height() = in->readInt(); } else{ diff --git a/src/osgPlugins/logo/ReaderWriterLOGO.cpp b/src/osgPlugins/logo/ReaderWriterLOGO.cpp index 91ceda460..a64b4da18 100644 --- a/src/osgPlugins/logo/ReaderWriterLOGO.cpp +++ b/src/osgPlugins/logo/ReaderWriterLOGO.cpp @@ -44,12 +44,10 @@ class Logos: public osg::Drawable osg::Viewport *vp = cv->getViewport(); if( vp != NULL ) { - int x, y, aw, ah, bw, bh; - logos->getViewport()->getViewport( x, y, aw, ah ); - vp->getViewport(x, y, bw, bh ); - if( aw != bw || ah != bh ) + if( vp->width() != logos->getViewport()->width() || + vp->height() != logos->getViewport()->height() ) { - logos->getViewport()->setViewport( x, y, bw, bh ); + logos->getViewport()->setViewport( vp->x(), vp->y(), vp->width(), vp->height() ); logos->dirtyDisplayList(); } } @@ -91,13 +89,18 @@ class Logos: public osg::Drawable if( state.getContextID() != _contextID ) return; - int x = 0, y = 0, w = 1, h = 1; - if( viewport != NULL ) - viewport->getViewport( x, y, w, h ); - float vx = x; - float vy = y; - float vw = w; - float vh = h; + + float vx = 0.0; + float vy = 0.0; + float vw = 1.0; + float vh = 1.0; + if (viewport) + { + vx = viewport->x(); + vy = viewport->y(); + vx = viewport->width(); + vy = viewport->height(); + } glMatrixMode( GL_PROJECTION ); glPushMatrix(); diff --git a/src/osgPlugins/osg/Viewport.cpp b/src/osgPlugins/osg/Viewport.cpp index 6e108fd5b..0ec72b221 100644 --- a/src/osgPlugins/osg/Viewport.cpp +++ b/src/osgPlugins/osg/Viewport.cpp @@ -25,28 +25,27 @@ RegisterDotOsgWrapperProxy g_ViewportProxy bool Viewport_readLocalData(Object& obj, Input& fr) { bool iteratorAdvanced = false; - int x = 0, y = 0, width = 0, height = 0; + double x = 0, y = 0, width = 0, height = 0; - - if (fr[0].matchWord("x") && fr[1].getInt(x)) + if (fr[0].matchWord("x") && fr[1].getFloat(x)) { fr+=2; iteratorAdvanced = true; } - if (fr[0].matchWord("y") && fr[1].getInt(y)) + if (fr[0].matchWord("y") && fr[1].getFloat(y)) { fr+=2; iteratorAdvanced = true; } - if (fr[0].matchWord("width") && fr[1].getInt(width)) + if (fr[0].matchWord("width") && fr[1].getFloat(width)) { fr+=2; iteratorAdvanced = true; } - if (fr[0].matchWord("height") && fr[1].getInt(height)) + if (fr[0].matchWord("height") && fr[1].getFloat(height)) { fr+=2; iteratorAdvanced = true; diff --git a/src/osgUtil/GNUmakefile b/src/osgUtil/GNUmakefile index 9adea1577..b900fe491 100644 --- a/src/osgUtil/GNUmakefile +++ b/src/osgUtil/GNUmakefile @@ -24,6 +24,7 @@ CXXFILES = \ Simplifier.cpp\ SmoothingVisitor.cpp\ StateGraph.cpp\ + Statistics.cpp\ TangentSpaceGenerator.cpp\ Tesselator.cpp\ TransformAttributeFunctor.cpp\ diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index 9081cbeab..599057806 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -104,7 +104,7 @@ SceneView::SceneView(DisplaySettings* ds) _initCalled = false; - _drawBufferValue = GL_BACK; + setDrawBufferValue(GL_BACK); _requiresFlush = true; @@ -134,9 +134,6 @@ SceneView::SceneView(const SceneView& rhs, const osg::CopyOp& copyop): _initCalled = rhs._initCalled; - - _drawBufferValue = rhs._drawBufferValue; - _requiresFlush = rhs._requiresFlush; _activeUniforms = rhs._activeUniforms; @@ -490,6 +487,8 @@ osg::Matrixd SceneView::computeRightEyeViewImplementation(const osg::Matrixd& vi void SceneView::cull() { + _renderInfo.setView(_camera->getView()); + // update the active uniforms updateUniforms(); @@ -883,13 +882,13 @@ void SceneView::draw() break; case(osg::DisplaySettings::ANAGLYPHIC): { - if( _drawBufferValue != GL_NONE) + if( getDrawBufferValue() != GL_NONE) { - _renderStageLeft->setDrawBuffer(_drawBufferValue); - _renderStageLeft->setReadBuffer(_drawBufferValue); + _renderStageLeft->setDrawBuffer(getDrawBufferValue()); + _renderStageLeft->setReadBuffer(getDrawBufferValue()); - _renderStageRight->setDrawBuffer(_drawBufferValue); - _renderStageRight->setReadBuffer(_drawBufferValue); + _renderStageRight->setDrawBuffer(getDrawBufferValue()); + _renderStageRight->setReadBuffer(getDrawBufferValue()); } _localStateSet->setAttribute(getViewport()); @@ -944,13 +943,13 @@ void SceneView::draw() break; case(osg::DisplaySettings::HORIZONTAL_SPLIT): { - if( _drawBufferValue != GL_NONE) + if( getDrawBufferValue() != GL_NONE) { - _renderStageLeft->setDrawBuffer(_drawBufferValue); - _renderStageLeft->setReadBuffer(_drawBufferValue); + _renderStageLeft->setDrawBuffer(getDrawBufferValue()); + _renderStageLeft->setReadBuffer(getDrawBufferValue()); - _renderStageRight->setDrawBuffer(_drawBufferValue); - _renderStageRight->setReadBuffer(_drawBufferValue); + _renderStageRight->setDrawBuffer(getDrawBufferValue()); + _renderStageRight->setReadBuffer(getDrawBufferValue()); } // ensure that all color planes are active. @@ -1010,13 +1009,13 @@ void SceneView::draw() break; case(osg::DisplaySettings::VERTICAL_SPLIT): { - if( _drawBufferValue != GL_NONE) + if( getDrawBufferValue() != GL_NONE) { - _renderStageLeft->setDrawBuffer(_drawBufferValue); - _renderStageLeft->setReadBuffer(_drawBufferValue); + _renderStageLeft->setDrawBuffer(getDrawBufferValue()); + _renderStageLeft->setReadBuffer(getDrawBufferValue()); - _renderStageRight->setDrawBuffer(_drawBufferValue); - _renderStageRight->setReadBuffer(_drawBufferValue); + _renderStageRight->setDrawBuffer(getDrawBufferValue()); + _renderStageRight->setReadBuffer(getDrawBufferValue()); } // ensure that all color planes are active. @@ -1075,10 +1074,10 @@ void SceneView::draw() case(osg::DisplaySettings::RIGHT_EYE): case(osg::DisplaySettings::LEFT_EYE): { - if( _drawBufferValue != GL_NONE) + if( getDrawBufferValue() != GL_NONE) { - _renderStage->setDrawBuffer(_drawBufferValue); - _renderStage->setReadBuffer(_drawBufferValue); + _renderStage->setDrawBuffer(getDrawBufferValue()); + _renderStage->setReadBuffer(getDrawBufferValue()); } // ensure that all color planes are active. @@ -1241,10 +1240,15 @@ void SceneView::draw() { // Need to restore draw buffer when toggling Stereo off. - if( _drawBufferValue != GL_NONE) + if( _camera->getDrawBuffer() != GL_NONE) { - _renderStage->setDrawBuffer(_drawBufferValue); - _renderStage->setReadBuffer(_drawBufferValue); + _renderStage->setDrawBuffer(_camera->getDrawBuffer()); + _renderStage->setReadBuffer(_camera->getDrawBuffer()); + } + + if( _camera->getReadBuffer() != GL_NONE) + { + _renderStage->setReadBuffer(_camera->getReadBuffer()); } _localStateSet->setAttribute(getViewport()); diff --git a/src/osgUtil/Statistics.cpp b/src/osgUtil/Statistics.cpp new file mode 100644 index 000000000..e0b81e694 --- /dev/null +++ b/src/osgUtil/Statistics.cpp @@ -0,0 +1,320 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace osgUtil; + +Statistics::Statistics() +{ + reset(); +}; + +void Statistics::reset() +{ + numDrawables=0; + nummat=0; + depth=0; + stattype=STAT_NONE; + nlights=0; + nbins=0; + nimpostor=0; + + _vertexCount=0; + _primitiveCount.clear(); + + _currentPrimitiveFunctorMode=0; + + _primitives_count.clear(); + _total_primitives_count=0; + _number_of_vertexes=0; +} + +void Statistics::drawArrays(GLenum mode,GLint,GLsizei count) +{ + PrimitivePair& prim = _primitiveCount[mode]; + ++prim.first; + prim.second+=count; + _primitives_count[mode] += _calculate_primitives_number_by_mode(mode, count); +} + +void Statistics::drawElements(GLenum mode,GLsizei count,const GLubyte*) +{ + PrimitivePair& prim = _primitiveCount[mode]; + ++prim.first; + prim.second+=count; + _primitives_count[mode] += _calculate_primitives_number_by_mode(mode, count); +} + +void Statistics::drawElements(GLenum mode,GLsizei count,const GLushort*) +{ + PrimitivePair& prim = _primitiveCount[mode]; + ++prim.first; + prim.second+=count; + _primitives_count[mode] += _calculate_primitives_number_by_mode(mode, count); +} + +void Statistics::drawElements(GLenum mode,GLsizei count,const GLuint*) +{ + PrimitivePair& prim = _primitiveCount[mode]; + ++prim.first; + prim.second+=count; + _primitives_count[mode] += _calculate_primitives_number_by_mode(mode, count); +} + + +void Statistics::begin(GLenum mode) +{ + _currentPrimitiveFunctorMode=mode; + PrimitivePair& prim = _primitiveCount[mode]; + ++prim.first; + _number_of_vertexes = 0; +} + +void Statistics::end() +{ + _primitives_count[_currentPrimitiveFunctorMode] += + _calculate_primitives_number_by_mode(_currentPrimitiveFunctorMode, _number_of_vertexes); + + _vertexCount += _number_of_vertexes; +} + +void Statistics::add(const Statistics& stats) +{ + numDrawables += stats.numDrawables; + nummat += stats.nummat; + depth += stats.depth; + nlights += stats.nlights; + nbins += stats.nbins; + nimpostor += stats.nimpostor; + + _vertexCount += stats._vertexCount; + // _primitiveCount += stats._primitiveCount; + for(PrimitiveValueMap::const_iterator pitr = stats._primitiveCount.begin(); + pitr != stats._primitiveCount.end(); + ++pitr) + { + _primitiveCount[pitr->first].first += pitr->second.first; + _primitiveCount[pitr->first].second += pitr->second.second; + } + + _currentPrimitiveFunctorMode += stats._currentPrimitiveFunctorMode; + + for(PrimitiveCountMap::const_iterator citr = stats._primitives_count.begin(); + citr != stats._primitives_count.end(); + ++citr) + { + _primitives_count[citr->first] += citr->second; + } + + _total_primitives_count += stats._total_primitives_count; + _number_of_vertexes += stats._number_of_vertexes; +} + +StatsVisitor::StatsVisitor(): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _numInstancedGroup(0), + _numInstancedSwitch(0), + _numInstancedLOD(0), + _numInstancedTransform(0), + _numInstancedGeode(0), + _numInstancedDrawable(0), + _numInstancedGeometry(0), + _numInstancedStateSet(0) +{} + +void StatsVisitor::reset() +{ + _numInstancedGroup = 0; + _numInstancedSwitch = 0; + _numInstancedLOD = 0; + _numInstancedTransform = 0; + _numInstancedGeode = 0; + _numInstancedDrawable = 0; + _numInstancedGeometry = 0; + _numInstancedStateSet = 0; + + _groupSet.clear(); + _transformSet.clear(); + _lodSet.clear(); + _switchSet.clear(); + _geodeSet.clear(); + _drawableSet.clear(); + _geometrySet.clear(); + _statesetSet.clear(); + + _uniqueStats.reset(); + _instancedStats.reset(); +} + +void StatsVisitor::apply(osg::Node& node) +{ + if (node.getStateSet()) + { + ++_numInstancedStateSet; + _statesetSet.insert(node.getStateSet()); + } + traverse(node); +} + +void StatsVisitor::apply(osg::Group& node) +{ + if (node.getStateSet()) + { + ++_numInstancedStateSet; + _statesetSet.insert(node.getStateSet()); + } + + ++_numInstancedGroup; + _groupSet.insert(&node); + traverse(node); +} + +void StatsVisitor::apply(osg::Transform& node) +{ + if (node.getStateSet()) + { + ++_numInstancedStateSet; + _statesetSet.insert(node.getStateSet()); + } + + ++_numInstancedTransform; + _transformSet.insert(&node); + traverse(node); +} + +void StatsVisitor::apply(osg::LOD& node) +{ + if (node.getStateSet()) + { + ++_numInstancedStateSet; + _statesetSet.insert(node.getStateSet()); + } + + ++_numInstancedLOD; + _lodSet.insert(&node); + traverse(node); +} + +void StatsVisitor::apply(osg::Switch& node) +{ + if (node.getStateSet()) + { + ++_numInstancedStateSet; + _statesetSet.insert(node.getStateSet()); + } + + ++_numInstancedSwitch; + _switchSet.insert(&node); + traverse(node); +} + +void StatsVisitor::apply(osg::Geode& node) +{ + if (node.getStateSet()) + { + ++_numInstancedStateSet; + _statesetSet.insert(node.getStateSet()); + } + + ++_numInstancedGeode; + _geodeSet.insert(&node); + + for(unsigned int i=0; i(&drawable); + if (geometry) + { + ++_numInstancedGeometry; + _geometrySet.insert(geometry); + } +} + +void StatsVisitor::totalUpStats() +{ + _uniqueStats.reset(); + + for(DrawableSet::iterator itr = _drawableSet.begin(); + itr != _drawableSet.end(); + ++itr) + { + (*itr)->accept(_uniqueStats); + } +} + +void StatsVisitor::print(std::ostream& out) +{ + + unsigned int unique_primitives = 0; + osgUtil::Statistics::PrimitiveCountMap::iterator pcmitr; + for(pcmitr = _uniqueStats.GetPrimitivesBegin(); + pcmitr != _uniqueStats.GetPrimitivesEnd(); + ++pcmitr) + { + unique_primitives += pcmitr->second; + } + + unsigned int instanced_primitives = 0; + for(pcmitr = _instancedStats.GetPrimitivesBegin(); + pcmitr != _instancedStats.GetPrimitivesEnd(); + ++pcmitr) + { + instanced_primitives += pcmitr->second; + } + + out<<"Object Type\t#Unique\t#Instanced"<second; + } + + protected: + + + typedef std::map KeyMap; + KeyMap _keymap; +}; + +static int remapX11Key(int key) +{ + static X11KeyboardMap s_x11KeyboardMap; + return s_x11KeyboardMap.remapKey(key); +} + bool GraphicsWindowX11::createVisualInfo() { typedef std::vector Attributes; @@ -347,9 +482,12 @@ void GraphicsWindowX11::init() // now update the window dimensions to account for any size changes made by the window manager, XGetWindowAttributes( _display, _window, &watt ); - _traits->width = watt.width; - _traits->height = watt.height; + if (_traits->width != watt.width && _traits->height != watt.height) + { + resized( _traits->x, _traits->y, _traits->width, _traits->height ); + } + //osg::notify(osg::NOTICE)<<"After sync apply.x = "<x; + int windowY = _traits->y; + int windowWidth = _traits->width; + int windowHeight = _traits->height; + // osg::notify(osg::NOTICE)<<"Check events"< dummyEvent = _eventQueue->createEvent(); - ActionAdapter aa; - _cameraManipulator->home(*dummyEvent, aa); + _cameraManipulator->home(*dummyEvent, *this); } } @@ -93,7 +82,11 @@ void View::setUpViewAcrossAllScreens() traits->y = 0; traits->width = width; traits->height = height; +#if 1 traits->windowDecoration = false; +#else + traits->windowDecoration = true; +#endif traits->doubleBuffer = true; traits->sharedContext = 0; @@ -112,18 +105,18 @@ void View::setUpViewAcrossAllScreens() osg::notify(osg::NOTICE)<<" GraphicsWindow has not been created successfully."<setViewport(new osg::Viewport(0, 0, width, height)); + + GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + + _camera->setDrawBuffer(buffer); + _camera->setReadBuffer(buffer); + } else { double rotate_x = - double(numScreens-1) * 0.5 * fovx; - - float inputRangeMinX = 0.0f; - float inputRangeMinY = 0.0f; - - float maxHeight = 0.0f; - + for(unsigned int i=0; igetEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, width, height ); - gw->getEventQueue()->setUseFixedMouseInputRange(true); - gw->getEventQueue()->getCurrentEventState()->setInputRange(inputRangeMinX, inputRangeMinY, inputRangeMinX+float(width),inputRangeMinY+float(height) ); - inputRangeMinX += float(width); - - if (maxHeight < float(height)) maxHeight = float(height); } else { @@ -163,12 +151,13 @@ void View::setUpViewAcrossAllScreens() camera->setViewport(new osg::Viewport(0, 0, width, height)); + GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate( rotate_x, 0.0, 1.0, 0.0)); } - - getEventQueue()->setUseFixedMouseInputRange(true); - getEventQueue()->getCurrentEventState()->setInputRange(0.0f, 0.0, inputRangeMinX, maxHeight); } setUpRenderingSupport(); @@ -190,6 +179,9 @@ struct RenderingOperation : public osg::GraphicsOperation { if (!_sceneView) return; + + // osg::notify(osg::NOTICE)<<"RenderingOperation"<cull(); _sceneView->draw(); @@ -255,8 +247,7 @@ void View::assignSceneDataToCameras() osg::ref_ptr dummyEvent = _eventQueue->createEvent(); - ActionAdapter aa; - _cameraManipulator->home(*dummyEvent, aa); + _cameraManipulator->home(*dummyEvent, *this); } if (_camera.valid()) @@ -275,3 +266,81 @@ void View::assignSceneDataToCameras() } } } + +void View::requestRedraw() +{ +} + +void View::requestContinuousUpdate(bool) +{ +} + +void View::requestWarpPointer(float x,float y) +{ + osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState(); + bool view_invert_y = eventState->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS; + + osgViewer::GraphicsWindow* gw = dynamic_cast(_camera->getGraphicsContext()); + if (gw) + { + bool gw_invert_y = gw->getEventQueue()->getCurrentEventState()->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS; + + x = x * float(gw->getTraits()->width) / (eventState->getXmax()-eventState->getXmin()); + y = y * float(gw->getTraits()->height) / (eventState->getYmax()-eventState->getYmin()); + + if (view_invert_y != gw_invert_y) y = gw->getTraits()->height - y; + + gw->requestWarpPointer(x, y); + + return; + } + + osg::Matrix masterCameraVPW = getCamera()->getViewMatrix() * getCamera()->getProjectionMatrix(); + + x = (x - eventState->getXmin()) * 2.0 / (eventState->getXmax()-eventState->getXmin()) - 1.0; + y = (y - eventState->getYmin())* 2.0 / (eventState->getYmax()-eventState->getYmin()) - 1.0; + + if (view_invert_y) y = - y; + + for(unsigned i=0; igetViewport() : 0; + + osg::Matrix localCameraVPW = camera->getViewMatrix() * camera->getProjectionMatrix(); + if (viewport) localCameraVPW *= viewport->computeWindowMatrix(); + + osg::Matrix matrix( osg::Matrix::inverse(masterCameraVPW) * localCameraVPW ); + + osg::Vec3d new_coord = osg::Vec3d(x,y,0.0) * matrix; + + if (viewport && + new_coord.x() >= viewport->x() && new_coord.y() >= viewport->y() && + new_coord.x() <= (viewport->x()+viewport->width()) && new_coord.y() <= (viewport->y()+viewport->height()) ) + { + gw = dynamic_cast(camera->getGraphicsContext()); + if (gw) + { + x = new_coord.x(); + y = new_coord.y(); + + bool gw_invert_y = gw->getEventQueue()->getCurrentEventState()->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS; + + if (gw_invert_y) y = gw->getTraits()->height - y; + + gw->requestWarpPointer(x, y); + + return; + } + } + + + } + } + + + +} diff --git a/src/osgViewer/Viewer.cpp b/src/osgViewer/Viewer.cpp index b027371dd..1785c91b8 100644 --- a/src/osgViewer/Viewer.cpp +++ b/src/osgViewer/Viewer.cpp @@ -18,19 +18,10 @@ #include #include +#include + using namespace osgViewer; -class ActionAdapter : public osgGA::GUIActionAdapter -{ -public: - virtual ~ActionAdapter() {} - - virtual void requestRedraw() { /*osg::notify(osg::NOTICE)<<"requestRedraw()"<init(*initEvent, aa); + _cameraManipulator->init(*initEvent, *this); } } @@ -157,12 +147,14 @@ void Viewer::realize() { osg::notify(osg::INFO)<<"Viewer::realize()"< 1; + bool multiThreaded = contexts.size() > 1; if (multiThreaded) { @@ -223,7 +215,6 @@ void Viewer::realize() // initialize the global timer to be relative to the current time. osg::Timer::instance()->setStartTick(); - if (multiThreaded) { for(citr = contexts.begin(); @@ -238,7 +229,6 @@ void Viewer::realize() } } } - } @@ -281,6 +271,20 @@ void Viewer::frameEventTraversal() Contexts contexts; getContexts(contexts); + osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState(); + osg::Matrix masterCameraVPW = getCamera()->getViewMatrix() * getCamera()->getProjectionMatrix(); + if (getCamera()->getViewport()) + { + osg::Viewport* viewport = getCamera()->getViewport(); + masterCameraVPW *= viewport->computeWindowMatrix(); + eventState->setInputRange( viewport->x(), viewport->y(), viewport->x() + viewport->width(), viewport->y() + viewport->height()); + } + else + { + eventState->setInputRange(-1.0, -1.0, 1.0, 1.0); + } + + for(Contexts::iterator citr = contexts.begin(); citr != contexts.end(); ++citr) @@ -289,11 +293,104 @@ void Viewer::frameEventTraversal() if (gw) { gw->checkEvents(); - gw->getEventQueue()->takeEvents(events); + + osgGA::EventQueue::Events gw_events; + gw->getEventQueue()->takeEvents(gw_events); + + for(osgGA::EventQueue::Events::iterator itr = gw_events.begin(); + itr != gw_events.end(); + ++itr) + { + osgGA::GUIEventAdapter* event = itr->get(); + + bool pointerEvent = false; + + float x = event->getX(); + float y = event->getY(); + + bool invert_y = event->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS; + if (invert_y) y = gw->getTraits()->height - y; + + switch(event->getEventType()) + { + case(osgGA::GUIEventAdapter::PUSH): + case(osgGA::GUIEventAdapter::RELEASE): + case(osgGA::GUIEventAdapter::DRAG): + case(osgGA::GUIEventAdapter::MOVE): + { + pointerEvent = true; + + if (event->getEventType()!=osgGA::GUIEventAdapter::DRAG || !getCameraWithFocus()) + { + osg::GraphicsContext::Cameras& cameras = gw->getCameras(); + for(osg::GraphicsContext::Cameras::iterator citr = cameras.begin(); + citr != cameras.end(); + ++citr) + { + osg::Camera* camera = *citr; + osg::Viewport* viewport = camera ? camera->getViewport() : 0; + if (viewport && + x >= viewport->x() && y >= viewport->y() && + x <= (viewport->x()+viewport->width()) && y <= (viewport->y()+viewport->height()) ) + { + setCameraWithFocus(camera); + } + } + } + + break; + } + default: + break; + } + + if (pointerEvent) + { + if (getCameraWithFocus()) + { + osg::Viewport* viewport = getCameraWithFocus()->getViewport(); + osg::Matrix localCameraVPW = getCameraWithFocus()->getViewMatrix() * getCameraWithFocus()->getProjectionMatrix(); + if (viewport) localCameraVPW *= viewport->computeWindowMatrix(); + + osg::Matrix matrix( osg::Matrix::inverse(localCameraVPW) * masterCameraVPW ); + + osg::Vec3d new_coord = osg::Vec3d(x,y,0.0) * matrix; + + x = new_coord.x(); + y = new_coord.y(); + + event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax()); + event->setX(x); + event->setY(y); + event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS); + + } + // pass along the new pointer events details to the eventState of the viewer + eventState->setX(x); + eventState->setY(y); + eventState->setButtonMask(event->getButtonMask()); + eventState->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS); + + } + else + { + event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax()); + event->setX(eventState->getX()); + event->setY(eventState->getY()); + event->setButtonMask(eventState->getButtonMask()); + event->setMouseYOrientation(eventState->getMouseYOrientation()); + } + //osg::notify(osg::NOTICE)<<" mouse x = "<getX()<<" y="<getY()<getKey()<<"'"<getEventType()) { case(osgGA::GUIEventAdapter::KEYUP): - if (event->getKey()=='q') _done = true; + if (event->getKey()==osgGA::GUIEventAdapter::KEY_Escape) _done = true; break; default: break; @@ -388,8 +489,6 @@ void Viewer::frameEventTraversal() if (_done) return; - ActionAdapter aa; - for(osgGA::EventQueue::Events::iterator itr = events.begin(); itr != events.end(); ++itr) @@ -400,16 +499,17 @@ void Viewer::frameEventTraversal() if (_cameraManipulator.valid()) { - _cameraManipulator->handle( *event, aa); + _cameraManipulator->handle( *event, *this); } for(EventHandlers::iterator hitr = _eventHandlers.begin(); hitr != _eventHandlers.end() && !handled; ++hitr) { - handled = (*hitr)->handle( *event, aa, 0, 0); + handled = (*hitr)->handle( *event, *this, 0, 0); } } + } void Viewer::frameUpdateTraversal()