| 310 | | } |
| 311 | | |
| 312 | | class DomeModel |
| 313 | | { |
| 314 | | public: |
| 315 | | |
| 316 | | DomeModel(osg::ArgumentParser& arguments): |
| 317 | | sphere_radius(1.0), |
| 318 | | collar_radius(0.45), |
| 319 | | rotationDegrees(180.0), |
| 320 | | distance(0.0), |
| 321 | | flip(false), |
| 322 | | texcoord_flip(false) |
| 323 | | { |
| 324 | | if (arguments.read("--radius", sphere_radius)) {} |
| 325 | | if (arguments.read("--collar", collar_radius)) {} |
| 326 | | if (arguments.read("--rotation", rotationDegrees)) {} |
| 327 | | |
| 328 | | distance = sqrt(sphere_radius*sphere_radius - collar_radius*collar_radius); |
| 329 | | if (arguments.read("--distance", distance)) {} |
| 330 | | |
| 331 | | if (arguments.read("--flip")) { flip = true; } |
| 332 | | } |
| 333 | | |
| 334 | | double sphere_radius; |
| 335 | | double collar_radius; |
| 336 | | double rotationDegrees; |
| 337 | | double distance; |
| 338 | | bool flip; |
| 339 | | bool texcoord_flip; |
| 340 | | |
| 341 | | }; |
| 342 | | |
| 343 | | |
| 344 | | osg::Geometry* createDomeDistortionMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector, DomeModel& domeModel) |
| 345 | | { |
| 346 | | osg::Vec3d center(0.0,0.0,0.0); |
| 347 | | osg::Vec3d eye(0.0,0.0,0.0); |
| 348 | | |
| 349 | | bool centerProjection = false; |
| 350 | | |
| 351 | | osg::Vec3d projector = eye - osg::Vec3d(0.0,0.0, domeModel.distance); |
| 352 | | |
| 353 | | |
| 354 | | osg::notify(osg::NOTICE)<<"Projector position = "<<projector<<std::endl; |
| 355 | | osg::notify(osg::NOTICE)<<"distance = "<<domeModel.distance<<std::endl; |
| 356 | | |
| 357 | | |
| 358 | | // create the quad to visualize. |
| 359 | | osg::Geometry* geometry = new osg::Geometry(); |
| 360 | | |
| 361 | | geometry->setSupportsDisplayList(false); |
| 362 | | |
| 363 | | osg::Vec3 xAxis(widthVector); |
| 364 | | float width = widthVector.length(); |
| 365 | | xAxis /= width; |
| 366 | | |
| 367 | | osg::Vec3 yAxis(heightVector); |
| 368 | | float height = heightVector.length(); |
| 369 | | yAxis /= height; |
| 370 | | |
| 371 | | int noSteps = 160; |
| 372 | | |
| 373 | | osg::Vec3Array* vertices = new osg::Vec3Array; |
| 374 | | osg::Vec2Array* texcoords = new osg::Vec2Array; |
| 375 | | osg::Vec4Array* colors = new osg::Vec4Array; |
| 376 | | |
| 377 | | osg::Vec3 bottom = origin; |
| 378 | | osg::Vec3 dx = xAxis*(width/((float)(noSteps-2))); |
| 379 | | osg::Vec3 dy = yAxis*(height/((float)(noSteps-1))); |
| 380 | | |
| 381 | | osg::Vec3 top = origin + yAxis*height; |
| 382 | | |
| 383 | | osg::Vec3d screenCenter = origin + widthVector*0.5f + heightVector*0.5f; |
| 384 | | float screenRadius = heightVector.length() * 0.5f; |
| 385 | | |
| 386 | | double rotation = osg::DegreesToRadians(domeModel.rotationDegrees); |
| 387 | | |
| 388 | | osg::Vec3 cursor = bottom; |
| 389 | | int i,j; |
| 390 | | |
| 391 | | int midSteps = noSteps/2; |
| 392 | | |
| 393 | | for(i=0;i<midSteps;++i) |
| 394 | | { |
| 395 | | osg::Vec3 cursor = bottom+dy*(float)i; |
| 396 | | for(j=0;j<midSteps;++j) |
| 397 | | { |
| 398 | | osg::Vec2 delta(cursor.x() - screenCenter.x(), cursor.y() - screenCenter.y()); |
| 399 | | double theta = atan2(delta.x(), -delta.y()); |
| 400 | | theta += 2*osg::PI; |
| 401 | | |
| 402 | | double phi = osg::PI_2 * delta.length() / screenRadius; |
| 403 | | if (phi > osg::PI_2) phi = osg::PI_2; |
| 404 | | |
| 405 | | double f = domeModel.distance * sin(phi); |
| 406 | | double e = domeModel.distance * cos(phi) + sqrt( domeModel.sphere_radius*domeModel.sphere_radius - f*f); |
| 407 | | double l = e * cos(phi); |
| 408 | | double h = e * sin(phi); |
| 409 | | double gamma = atan2(h, l-domeModel.distance); |
| 410 | | |
| 411 | | osg::Vec2 texcoord(theta/(2.0*osg::PI), 1.0-gamma/osg::PI); |
| 412 | | |
| 413 | | // osg::notify(osg::NOTICE)<<"cursor = "<<cursor<< " theta = "<<theta<< "phi="<<phi<<" gamma = "<<gamma<<" texcoord="<<texcoord<<std::endl; |
| 414 | | |
| 415 | | if (domeModel.flip) |
| 416 | | vertices->push_back(osg::Vec3(cursor.x(), top.y()-(cursor.y()-origin.y()),cursor.z())); |
| 417 | | else |
| 418 | | vertices->push_back(cursor); |
| 419 | | |
| 420 | | colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); |
| 421 | | texcoords->push_back( domeModel.texcoord_flip ? osg::Vec2(texcoord.x(), 1.0f - texcoord.y()) : texcoord); |
| 422 | | |
| 423 | | if (j+1<midSteps) cursor += dx; |
| 424 | | } |
| 425 | | |
| 426 | | for(;j<noSteps;++j) |
| 427 | | { |
| 428 | | osg::Vec2 delta(cursor.x() - screenCenter.x(), cursor.y() - screenCenter.y()); |
| 429 | | double theta = atan2(delta.x(), -delta.y()); |
| 430 | | double phi = osg::PI_2 * delta.length() / screenRadius; |
| 431 | | if (phi > osg::PI_2) phi = osg::PI_2; |
| 432 | | |
| 433 | | double f = domeModel.distance * sin(phi); |
| 434 | | double e = domeModel.distance * cos(phi) + sqrt( domeModel.sphere_radius*domeModel.sphere_radius - f*f); |
| 435 | | double l = e * cos(phi); |
| 436 | | double h = e * sin(phi); |
| 437 | | double gamma = atan2(h, l-domeModel.distance); |
| 438 | | |
| 439 | | osg::Vec2 texcoord(theta/(2.0*osg::PI), 1.0-gamma/osg::PI); |
| 440 | | |
| 441 | | // osg::notify(osg::NOTICE)<<"cursor = "<<cursor<< " theta = "<<theta<< "phi="<<phi<<" gamma = "<<gamma<<" texcoord="<<texcoord<<std::endl; |
| 442 | | |
| 443 | | if (domeModel.flip) |
| 444 | | vertices->push_back(osg::Vec3(cursor.x(), top.y()-(cursor.y()-origin.y()),cursor.z())); |
| 445 | | else |
| 446 | | vertices->push_back(cursor); |
| 447 | | |
| 448 | | colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); |
| 449 | | texcoords->push_back( domeModel.texcoord_flip ? osg::Vec2(texcoord.x(), 1.0f - texcoord.y()) : texcoord); |
| 450 | | |
| 451 | | cursor += dx; |
| 452 | | } |
| 453 | | // osg::notify(osg::NOTICE)<<std::endl; |
| 454 | | } |
| 455 | | |
| 456 | | for(;i<noSteps;++i) |
| 457 | | { |
| 458 | | osg::Vec3 cursor = bottom+dy*(float)i; |
| 459 | | for(j=0;j<noSteps;++j) |
| 460 | | { |
| 461 | | osg::Vec2 delta(cursor.x() - screenCenter.x(), cursor.y() - screenCenter.y()); |
| 462 | | double theta = atan2(delta.x(), -delta.y()); |
| 463 | | if (theta<0.0) theta += 2*osg::PI; |
| 464 | | double phi = osg::PI_2 * delta.length() / screenRadius; |
| 465 | | if (phi > osg::PI_2) phi = osg::PI_2; |
| 466 | | |
| 467 | | double f = domeModel.distance * sin(phi); |
| 468 | | double e = domeModel.distance * cos(phi) + sqrt( domeModel.sphere_radius*domeModel.sphere_radius - f*f); |
| 469 | | double l = e * cos(phi); |
| 470 | | double h = e * sin(phi); |
| 471 | | double gamma = atan2(h, l-domeModel.distance); |
| 472 | | |
| 473 | | osg::Vec2 texcoord(theta/(2.0*osg::PI), 1.0-gamma/osg::PI); |
| 474 | | |
| 475 | | // osg::notify(osg::NOTICE)<<"cursor = "<<cursor<< " theta = "<<theta<< "phi="<<phi<<" gamma = "<<gamma<<" texcoord="<<texcoord<<std::endl; |
| 476 | | |
| 477 | | if (domeModel.flip) |
| 478 | | vertices->push_back(osg::Vec3(cursor.x(), top.y()-(cursor.y()-origin.y()),cursor.z())); |
| 479 | | else |
| 480 | | vertices->push_back(cursor); |
| 481 | | |
| 482 | | colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); |
| 483 | | texcoords->push_back( domeModel.texcoord_flip ? osg::Vec2(texcoord.x(), 1.0f - texcoord.y()) : texcoord); |
| 484 | | |
| 485 | | cursor += dx; |
| 486 | | } |
| 487 | | |
| 488 | | // osg::notify(osg::NOTICE)<<std::endl; |
| 489 | | } |
| 490 | | |
| 491 | | // pass the created vertex array to the points geometry object. |
| 492 | | geometry->setVertexArray(vertices); |
| 493 | | |
| 494 | | geometry->setColorArray(colors); |
| 495 | | geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); |
| 496 | | |
| 497 | | geometry->setTexCoordArray(0,texcoords); |
| 498 | | |
| 499 | | for(i=0;i<noSteps-1;++i) |
| 500 | | { |
| 501 | | osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(osg::PrimitiveSet::QUAD_STRIP); |
| 502 | | for(j=0;j<noSteps;++j) |
| 503 | | { |
| 504 | | elements->push_back(j+(i+1)*noSteps); |
| 505 | | elements->push_back(j+(i)*noSteps); |
| 506 | | } |
| 507 | | geometry->addPrimitiveSet(elements); |
| 508 | | } |
| 509 | | |
| 510 | | return geometry; |
| 511 | | } |
| 512 | | |
| 513 | | |
| 514 | | void setDomeCorrection(osgViewer::Viewer& viewer, osg::ArgumentParser& arguments) |
| 515 | | { |
| 516 | | // enforce single threading right now to avoid double buffering of RTT texture |
| 517 | | viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); |
| 518 | | |
| 519 | | osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); |
| 520 | | if (!wsi) |
| 521 | | { |
| 522 | | osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl; |
| 523 | | return; |
| 524 | | } |
| 525 | | |
| 526 | | unsigned int screenNum = 0; |
| 527 | | while (arguments.read("--screen",screenNum)) {} |
| 528 | | |
| 529 | | |
| 530 | | unsigned int width, height; |
| 531 | | wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(screenNum), width, height); |
| 532 | | |
| 533 | | while (arguments.read("--width",width)) {} |
| 534 | | while (arguments.read("--height",height)) {} |
| 535 | | |
| 536 | | DomeModel domeModel(arguments); |
| 537 | | |
| 538 | | osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; |
| 539 | | traits->screenNum = screenNum; |
| 540 | | traits->x = 0; |
| 541 | | traits->y = 0; |
| 542 | | traits->width = width; |
| 543 | | traits->height = height; |
| 544 | | traits->windowDecoration = false; |
| 545 | | traits->doubleBuffer = true; |
| 546 | | traits->sharedContext = 0; |
| 547 | | |
| 548 | | |
| 549 | | |
| 550 | | osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get()); |
| 551 | | if (!gc) |
| 552 | | { |
| 553 | | osg::notify(osg::NOTICE)<<"GraphicsWindow has not been created successfully."<<std::endl; |
| 554 | | return; |
| 555 | | } |
| 556 | | |
| 557 | | osg::Texture* texture = 0; |
| 558 | | for(int i=1;i<arguments.argc() && !texture;++i) |
| 559 | | { |
| 560 | | if (arguments.isString(i)) |
| 561 | | { |
| 562 | | osg::Image* image = osgDB::readImageFile(arguments[i]); |
| 563 | | osg::ImageStream* imagestream = dynamic_cast<osg::ImageStream*>(image); |
| 564 | | if (imagestream) imagestream->play(); |
| 565 | | |
| 566 | | if (image) |
| 567 | | { |
| 568 | | domeModel.texcoord_flip = image->getOrigin()==osg::Image::TOP_LEFT; |
| 569 | | |
| 570 | | #if 1 |
| 571 | | texture = new osg::TextureRectangle(image); |
| 572 | | #else |
| 573 | | texture = new osg::Texture2D(image); |
| 574 | | #endif |
| 575 | | } |
| 576 | | } |
| 577 | | } |
| 578 | | |
| 579 | | if (!texture) |
| 580 | | { |
| 581 | | return; |
| 582 | | } |
| 583 | | |
| 584 | | // distortion correction set up. |
| 585 | | { |
| 586 | | osg::Geode* geode = new osg::Geode(); |
| 587 | | geode->addDrawable( createDomeDistortionMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), domeModel) ); |
| 588 | | |
| 589 | | // new we need to add the texture to the mesh, we do so by creating a |
| 590 | | // StateSet to contain the Texture StateAttribute. |
| 591 | | osg::StateSet* stateset = geode->getOrCreateStateSet(); |
| 592 | | stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); |
| 593 | | texture->setMaxAnisotropy(16.0f); |
| 594 | | stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); |
| 595 | | #if 1 |
| 596 | | osg::TexMat* texmat = new osg::TexMat; |
| 597 | | texmat->setScaleByTextureRectangleSize(true); |
| 598 | | stateset->setTextureAttributeAndModes(0, texmat, osg::StateAttribute::ON); |
| 599 | | #endif |
| 600 | | osg::ref_ptr<osg::Camera> camera = new osg::Camera; |
| 601 | | camera->setGraphicsContext(gc.get()); |
| 602 | | camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); |
| 603 | | camera->setClearColor( osg::Vec4(0.1,0.1,1.0,1.0) ); |
| 604 | | camera->setViewport(new osg::Viewport(0, 0, width, height)); |
| 605 | | GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; |
| 606 | | camera->setDrawBuffer(buffer); |
| 607 | | camera->setReadBuffer(buffer); |
| 608 | | camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); |
| 609 | | camera->setAllowEventFocus(false); |
| 610 | | //camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE); |
| 611 | | //camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); |
| 612 | | |
| 613 | | camera->setProjectionMatrixAsOrtho2D(0,width,0,height); |
| 614 | | camera->setViewMatrix(osg::Matrix::identity()); |
| 615 | | |
| 616 | | // add subgraph to render |
| 617 | | // camera->addChild(geode); |
| 618 | | |
| 619 | | camera->setName("DistortionCorrectionCamera"); |
| 620 | | |
| 621 | | viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd(), true); |
| 622 | | |
| 623 | | viewer.setSceneData(geode); |
| 624 | | } |
| 625 | | |
| 626 | | |
| 627 | | viewer.getCamera()->setNearFarRatio(0.0001f); |
| 666 | | |
| 667 | | |
| 668 | | if (arguments.read("--dome") || arguments.read("--puffer") ) |
| 669 | | { |
| 670 | | setDomeCorrection(viewer, arguments); |
| 671 | | } |
| 672 | | else |
| 673 | | { |
| 674 | | osg::ref_ptr<osg::Geode> geode = new osg::Geode; |
| 675 | | osg::Vec3 pos(0.0f,0.0f,0.0f); |
| 676 | | |
| 677 | | osg::StateSet* stateset = geode->getOrCreateStateSet(); |
| 678 | | stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); |
| 679 | | |
| 680 | | if (useShader) |
| 681 | | { |
| 682 | | //useTextureRectangle = false; |
| 683 | | |
| 684 | | static const char *shaderSourceTextureRec = { |
| 685 | | "uniform vec4 cutoff_color;\n" |
| 686 | | "uniform samplerRect movie_texture;\n" |
| 687 | | "void main(void)\n" |
| 688 | | "{\n" |
| 689 | | " vec4 texture_color = textureRect(movie_texture, gl_TexCoord[0]); \n" |
| 690 | | " if (all(lessThanEqual(texture_color,cutoff_color))) discard; \n" |
| 691 | | " gl_FragColor = texture_color;\n" |
| 692 | | "}\n" |
| 693 | | }; |
| 694 | | |
| 695 | | static const char *shaderSourceTexture2D = { |
| 696 | | "uniform vec4 cutoff_color;\n" |
| 697 | | "uniform sampler2D movie_texture;\n" |
| 698 | | "void main(void)\n" |
| 699 | | "{\n" |
| 700 | | " vec4 texture_color = texture2D(movie_texture, gl_TexCoord[0]); \n" |
| 701 | | " if (all(lessThanEqual(texture_color,cutoff_color))) discard; \n" |
| 702 | | " gl_FragColor = texture_color;\n" |
| 703 | | "}\n" |
| 704 | | }; |
| 705 | | |
| 706 | | osg::Program* program = new osg::Program; |
| 707 | | |
| 708 | | program->addShader(new osg::Shader(osg::Shader::FRAGMENT, |
| 709 | | useTextureRectangle ? shaderSourceTextureRec : shaderSourceTexture2D)); |
| 710 | | |
| 711 | | stateset->addUniform(new osg::Uniform("cutoff_color",osg::Vec4(0.1f,0.1f,0.1f,1.0f))); |
| 712 | | stateset->addUniform(new osg::Uniform("movie_texture",0)); |
| 713 | | |
| 714 | | stateset->setAttribute(program); |
| 715 | | |
| 716 | | } |
| 717 | | |
| 718 | | for(int i=1;i<arguments.argc();++i) |
| 719 | | { |
| 720 | | if (arguments.isString(i)) |
| 721 | | { |
| 722 | | osg::Image* image = osgDB::readImageFile(arguments[i]); |
| 723 | | osg::ImageStream* imagestream = dynamic_cast<osg::ImageStream*>(image); |
| 724 | | if (imagestream) imagestream->play(); |
| 725 | | |
| 726 | | if (image) |
| 727 | | { |
| 728 | | geode->addDrawable(myCreateTexturedQuadGeometry(pos,image->s(),image->t(),image, useTextureRectangle)); |
| 729 | | |
| 730 | | pos.z() += image->t()*1.5f; |
| 731 | | } |
| 732 | | else |
| 733 | | { |
| 734 | | std::cout<<"Unable to read file "<<arguments[i]<<std::endl; |
| 735 | | } |
| 736 | | } |
| 737 | | } |
| 738 | | |
| 739 | | // set the scene to render |
| 740 | | viewer.setSceneData(geode.get()); |
| 741 | | |
| 742 | | if (viewer.getSceneData()==0) |
| 743 | | { |
| 744 | | arguments.getApplicationUsage()->write(std::cout); |
| 745 | | return 1; |
| 746 | | } |
| 747 | | } |
| 748 | | |
| | 349 | bool fullscreen = !arguments.read("--interactive"); |
| | 350 | |
| | 351 | |
| | 352 | osg::ref_ptr<osg::Geode> geode = new osg::Geode; |
| | 353 | |
| | 354 | osg::StateSet* stateset = geode->getOrCreateStateSet(); |
| | 355 | stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); |
| | 356 | |
| | 357 | if (useShader) |
| | 358 | { |
| | 359 | //useTextureRectangle = false; |
| | 360 | |
| | 361 | static const char *shaderSourceTextureRec = { |
| | 362 | "uniform vec4 cutoff_color;\n" |
| | 363 | "uniform samplerRect movie_texture;\n" |
| | 364 | "void main(void)\n" |
| | 365 | "{\n" |
| | 366 | " vec4 texture_color = textureRect(movie_texture, gl_TexCoord[0]); \n" |
| | 367 | " if (all(lessThanEqual(texture_color,cutoff_color))) discard; \n" |
| | 368 | " gl_FragColor = texture_color;\n" |
| | 369 | "}\n" |
| | 370 | }; |
| | 371 | |
| | 372 | static const char *shaderSourceTexture2D = { |
| | 373 | "uniform vec4 cutoff_color;\n" |
| | 374 | "uniform sampler2D movie_texture;\n" |
| | 375 | "void main(void)\n" |
| | 376 | "{\n" |
| | 377 | " vec4 texture_color = texture2D(movie_texture, gl_TexCoord[0]); \n" |
| | 378 | " if (all(lessThanEqual(texture_color,cutoff_color))) discard; \n" |
| | 379 | " gl_FragColor = texture_color;\n" |
| | 380 | "}\n" |
| | 381 | }; |
| | 382 | |
| | 383 | osg::Program* program = new osg::Program; |
| | 384 | |
| | 385 | program->addShader(new osg::Shader(osg::Shader::FRAGMENT, |
| | 386 | useTextureRectangle ? shaderSourceTextureRec : shaderSourceTexture2D)); |
| | 387 | |
| | 388 | stateset->addUniform(new osg::Uniform("cutoff_color",osg::Vec4(0.1f,0.1f,0.1f,1.0f))); |
| | 389 | stateset->addUniform(new osg::Uniform("movie_texture",0)); |
| | 390 | |
| | 391 | stateset->setAttribute(program); |
| | 392 | |
| | 393 | } |
| | 394 | |
| | 395 | osg::Vec3 pos(0.0f,0.0f,0.0f); |
| | 396 | osg::Vec3 topleft = pos; |
| | 397 | osg::Vec3 bottomright = pos; |
| | 398 | |
| | 399 | bool xyPlane = fullscreen; |
| | 400 | |
| | 401 | for(int i=1;i<arguments.argc();++i) |
| | 402 | { |
| | 403 | if (arguments.isString(i)) |
| | 404 | { |
| | 405 | osg::Image* image = osgDB::readImageFile(arguments[i]); |
| | 406 | osg::ImageStream* imagestream = dynamic_cast<osg::ImageStream*>(image); |
| | 407 | if (imagestream) imagestream->play(); |
| | 408 | |
| | 409 | if (image) |
| | 410 | { |
| | 411 | geode->addDrawable(myCreateTexturedQuadGeometry(pos,image->s(),image->t(),image, useTextureRectangle, xyPlane)); |
| | 412 | |
| | 413 | bottomright = pos + osg::Vec3(static_cast<float>(image->s()),static_cast<float>(image->t()),0.0f); |
| | 414 | |
| | 415 | pos.y() += image->t()*1.5f; |
| | 416 | } |
| | 417 | else |
| | 418 | { |
| | 419 | std::cout<<"Unable to read file "<<arguments[i]<<std::endl; |
| | 420 | } |
| | 421 | } |
| | 422 | } |
| | 423 | |
| | 424 | // set the scene to render |
| | 425 | viewer.setSceneData(geode.get()); |
| | 426 | |
| | 427 | if (viewer.getSceneData()==0) |
| | 428 | { |
| | 429 | arguments.getApplicationUsage()->write(std::cout); |
| | 430 | return 1; |
| | 431 | } |