Various work on osgViewer library, including warp point and graphics window resize support
This commit is contained in:
parent
88fc4ee986
commit
7155f7d1b0
@ -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
|
||||
|
@ -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."<<std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int width, height;
|
||||
wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);
|
||||
|
||||
osg::ref_ptr<osg::GraphicsContext::Traits> 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<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
|
||||
|
||||
osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(gc.get());
|
||||
if (gw)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<" GraphicsWindow has been created successfully."<<gw<<std::endl;
|
||||
|
||||
gw->getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, width, height );
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<" GraphicsWindow has not been created successfully."<<std::endl;
|
||||
}
|
||||
|
||||
unsigned int numCameras = 2;
|
||||
double aspectRatioScale = 1.0;///(double)numCameras;
|
||||
for(unsigned int i=0; i<numCameras;++i)
|
||||
{
|
||||
osg::ref_ptr<osg::Camera> 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;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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."<<std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int width, height;
|
||||
wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);
|
||||
|
||||
width -= 500;
|
||||
height -= 500;
|
||||
|
||||
osg::ref_ptr<osg::GraphicsContext::Traits> 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<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
|
||||
|
||||
osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(gc.get());
|
||||
if (gw)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<" GraphicsWindow has been created successfully."<<gw<<std::endl;
|
||||
|
||||
gw->getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, width, height );
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<" GraphicsWindow has not been created successfully."<<std::endl;
|
||||
}
|
||||
|
||||
unsigned int numCameras = 2;
|
||||
double aspectRatioScale = 1.0/(double)numCameras;
|
||||
for(unsigned int i=0; i<numCameras;++i)
|
||||
{
|
||||
osg::ref_ptr<osg::Camera> 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() )
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include <osgUtil/Optimizer>
|
||||
#include <osgUtil/TriStripVisitor>
|
||||
|
||||
#include <osgProducer/Viewer>
|
||||
|
||||
@ -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; iy<num_y-1; ++iy)
|
||||
unsigned int totalIndices = 0;
|
||||
if (mesh=="triangles" || mesh=="tristrip")
|
||||
{
|
||||
unsigned int element_no = 0;
|
||||
osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_TRIANGLE_STRIP, num_x*2);
|
||||
unsigned int index = iy * num_x;
|
||||
for(unsigned int ix = 0; ix<num_x; ++ix)
|
||||
if (cacheSize)
|
||||
{
|
||||
(*elements)[element_no++] = index + num_x;
|
||||
(*elements)[element_no++] = index++;
|
||||
unsigned int index=0;
|
||||
osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_TRIANGLES);
|
||||
geom->addPrimitiveSet(elements);
|
||||
elements->dirty();
|
||||
|
||||
for(unsigned int is=0; is<num_x; is += cacheSize-1)
|
||||
{
|
||||
|
||||
for(iy=0; iy<num_y-1; ++iy)
|
||||
{
|
||||
unsigned int num_in_stripe = osg::minimum(cacheSize, num_x-is);
|
||||
|
||||
bool rightToLeft = true;
|
||||
|
||||
if (elements->size() > maxSize)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"elements->size() = "<<elements->size()<<std::endl;
|
||||
totalIndices += elements->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; ix<num_in_stripe-1; ++ix)
|
||||
{
|
||||
(*elements).push_back(index + num_x);
|
||||
(*elements).push_back(index);
|
||||
(*elements).push_back(index+1);
|
||||
|
||||
(*elements).push_back(index + num_x);
|
||||
(*elements).push_back(index+1);
|
||||
(*elements).push_back(index + num_x + 1);
|
||||
|
||||
++index;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
index = iy * num_x + is + (num_x-2);
|
||||
|
||||
for(unsigned int ix = 0; ix<num_in_stripe-1; ++ix)
|
||||
{
|
||||
(*elements).push_back(index + num_x);
|
||||
(*elements).push_back(index);
|
||||
(*elements).push_back(index+1);
|
||||
|
||||
(*elements).push_back(index + num_x);
|
||||
(*elements).push_back(index+1);
|
||||
(*elements).push_back(index + num_x + 1);
|
||||
|
||||
--index;
|
||||
}
|
||||
}
|
||||
|
||||
rightToLeft = !rightToLeft;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
totalIndices += elements->size();
|
||||
osg::notify(osg::NOTICE)<<"elements->size() = "<<elements->size()<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_TRIANGLES, (num_x-1)*(num_y-1)*6);
|
||||
elements->dirty();
|
||||
unsigned int element_no = 0;
|
||||
for(iy=0; iy<num_y-1; ++iy)
|
||||
{
|
||||
unsigned int index = iy * num_x;
|
||||
for(unsigned int ix = 0; ix<num_x-1; ++ix)
|
||||
{
|
||||
(*elements)[element_no++] = index + num_x;
|
||||
(*elements)[element_no++] = index;
|
||||
(*elements)[element_no++] = index+1;
|
||||
|
||||
(*elements)[element_no++] = index + num_x;
|
||||
(*elements)[element_no++] = index+1;
|
||||
(*elements)[element_no++] = index + num_x + 1;
|
||||
|
||||
++index;
|
||||
}
|
||||
}
|
||||
geom->addPrimitiveSet(elements);
|
||||
osg::notify(osg::NOTICE)<<"elements->size() = "<<elements->size()<<std::endl;
|
||||
}
|
||||
geom->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; is<num_x; is += cacheSize-1)
|
||||
{
|
||||
|
||||
for(iy=0; iy<num_y-1; ++iy)
|
||||
{
|
||||
unsigned int num_in_stripe = osg::minimum(cacheSize, num_x-is);
|
||||
|
||||
bool rightToLeft = true;
|
||||
|
||||
if (elements->size() > maxSize)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"elements->size() = "<<elements->size()<<std::endl;
|
||||
|
||||
totalIndices += elements->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; ix<num_in_stripe; ++ix)
|
||||
{
|
||||
(*elements).push_back(index + num_x);
|
||||
(*elements).push_back(index++);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
index = iy * num_x + is + (num_x-1);
|
||||
|
||||
if (needToJoin) (*elements).push_back(index);
|
||||
|
||||
for(unsigned int ix = 0; ix<num_in_stripe; ++ix)
|
||||
{
|
||||
(*elements).push_back(index);
|
||||
(*elements).push_back(index-- + num_x);
|
||||
}
|
||||
}
|
||||
|
||||
rightToLeft = !rightToLeft;
|
||||
|
||||
needToJoin = true;
|
||||
}
|
||||
|
||||
}
|
||||
totalIndices += elements->size();
|
||||
}
|
||||
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; iy<num_y-1; ++iy)
|
||||
{
|
||||
|
||||
if (needToJoin) (*elements).push_back(index-1);
|
||||
|
||||
index = iy * num_x;
|
||||
|
||||
if (needToJoin) (*elements).push_back(index + num_x);
|
||||
|
||||
for(unsigned int ix = 0; ix<num_x; ++ix)
|
||||
{
|
||||
(*elements).push_back(index + num_x);
|
||||
(*elements).push_back(index++);
|
||||
}
|
||||
needToJoin = true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
osg::notify(osg::NOTICE)<<"totalIndices = "<<totalIndices<<std::endl;
|
||||
|
||||
if (mesh=="tristrip")
|
||||
{ osgUtil::TriStripVisitor stripper;
|
||||
stripper.stripify(*geom);
|
||||
}
|
||||
|
||||
#if 0
|
||||
geom->setUseVertexBufferObjects(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;
|
||||
|
@ -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<Tree> > TreeList;
|
||||
|
||||
class Cell : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
typedef std::vector< osg::ref_ptr<Cell> > 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<numCellsToDivide;++i)
|
||||
{
|
||||
Cell* orig_cell = _cells[i].get();
|
||||
Cell* new_cell = new Cell(orig_cell->_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<numCellsToDivide;++i)
|
||||
{
|
||||
Cell* orig_cell = _cells[i].get();
|
||||
Cell* new_cell = new Cell(orig_cell->_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<numCellsToDivide;++i)
|
||||
{
|
||||
Cell* orig_cell = _cells[i].get();
|
||||
Cell* new_cell = new Cell(orig_cell->_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<numTreesToCreate;++i)
|
||||
{
|
||||
Tree* tree = new Tree;
|
||||
tree->_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<osg::LineSegment> 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<osg::Vec4> 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<osg::Geometry> _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."<<std::endl;
|
||||
|
||||
#if 0
|
||||
std::cout<<"Creating tree locations...";std::cout.flush();
|
||||
TreeList trees;
|
||||
createTreeList(0,origin,size,numTreesToCreates,trees);
|
||||
std::cout<<"done."<<std::endl;
|
||||
|
||||
std::cout<<"Creating cell subdivision...";
|
||||
osg::ref_ptr<Cell> cell = new Cell;
|
||||
cell->addTrees(trees);
|
||||
cell->divide();
|
||||
std::cout<<"done."<<std::endl;
|
||||
|
||||
|
||||
osg::Texture2D *tex = new osg::Texture2D;
|
||||
tex->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<ForestTechniqueManager> 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 );
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <osg/Group>
|
||||
#include <osg/Transform>
|
||||
#include <osg/Quat>
|
||||
#include <osg/Viewport>
|
||||
|
||||
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;
|
||||
|
@ -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(); }
|
||||
|
@ -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> _traits;
|
||||
ref_ptr<State> _state;
|
||||
|
@ -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<const PrimitiveSet*>(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;
|
||||
};
|
||||
|
||||
|
@ -59,8 +59,8 @@ class OSG_EXPORT View : public virtual osg::Referenced
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Camera> _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 :
|
||||
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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. */
|
||||
|
@ -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<osg::FrameStamp> _frameStamp;
|
||||
|
||||
osg::ref_ptr<osg::Camera> _camera;
|
||||
osg::ref_ptr<osg::Camera> _camera;
|
||||
|
||||
osg::ref_ptr<osg::StateSet> _globalStateSet;
|
||||
osg::ref_ptr<osg::Light> _light;
|
||||
@ -517,8 +501,6 @@ class OSGUTIL_EXPORT SceneView : public osg::Object, public osg::CullSettings
|
||||
|
||||
bool _prioritizeTextures;
|
||||
|
||||
GLenum _drawBufferValue;
|
||||
|
||||
bool _requiresFlush;
|
||||
|
||||
int _activeUniforms;
|
||||
|
@ -51,10 +51,7 @@ class Statistics : public osg::PrimitiveFunctor
|
||||
typedef std::map<GLenum, unsigned int> 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<osg::Drawable*> DrawableSet;
|
||||
typedef std::set<osg::StateSet*> 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<node.getNumDrawables();++i)
|
||||
{
|
||||
apply(*node.getDrawable(i));
|
||||
}
|
||||
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
void apply(osg::Drawable& drawable)
|
||||
{
|
||||
if (drawable.getStateSet())
|
||||
{
|
||||
++_numInstancedStateSet;
|
||||
_statesetSet.insert(drawable.getStateSet());
|
||||
}
|
||||
|
||||
++_numInstancedDrawable;
|
||||
|
||||
drawable.accept(_instancedStats);
|
||||
|
||||
_drawableSet.insert(&drawable);
|
||||
|
||||
osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(&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"<<std::endl;
|
||||
out<<"StateSet \t"<<_statesetSet.size()<<"\t"<<_numInstancedStateSet<<std::endl;
|
||||
out<<"Group \t"<<_groupSet.size()<<"\t"<<_numInstancedGroup<<std::endl;
|
||||
out<<"Transform \t"<<_transformSet.size()<<"\t"<<_numInstancedTransform<<std::endl;
|
||||
out<<"LOD \t"<<_lodSet.size()<<"\t"<<_numInstancedLOD<<std::endl;
|
||||
out<<"Switch \t"<<_switchSet.size()<<"\t"<<_numInstancedSwitch<<std::endl;
|
||||
out<<"Geode \t"<<_geodeSet.size()<<"\t"<<_numInstancedGeode<<std::endl;
|
||||
out<<"Drawable \t"<<_drawableSet.size()<<"\t"<<_numInstancedDrawable<<std::endl;
|
||||
out<<"Geometry \t"<<_geometrySet.size()<<"\t"<<_numInstancedGeometry<<std::endl;
|
||||
out<<"Vertices \t"<<_uniqueStats._vertexCount<<"\t"<<_instancedStats._vertexCount<<std::endl;
|
||||
out<<"Primitives \t"<<unique_primitives<<"\t"<<instanced_primitives<<std::endl;
|
||||
}
|
||||
void print(std::ostream& out);
|
||||
|
||||
unsigned int _numInstancedGroup;
|
||||
unsigned int _numInstancedSwitch;
|
||||
|
@ -86,6 +86,9 @@ class GraphicsWindowX11 : public osgViewer::GraphicsWindow
|
||||
/** Get focus on if the pointer is in this window.*/
|
||||
virtual void grabFocusIfPointerInWindow();
|
||||
|
||||
// Override from GUIActionAdapter
|
||||
virtual void requestWarpPointer(float x,float y);
|
||||
|
||||
protected:
|
||||
|
||||
bool createVisualInfo();
|
||||
|
@ -23,7 +23,7 @@
|
||||
namespace osgViewer {
|
||||
|
||||
/** View holds a single view on a scene, this view may be composed of one or more slave cameras.*/
|
||||
class OSGVIEWER_EXPORT View : public osg::View
|
||||
class OSGVIEWER_EXPORT View : public osg::View, public osgGA::GUIActionAdapter
|
||||
{
|
||||
public:
|
||||
|
||||
@ -50,6 +50,9 @@ class OSGVIEWER_EXPORT View : public osg::View
|
||||
/** Convinience method for creating slave Cameras and associated GraphicsWindows across all screens.*/
|
||||
void setUpViewAcrossAllScreens();
|
||||
|
||||
virtual void requestRedraw();
|
||||
virtual void requestContinuousUpdate(bool needed=true);
|
||||
virtual void requestWarpPointer(float x,float y);
|
||||
|
||||
public:
|
||||
|
||||
@ -57,6 +60,7 @@ class OSGVIEWER_EXPORT View : public osg::View
|
||||
|
||||
void assignSceneDataToCameras();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~View();
|
||||
|
@ -54,6 +54,10 @@ class OSGVIEWER_EXPORT Viewer : public osgViewer::View
|
||||
/** Clean up all OpenGL objects associated with this viewer's scenegraph.*/
|
||||
virtual void cleanup();
|
||||
|
||||
void setCameraWithFocus(osg::Camera* camera) { _cameraWithFocus = camera; }
|
||||
osg::Camera* getCameraWithFocus() { return _cameraWithFocus.get(); }
|
||||
const osg::Camera* getCameraWithFocus() const { return _cameraWithFocus.get(); }
|
||||
|
||||
public:
|
||||
|
||||
void init();
|
||||
@ -66,6 +70,8 @@ class OSGVIEWER_EXPORT Viewer : public osgViewer::View
|
||||
|
||||
osg::ref_ptr<osg::BarrierOperation> _startRenderingBarrier;
|
||||
osg::ref_ptr<osg::BarrierOperation> _endRenderingDispatchBarrier;
|
||||
|
||||
osg::observer_ptr<osg::Camera> _cameraWithFocus;
|
||||
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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());
|
||||
|
@ -13,7 +13,11 @@
|
||||
|
||||
|
||||
#include <osg/GraphicsContext>
|
||||
#include <osg/Camera>
|
||||
#include <osg/View>
|
||||
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
|
||||
@ -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<osg::Viewport::value_type>(double(viewport->x())*widthChangeRatio);
|
||||
viewport->y() = static_cast<osg::Viewport::value_type>(double(viewport->y())*heigtChangeRatio);
|
||||
viewport->width() = static_cast<osg::Viewport::value_type>(double(viewport->width())*widthChangeRatio);
|
||||
viewport->height() = static_cast<osg::Viewport::value_type>(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;
|
||||
}
|
||||
|
@ -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"<<std::endl;
|
||||
updateSlave(i);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -90,10 +88,19 @@ bool View::removeSlave(unsigned int pos)
|
||||
_slaves[pos]._camera->setCullCallback(0);
|
||||
|
||||
_slaves.erase(_slaves.begin()+pos);
|
||||
|
||||
osg::notify(osg::NOTICE)<<"Removed camera"<<std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
View::Slave* View::findSlaveForCamera(osg::Camera* camera)
|
||||
{
|
||||
if (_camera == camera) return 0;
|
||||
|
||||
for(unsigned int i=0; i<_slaves.size(); ++i)
|
||||
{
|
||||
if (_slaves[i]._camera == camera) return &(_slaves[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ Viewport::~Viewport()
|
||||
|
||||
void Viewport::apply(State&) const
|
||||
{
|
||||
glViewport(_x,_y,_width,_height);
|
||||
glViewport( static_cast<GLint>(_x),static_cast<GLint>(_y),
|
||||
static_cast<GLsizei>(_width),static_cast<GLsizei>(_height) );
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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{
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -24,6 +24,7 @@ CXXFILES = \
|
||||
Simplifier.cpp\
|
||||
SmoothingVisitor.cpp\
|
||||
StateGraph.cpp\
|
||||
Statistics.cpp\
|
||||
TangentSpaceGenerator.cpp\
|
||||
Tesselator.cpp\
|
||||
TransformAttributeFunctor.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());
|
||||
|
320
src/osgUtil/Statistics.cpp
Normal file
320
src/osgUtil/Statistics.cpp
Normal file
@ -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 <osgUtil/Statistics>
|
||||
|
||||
#include <osg/PrimitiveSet>
|
||||
#include <osg/Drawable>
|
||||
#include <osg/NodeVisitor>
|
||||
#include <osg/Geode>
|
||||
#include <osg/LOD>
|
||||
#include <osg/Switch>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/Transform>
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <ostream>
|
||||
|
||||
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<node.getNumDrawables();++i)
|
||||
{
|
||||
apply(*node.getDrawable(i));
|
||||
}
|
||||
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
void StatsVisitor::apply(osg::Drawable& drawable)
|
||||
{
|
||||
if (drawable.getStateSet())
|
||||
{
|
||||
++_numInstancedStateSet;
|
||||
_statesetSet.insert(drawable.getStateSet());
|
||||
}
|
||||
|
||||
++_numInstancedDrawable;
|
||||
|
||||
drawable.accept(_instancedStats);
|
||||
|
||||
_drawableSet.insert(&drawable);
|
||||
|
||||
osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(&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"<<std::endl;
|
||||
out<<"StateSet \t"<<_statesetSet.size()<<"\t"<<_numInstancedStateSet<<std::endl;
|
||||
out<<"Group \t"<<_groupSet.size()<<"\t"<<_numInstancedGroup<<std::endl;
|
||||
out<<"Transform \t"<<_transformSet.size()<<"\t"<<_numInstancedTransform<<std::endl;
|
||||
out<<"LOD \t"<<_lodSet.size()<<"\t"<<_numInstancedLOD<<std::endl;
|
||||
out<<"Switch \t"<<_switchSet.size()<<"\t"<<_numInstancedSwitch<<std::endl;
|
||||
out<<"Geode \t"<<_geodeSet.size()<<"\t"<<_numInstancedGeode<<std::endl;
|
||||
out<<"Drawable \t"<<_drawableSet.size()<<"\t"<<_numInstancedDrawable<<std::endl;
|
||||
out<<"Geometry \t"<<_geometrySet.size()<<"\t"<<_numInstancedGeometry<<std::endl;
|
||||
out<<"Vertices \t"<<_uniqueStats._vertexCount<<"\t"<<_instancedStats._vertexCount<<std::endl;
|
||||
out<<"Primitives \t"<<unique_primitives<<"\t"<<instanced_primitives<<std::endl;
|
||||
}
|
||||
|
@ -88,6 +88,141 @@ class GraphicsContextX11 : public osg::GraphicsContext
|
||||
|
||||
}
|
||||
|
||||
class X11KeyboardMap
|
||||
{
|
||||
public:
|
||||
|
||||
X11KeyboardMap()
|
||||
{
|
||||
_keymap[XK_Escape ] = osgGA::GUIEventAdapter::KEY_Escape;
|
||||
_keymap[XK_F1 ] = osgGA::GUIEventAdapter::KEY_F1;
|
||||
_keymap[XK_F2 ] = osgGA::GUIEventAdapter::KEY_F2;
|
||||
_keymap[XK_F3 ] = osgGA::GUIEventAdapter::KEY_F3;
|
||||
_keymap[XK_F4 ] = osgGA::GUIEventAdapter::KEY_F4;
|
||||
_keymap[XK_F5 ] = osgGA::GUIEventAdapter::KEY_F5;
|
||||
_keymap[XK_F6 ] = osgGA::GUIEventAdapter::KEY_F6;
|
||||
_keymap[XK_F7 ] = osgGA::GUIEventAdapter::KEY_F7;
|
||||
_keymap[XK_F8 ] = osgGA::GUIEventAdapter::KEY_F8;
|
||||
_keymap[XK_F9 ] = osgGA::GUIEventAdapter::KEY_F9;
|
||||
_keymap[XK_F10 ] = osgGA::GUIEventAdapter::KEY_F10;
|
||||
_keymap[XK_F11 ] = osgGA::GUIEventAdapter::KEY_F11;
|
||||
_keymap[XK_F12 ] = osgGA::GUIEventAdapter::KEY_F12;
|
||||
_keymap[XK_quoteleft ] = '"';
|
||||
_keymap[XK_1 ] = '1';
|
||||
_keymap[XK_2 ] = '2';
|
||||
_keymap[XK_3 ] = '3';
|
||||
_keymap[XK_4 ] = '4';
|
||||
_keymap[XK_5 ] = '5';
|
||||
_keymap[XK_6 ] = '6';
|
||||
_keymap[XK_7 ] = '7';
|
||||
_keymap[XK_8 ] = '8';
|
||||
_keymap[XK_9 ] = '9';
|
||||
_keymap[XK_0 ] = '0';
|
||||
_keymap[XK_minus ] = '-';
|
||||
_keymap[XK_equal ] = '=';
|
||||
_keymap[XK_BackSpace ] = osgGA::GUIEventAdapter::KEY_BackSpace;
|
||||
_keymap[XK_Tab ] = osgGA::GUIEventAdapter::KEY_Tab;
|
||||
_keymap[XK_a ] = 'A';
|
||||
_keymap[XK_b ] = 'B';
|
||||
_keymap[XK_c ] = 'C';
|
||||
_keymap[XK_d ] = 'D';
|
||||
_keymap[XK_e ] = 'E';
|
||||
_keymap[XK_f ] = 'F';
|
||||
_keymap[XK_g ] = 'G';
|
||||
_keymap[XK_h ] = 'H';
|
||||
_keymap[XK_i ] = 'I';
|
||||
_keymap[XK_j ] = 'J';
|
||||
_keymap[XK_k ] = 'K';
|
||||
_keymap[XK_l ] = 'L';
|
||||
_keymap[XK_m ] = 'M';
|
||||
_keymap[XK_n ] = 'N';
|
||||
_keymap[XK_o ] = 'O';
|
||||
_keymap[XK_p ] = 'P';
|
||||
_keymap[XK_q ] = 'Q';
|
||||
_keymap[XK_r ] = 'R';
|
||||
_keymap[XK_s ] = 'S';
|
||||
_keymap[XK_t ] = 'T';
|
||||
_keymap[XK_u ] = 'U';
|
||||
_keymap[XK_v ] = 'V';
|
||||
_keymap[XK_w ] = 'W';
|
||||
_keymap[XK_x ] = 'X';
|
||||
_keymap[XK_y ] = 'Y';
|
||||
_keymap[XK_z ] = 'Z';
|
||||
_keymap[XK_bracketleft ] = '(';
|
||||
_keymap[XK_bracketright ] = ')';
|
||||
_keymap[XK_backslash ] = '\\';
|
||||
_keymap[XK_Caps_Lock ] = osgGA::GUIEventAdapter::KEY_Caps_Lock;
|
||||
_keymap[XK_semicolon ] = ';';
|
||||
_keymap[XK_apostrophe ] = '\'';
|
||||
_keymap[XK_Return ] = osgGA::GUIEventAdapter::KEY_Return;
|
||||
_keymap[XK_Shift_L ] = osgGA::GUIEventAdapter::KEY_Shift_L;
|
||||
_keymap[XK_comma ] = ',';
|
||||
_keymap[XK_period ] = '.';
|
||||
_keymap[XK_slash ] = '/';
|
||||
_keymap[XK_Shift_R ] = osgGA::GUIEventAdapter::KEY_Shift_R;
|
||||
_keymap[XK_Control_L ] = osgGA::GUIEventAdapter::KEY_Control_L;
|
||||
_keymap[XK_Super_L ] = osgGA::GUIEventAdapter::KEY_Super_L;
|
||||
_keymap[XK_space ] = ' ';
|
||||
_keymap[XK_Alt_L ] = osgGA::GUIEventAdapter::KEY_Alt_L;
|
||||
_keymap[XK_Alt_R ] = osgGA::GUIEventAdapter::KEY_Alt_R;
|
||||
_keymap[XK_Super_R ] = osgGA::GUIEventAdapter::KEY_Super_R;
|
||||
_keymap[XK_Menu ] = osgGA::GUIEventAdapter::KEY_Menu;
|
||||
_keymap[XK_Control_R ] = osgGA::GUIEventAdapter::KEY_Control_R;
|
||||
_keymap[XK_Print ] = osgGA::GUIEventAdapter::KEY_Print;
|
||||
_keymap[XK_Scroll_Lock ] = osgGA::GUIEventAdapter::KEY_Scroll_Lock;
|
||||
_keymap[XK_Pause ] = osgGA::GUIEventAdapter::KEY_Pause;
|
||||
_keymap[XK_Home ] = osgGA::GUIEventAdapter::KEY_Home;
|
||||
_keymap[XK_Page_Up ] = osgGA::GUIEventAdapter::KEY_Page_Up;
|
||||
_keymap[XK_End ] = osgGA::GUIEventAdapter::KEY_End;
|
||||
_keymap[XK_Page_Down ] = osgGA::GUIEventAdapter::KEY_Page_Down;
|
||||
_keymap[XK_Delete ] = osgGA::GUIEventAdapter::KEY_Delete;
|
||||
_keymap[XK_Insert ] = osgGA::GUIEventAdapter::KEY_Insert;
|
||||
_keymap[XK_Left ] = osgGA::GUIEventAdapter::KEY_Left;
|
||||
_keymap[XK_Up ] = osgGA::GUIEventAdapter::KEY_Up;
|
||||
_keymap[XK_Right ] = osgGA::GUIEventAdapter::KEY_Right;
|
||||
_keymap[XK_Down ] = osgGA::GUIEventAdapter::KEY_Down;
|
||||
_keymap[XK_Num_Lock ] = osgGA::GUIEventAdapter::KEY_Num_Lock;
|
||||
_keymap[XK_KP_Divide ] = osgGA::GUIEventAdapter::KEY_KP_Divide;
|
||||
_keymap[XK_KP_Multiply ] = osgGA::GUIEventAdapter::KEY_KP_Multiply;
|
||||
_keymap[XK_KP_Subtract ] = osgGA::GUIEventAdapter::KEY_KP_Subtract;
|
||||
_keymap[XK_KP_Add ] = osgGA::GUIEventAdapter::KEY_KP_Add;
|
||||
_keymap[XK_KP_Home ] = osgGA::GUIEventAdapter::KEY_KP_Home;
|
||||
_keymap[XK_KP_Up ] = osgGA::GUIEventAdapter::KEY_KP_Up;
|
||||
_keymap[XK_KP_Page_Up ] = osgGA::GUIEventAdapter::KEY_KP_Page_Up;
|
||||
_keymap[XK_KP_Left ] = osgGA::GUIEventAdapter::KEY_KP_Left;
|
||||
_keymap[XK_KP_Begin ] = osgGA::GUIEventAdapter::KEY_KP_Begin;
|
||||
_keymap[XK_KP_Right ] = osgGA::GUIEventAdapter::KEY_KP_Right;
|
||||
_keymap[XK_KP_End ] = osgGA::GUIEventAdapter::KEY_KP_End;
|
||||
_keymap[XK_KP_Down ] = osgGA::GUIEventAdapter::KEY_KP_Down;
|
||||
_keymap[XK_KP_Page_Down ] = osgGA::GUIEventAdapter::KEY_KP_Page_Down;
|
||||
_keymap[XK_KP_Insert ] = osgGA::GUIEventAdapter::KEY_KP_Insert;
|
||||
_keymap[XK_KP_Delete ] = osgGA::GUIEventAdapter::KEY_KP_Delete;
|
||||
_keymap[XK_KP_Enter ] = osgGA::GUIEventAdapter::KEY_KP_Enter;
|
||||
|
||||
}
|
||||
|
||||
~X11KeyboardMap() {}
|
||||
|
||||
int remapKey(int key)
|
||||
{
|
||||
KeyMap::iterator itr = _keymap.find(key);
|
||||
if (itr == _keymap.end()) return key;
|
||||
else return itr->second;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
typedef std::map<int, int> KeyMap;
|
||||
KeyMap _keymap;
|
||||
};
|
||||
|
||||
static int remapX11Key(int key)
|
||||
{
|
||||
static X11KeyboardMap s_x11KeyboardMap;
|
||||
return s_x11KeyboardMap.remapKey(key);
|
||||
}
|
||||
|
||||
bool GraphicsWindowX11::createVisualInfo()
|
||||
{
|
||||
typedef std::vector<int> 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 = "<<watt.x<<" watt.y="<<watt.y<<" width="<<watt.width<<" height="<<watt.height<<std::endl;
|
||||
|
||||
_valid = true;
|
||||
@ -388,7 +526,6 @@ void GraphicsWindowX11::makeCurrentImplementation()
|
||||
// checkEvents();
|
||||
|
||||
glXMakeCurrent( _display, _window, _glxContext );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -422,8 +559,6 @@ void GraphicsWindowX11::swapBuffersImplementation()
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"swapBuffersImplementation "<<this<<" "<<OpenThreads::Thread::CurrentThread()<<std::endl;
|
||||
|
||||
// makeCurrentImplementation();
|
||||
|
||||
glXSwapBuffers(_display, _window);
|
||||
|
||||
#if 0
|
||||
@ -437,6 +572,11 @@ void GraphicsWindowX11::checkEvents()
|
||||
{
|
||||
if (!_realized) return;
|
||||
|
||||
int windowX = _traits->x;
|
||||
int windowY = _traits->y;
|
||||
int windowWidth = _traits->width;
|
||||
int windowHeight = _traits->height;
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"Check events"<<std::endl;
|
||||
while( XPending(_display) )
|
||||
{
|
||||
@ -462,7 +602,7 @@ void GraphicsWindowX11::checkEvents()
|
||||
break;
|
||||
|
||||
case DestroyNotify :
|
||||
osg::notify(osg::INFO)<<"DestroyNotify"<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"DestroyNotify"<<std::endl;
|
||||
_realized = false;
|
||||
break;
|
||||
|
||||
@ -470,11 +610,17 @@ void GraphicsWindowX11::checkEvents()
|
||||
{
|
||||
osg::notify(osg::INFO)<<"ConfigureNotify x="<<ev.xconfigure.x<<" y="<<ev.xconfigure.y<<" width="<<ev.xconfigure.width<<", height="<<ev.xconfigure.height<<std::endl;
|
||||
|
||||
_traits->x = ev.xconfigure.x;
|
||||
_traits->y = ev.xconfigure.y;
|
||||
_traits->width = ev.xconfigure.width;
|
||||
_traits->height = ev.xconfigure.height;
|
||||
// need to dispatch resize event.
|
||||
if (windowX != ev.xconfigure.x ||
|
||||
windowX != ev.xconfigure.y ||
|
||||
windowWidth != ev.xconfigure.width ||
|
||||
windowHeight != ev.xconfigure.height)
|
||||
{
|
||||
windowX = ev.xconfigure.x;
|
||||
windowY = ev.xconfigure.y;
|
||||
windowWidth = ev.xconfigure.width;
|
||||
windowHeight = ev.xconfigure.height;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -487,8 +633,16 @@ void GraphicsWindowX11::checkEvents()
|
||||
while( watt.map_state != IsViewable );
|
||||
|
||||
osg::notify(osg::INFO)<<"MapNotify x="<<watt.x<<" y="<<watt.y<<" width="<<watt.width<<", height="<<watt.height<<std::endl;
|
||||
|
||||
if (windowWidth != watt.width || windowHeight != watt.height)
|
||||
{
|
||||
windowWidth = watt.width;
|
||||
windowHeight = watt.height;
|
||||
}
|
||||
|
||||
_traits->width = watt.width;
|
||||
_traits->height = watt.height;
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
@ -620,6 +774,15 @@ void GraphicsWindowX11::checkEvents()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (windowX != _traits->x ||
|
||||
windowY != _traits->y ||
|
||||
windowWidth != _traits->width ||
|
||||
windowHeight != _traits->height)
|
||||
{
|
||||
resized(windowX, windowY, windowWidth, windowHeight);
|
||||
getEventQueue()->windowResize(windowX, windowY, windowWidth, windowHeight);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsWindowX11::grabFocus()
|
||||
@ -654,8 +817,7 @@ void GraphicsWindowX11::transformMouseXY(float& x, float& y)
|
||||
|
||||
void GraphicsWindowX11::adaptKey(XKeyEvent& keyevent, int& keySymbol, unsigned int& modifierMask)
|
||||
{
|
||||
// KeySym ks = XKeycodeToKeysym( _display, keyevent.keycode, 0 );
|
||||
|
||||
|
||||
static XComposeStatus state;
|
||||
unsigned char keybuf[32];
|
||||
XLookupString( &keyevent, (char *)keybuf, sizeof(keybuf), NULL, &state );
|
||||
@ -687,6 +849,33 @@ void GraphicsWindowX11::adaptKey(XKeyEvent& keyevent, int& keySymbol, unsigned i
|
||||
}
|
||||
|
||||
keySymbol = keybuf[0];
|
||||
|
||||
KeySym ks = XKeycodeToKeysym( _display, keyevent.keycode, 0 );
|
||||
int remappedKey = remapX11Key(ks);
|
||||
if (remappedKey & 0xff00)
|
||||
{
|
||||
// special keyboard character
|
||||
keySymbol = remappedKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal ascii key
|
||||
keySymbol = keybuf[0];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void GraphicsWindowX11::requestWarpPointer(float x,float y)
|
||||
{
|
||||
XWarpPointer( _display,
|
||||
None,
|
||||
_window,
|
||||
0, 0, 0, 0,
|
||||
static_cast<int>(x), static_cast<int>(y) );
|
||||
|
||||
XFlush(_display);
|
||||
XSync(_display, 0);
|
||||
}
|
||||
|
||||
struct X11WindowingSystemInterface : public osg::GraphicsContext::WindowingSystemInterface
|
||||
|
@ -15,20 +15,10 @@
|
||||
#include <osgViewer/GraphicsWindow>
|
||||
|
||||
#include <osgUtil/SceneView>
|
||||
#include <osg/io_utils>
|
||||
|
||||
using namespace osgViewer;
|
||||
|
||||
class ActionAdapter : public osgGA::GUIActionAdapter
|
||||
{
|
||||
public:
|
||||
virtual ~ActionAdapter() {}
|
||||
|
||||
virtual void requestRedraw() { /*osg::notify(osg::NOTICE)<<"requestRedraw()"<<std::endl;*/ }
|
||||
virtual void requestContinuousUpdate(bool /*needed*/=true) { /*osg::notify(osg::NOTICE)<<"requestContinuousUpdate("<<needed<<")"<<std::endl;*/ }
|
||||
virtual void requestWarpPointer(float x,float y) { osg::notify(osg::NOTICE)<<"requestWarpPointer("<<x<<","<<y<<")"<<std::endl; }
|
||||
|
||||
};
|
||||
|
||||
View::View()
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<"Constructing osgViewer::View"<<std::endl;
|
||||
@ -57,8 +47,7 @@ void View::setCameraManipulator(osgGA::MatrixManipulator* manipulator)
|
||||
|
||||
osg::ref_ptr<osgGA::GUIEventAdapter> 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."<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
_camera->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; i<numScreens; ++i, rotate_x += fovx)
|
||||
{
|
||||
unsigned int width, height;
|
||||
@ -150,11 +143,6 @@ void View::setUpViewAcrossAllScreens()
|
||||
osg::notify(osg::INFO)<<" GraphicsWindow has been created successfully."<<gw<<std::endl;
|
||||
|
||||
gw->getEventQueue()->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"<<std::endl;
|
||||
|
||||
_sceneView->cull();
|
||||
_sceneView->draw();
|
||||
|
||||
@ -255,8 +247,7 @@ void View::assignSceneDataToCameras()
|
||||
|
||||
osg::ref_ptr<osgGA::GUIEventAdapter> 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<osgViewer::GraphicsWindow*>(_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; i<getNumSlaves(); ++i)
|
||||
{
|
||||
Slave& slave = getSlave(i);
|
||||
if (slave._camera.valid())
|
||||
{
|
||||
osg::Camera* camera = slave._camera.get();
|
||||
osg::Viewport* viewport = camera ? camera->getViewport() : 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<osgViewer::GraphicsWindow*>(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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -18,19 +18,10 @@
|
||||
#include <osgUtil/GLObjectsVisitor>
|
||||
#include <osg/GLExtensions>
|
||||
|
||||
#include <osg/io_utils>
|
||||
|
||||
using namespace osgViewer;
|
||||
|
||||
class ActionAdapter : public osgGA::GUIActionAdapter
|
||||
{
|
||||
public:
|
||||
virtual ~ActionAdapter() {}
|
||||
|
||||
virtual void requestRedraw() { /*osg::notify(osg::NOTICE)<<"requestRedraw()"<<std::endl;*/ }
|
||||
virtual void requestContinuousUpdate(bool =true) { /*osg::notify(osg::NOTICE)<<"requestContinuousUpdate("<<needed<<")"<<std::endl;*/ }
|
||||
virtual void requestWarpPointer(float x,float y) { osg::notify(osg::NOTICE)<<"requestWarpPointer("<<x<<","<<y<<")"<<std::endl; }
|
||||
|
||||
};
|
||||
|
||||
Viewer::Viewer():
|
||||
_firstFrame(true),
|
||||
_done(false)
|
||||
@ -69,8 +60,7 @@ void Viewer::init()
|
||||
|
||||
if (_cameraManipulator.valid())
|
||||
{
|
||||
ActionAdapter aa;
|
||||
_cameraManipulator->init(*initEvent, aa);
|
||||
_cameraManipulator->init(*initEvent, *this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,12 +147,14 @@ void Viewer::realize()
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Viewer::realize()"<<std::endl;
|
||||
|
||||
setCameraWithFocus(0);
|
||||
|
||||
Contexts::iterator citr;
|
||||
|
||||
Contexts contexts;
|
||||
getContexts(contexts);
|
||||
|
||||
bool multiThreaded = getNumSlaves() > 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 = "<<event->getX()<<" y="<<event->getY()<<std::endl;
|
||||
// osg::notify(osg::NOTICE)<<" mouse Xmin = "<<event->getXmin()<<" Ymin="<<event->getYmin()<<" xMax="<<event->getXmax()<<" Ymax="<<event->getYmax()<<std::endl;
|
||||
}
|
||||
|
||||
events.insert(events.end(), gw_events.begin(), gw_events.end());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState();
|
||||
#if 0
|
||||
// pointer coordinate transform
|
||||
for(osgGA::EventQueue::Events::iterator itr = events.begin();
|
||||
itr != events.end();
|
||||
++itr)
|
||||
@ -321,12 +418,13 @@ void Viewer::frameEventTraversal()
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"mouseEventState Xmin = "<<eventState->getXmin()<<" Ymin="<<eventState->getYmin()<<" xMax="<<eventState->getXmax()<<" Ymax="<<eventState->getYmax()<<std::endl;
|
||||
|
||||
|
||||
_eventQueue->frame( _scene->getFrameStamp()->getReferenceTime() );
|
||||
|
||||
_eventQueue->takeEvents(events);
|
||||
|
||||
|
||||
@ -360,6 +458,9 @@ void Viewer::frameEventTraversal()
|
||||
case(osgGA::GUIEventAdapter::KEYUP):
|
||||
osg::notify(osg::NOTICE)<<" KEYUP '"<<(char)event->getKey()<<"'"<<std::endl;
|
||||
break;
|
||||
case(osgGA::GUIEventAdapter::RESIZE):
|
||||
osg::notify(osg::NOTICE)<<" RESIZE "<<std::endl;
|
||||
break;
|
||||
case(osgGA::GUIEventAdapter::FRAME):
|
||||
// osg::notify(osg::NOTICE)<<" FRAME "<<std::endl;
|
||||
break;
|
||||
@ -379,7 +480,7 @@ void Viewer::frameEventTraversal()
|
||||
switch(event->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()
|
||||
|
Loading…
Reference in New Issue
Block a user