osgDB::ReaderWriter::ReadResult ReaderWriterLORENZ::readNode( const std::string& fileName, const osgDB::ReaderWriter::Options* options ) const { std::string ext( osgDB::getLowerCaseFileExtension(fileName) ); if( !acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED; osg::notify(osg::INFO) << "ReaderWriterLORENZ( \"" << fileName << "\" )" << std::endl; // strip the pseudo-loader extension, leaving the parameter string std::string params( osgDB::getNameLessExtension(fileName) ); osg::notify(osg::INFO) << EXTENSION_NAME " params = \"" << params << "\"" << std::endl; int numPoints; int count( sscanf( params.c_str(), "%d", &numPoints ) ); if( count != 1 ) { osg::notify(osg::WARN) << "Bad parameters for " EXTENSION_NAME " pseudo-loader: \"" << params << "\"" << std::endl; return ReadResult::FILE_NOT_HANDLED; } osg::Geode* geode( new osg::Geode ); geode->addDrawable( new osgToy::LorenzAttractor( numPoints ) ); return geode; }
void CSVRender::CellMarker::buildMarker() { const int characterSize = 20; // Set up attributes of marker text. osg::ref_ptr<osgText::Text> markerText (new osgText::Text); markerText->setLayout(osgText::Text::LEFT_TO_RIGHT); markerText->setCharacterSize(characterSize); markerText->setAlignment(osgText::Text::CENTER_CENTER); markerText->setDrawMode(osgText::Text::TEXT | osgText::Text::FILLEDBOUNDINGBOX); // If cell exists then show black bounding box otherwise show red. if (mExists) { markerText->setBoundingBoxColor(osg::Vec4f(0.0f, 0.0f, 0.0f, 1.0f)); } else { markerText->setBoundingBoxColor(osg::Vec4f(1.0f, 0.0f, 0.0f, 1.0f)); } // Add text containing cell's coordinates. std::string coordinatesText = boost::lexical_cast<std::string>(mCoordinates.getX()) + "," + boost::lexical_cast<std::string>(mCoordinates.getY()); markerText->setText(coordinatesText); // Add text to marker node. osg::ref_ptr<osg::Geode> geode (new osg::Geode); geode->addDrawable(markerText); mMarkerNode->addChild(geode); }
FaceTransform::FaceTransform(Drawable drawable) :_drawable(drawable) { osg::ref_ptr<osg::Geode> geode(new osg::Geode()); geode->addDrawable(_drawable); addChild(geode); }
int main( int argc, char** argv ) { osg::ref_ptr< osg::MatrixTransform > root( new osg::MatrixTransform ); osg::ref_ptr< osg::Geode > geode( new osg::Geode ); root->addChild( geode.get() ); osg::Matrix m; osg::ref_ptr< osg::Vec4Array > c; osg::Geometry* geom; const osg::Vec3d baseUp( 0., 0., 1. ); const osg::Vec3d baseRight( 1., 0., 0. ); const osg::Vec3d baseDir( 0., 1., 0. ); m.set( 1., 0., 0., 0., 0., 1., 0., 0., baseUp[0], baseUp[1], baseUp[2], 0., 0., 0., 0., 1. ); c = new osg::Vec4Array(); c->resize( 1 ); (*c)[0].set( 0., 0., 1., 1. ); geom = osgwTools::makeArrow( m ); geom->setColorArray( c.get() ); geode->addDrawable( geom ); m.set( 0., 0., 1., 0., 0., 1., 0., 0., baseRight[0], baseRight[1], baseRight[2], 0., 0., 0., 0., 1. ); c = new osg::Vec4Array(); c->resize( 1 ); (*c)[0].set( 1., 0., 0., 1. ); geom = osgwTools::makeArrow( m ); geom->setColorArray( c.get() ); geode->addDrawable( geom ); m.set( 1., 0., 0., 0., 0., 0., 1., 0., baseDir[0], baseDir[1], baseDir[2], 0., 0., 0., 0., 1. ); c = new osg::Vec4Array(); c->resize( 1 ); (*c)[0].set( 0., 1., 0., 1. ); geom = osgwTools::makeArrow( m ); geom->setColorArray( c.get() ); geode->addDrawable( geom ); YPRManip* yprManip = new YPRManip( root.get() ); osgViewer::Viewer viewer; viewer.setUpViewInWindow( 20., 30., 1027., 768. ); viewer.addEventHandler( yprManip ); viewer.setSceneData( root.get() ); return( viewer.run() ); }
osg::Node* postRender( osgViewer::Viewer& viewer ) { osg::Camera* rootCamera( viewer.getCamera() ); // Create the texture; we'll use this as our color buffer. // Note it has no image data; not required. osg::Texture2D* tex = new osg::Texture2D; tex->setTextureSize( winW, winH ); tex->dirtyTextureObject(); tex->setInternalFormat( GL_RGBA ); tex->setBorderWidth( 0 ); tex->setFilter( osg::Texture::MIN_FILTER, osg::Texture::NEAREST ); tex->setFilter( osg::Texture::MAG_FILTER, osg::Texture::NEAREST ); // Attach the texture to the camera. Tell it to use multisampling. // Internally, OSG allocates a multisampled renderbuffer, renders to it, // and at the end of the frame performs a BlitFramebuffer into our texture. rootCamera->attach( osg::Camera::COLOR_BUFFER0, tex, 0, 0, false ); rootCamera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT, osg::Camera::FRAME_BUFFER ); #if( OSGWORKS_OSG_VERSION >= 20906 ) rootCamera->setImplicitBufferAttachmentMask( osg::Camera::IMPLICIT_COLOR_BUFFER_ATTACHMENT|osg::Camera::IMPLICIT_DEPTH_BUFFER_ATTACHMENT, osg::Camera::IMPLICIT_COLOR_BUFFER_ATTACHMENT ); #endif // Configure postRenderCamera to draw fullscreen textured quad osg::ref_ptr< osg::Camera > postRenderCamera( new osg::Camera ); postRenderCamera->setClearColor( osg::Vec4( 0., 1., 0., 1. ) ); // should never see this. postRenderCamera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER, osg::Camera::FRAME_BUFFER ); postRenderCamera->setReferenceFrame( osg::Camera::ABSOLUTE_RF ); postRenderCamera->setRenderOrder( osg::Camera::POST_RENDER ); postRenderCamera->setViewMatrix( osg::Matrixd::identity() ); postRenderCamera->setProjectionMatrix( osg::Matrixd::identity() ); osg::Geode* geode( new osg::Geode ); geode->addDrawable( osgwTools::makePlane( osg::Vec3( -1,-1,0 ), osg::Vec3( 2,0,0 ), osg::Vec3( 0,2,0 ) ) ); geode->getOrCreateStateSet()->setTextureAttributeAndModes( 0, tex, osg::StateAttribute::ON ); geode->getOrCreateStateSet()->setAttribute( myCreateEffectProgram( "none" ) ); geode->getOrCreateStateSet()->addUniform( new osg::Uniform( "inputTextures[0]", 0 ) ); postRenderCamera->addChild( geode ); return( postRenderCamera.release() ); }
osg::ref_ptr<osg::Drawable> myQuad () { osg::ref_ptr<osg::Geode> geode (new osg::Geode()); osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry()); osg::ref_ptr<osg::Vec3Array> vertices (new osg::Vec3Array()); vertices->push_back (osg::Vec3 ( 1.0, 0.0, 0.0)); vertices->push_back (osg::Vec3 ( 1.0, 0.0, 1.0)); vertices->push_back (osg::Vec3 ( 0.0, 0.0, 1.0)); vertices->push_back (osg::Vec3 (0.0, 0.0, 0.0)); geometry->setVertexArray (vertices.get()); // All vertices are white this time (it's hard to see that we have two // textures with all the colors...) osg::ref_ptr<osg::Vec4Array> colors (new osg::Vec4Array()); colors->push_back (osg::Vec4 (1.0f, 1.0f, 1.0f, 1.0f)); geometry->setColorArray (colors.get()); geometry->setColorBinding (osg::Geometry::BIND_OVERALL); osg::ref_ptr<osg::Vec3Array> normals (new osg::Vec3Array()); normals->push_back (osg::Vec3 (0.0f, -1.0f, 0.0f)); geometry->setNormalArray (normals.get()); geometry->setNormalBinding (osg::Geometry::BIND_OVERALL); osg::ref_ptr<osg::Vec2Array> texCoords (new osg::Vec2Array()); texCoords->push_back (osg::Vec2 (0.0, 0.0)); texCoords->push_back (osg::Vec2 (0.0, 1.0)); texCoords->push_back (osg::Vec2 (1.0, 1.0)); texCoords->push_back (osg::Vec2 (1.0, 0.0)); // Here, the two texture units (0 and 1) share the same texture coordinates. geometry->setTexCoordArray (0, texCoords.get()); geometry->setTexCoordArray (1, texCoords.get()); // Back to the usual: setup a primitive set and add the geometry to the geode. geometry->addPrimitiveSet( new osg::DrawArrays (osg::PrimitiveSet::QUADS, // how to render? 0, // index of first vertex vertices->size())); // how many vertices? // geode->addDrawable (geometry.get()); return geometry.get(); }
osg::ref_ptr<osg::Node> get(const PointVec_t& points, const float size) { // the color array osg::ref_ptr<osg::Vec4Array> osgColors( new osg::Vec4Array() ); osgColors->reserve(points.size()); // the vertex array osg::ref_ptr<osg::Vec3Array> verts( new osg::Vec3Array() ); verts->reserve(points.size()); // the actual cloud indices osg::ref_ptr<osg::DrawElementsUInt> theCloud( new osg::DrawElementsUInt(osg::PrimitiveSet::POINTS, 0) ); theCloud->reserveElements(points.size()); // add the points and colors - only iterate the list once so we know we have // the right number of points and colors unsigned int index(0); for ( const Point& pt : points ) { verts->push_back(pt.location); osgColors->push_back(pt.color); theCloud->push_back(index++); } // now add all this stuff to the geometry object osg::ref_ptr<osg::Geometry> cloudGeometry( new osg::Geometry() ); cloudGeometry->setVertexArray(verts); #if OSG_MIN_VERSION_REQUIRED(3,2,0) cloudGeometry->setColorArray(osgColors, osg::Array::Binding::BIND_PER_VERTEX); #else // OSG_MIN_VERSION_REQUIRED(3,2,0) cloudGeometry->setColorArray(osgColors); cloudGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); #endif // OSG_MIN_VERSION_REQUIRED(3,2,0) cloudGeometry->addPrimitiveSet(theCloud); // set the state - point size and lighting osg::ref_ptr<osg::StateSet> cloudStateSet( cloudGeometry->getOrCreateStateSet() ); cloudStateSet->setAttribute(new osg::Point(size), osg::StateAttribute::ON); cloudStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); // build the geode to return osg::ref_ptr<osg::Geode> geode(new osg::Geode()); geode->addDrawable(cloudGeometry); return geode; };
osg::ref_ptr<osg::Node> get(const CapsuleVec_t& capsules) { osg::ref_ptr<osg::Group> pAddToThisGroup(new osg::Group()); for ( const auto& cc : capsules ) { osg::Vec3d pp( cc.begin - cc.end ); double height( pp.length() ); if ( height < 0.000001 ) continue; osg::Vec3d center( (cc.begin.x() + cc.end.x())/2.0, (cc.begin.y() + cc.end.y())/2.0, (cc.begin.z() + cc.end.z())/2.0 ); // This is the default direction for the capsules to face in OpenGL static const osg::Vec3d ZZ( 0,0,1 ); // Get CROSS product (the axis of rotation) osg::Vec3d tt( ZZ^pp ); // Get angle. length is magnitude of the vector double angle( acos( (ZZ * pp) / height) ); // Create a capsule between the two points with the given radius osg::ref_ptr<osg::Capsule> capsule( new osg::Capsule(center, cc.radius, height) ); capsule->setRotation(osg::Quat(angle, osg::Vec3d(tt.x(), tt.y(), tt.z()))); // A geode to hold the capsule osg::ref_ptr<osg::ShapeDrawable> capsuleDrawable( new osg::ShapeDrawable(capsule) ); capsuleDrawable->setColor(cc.color); osg::ref_ptr<osg::Geode> geode( new osg::Geode() ); geode->addDrawable(capsuleDrawable); // Set the color of the capsule that extends between the two points. // osg::ref_ptr<osg::Material> pMaterial( new osg::Material() ); // pMaterial->setDiffuse( osg::Material::FRONT, cc.color); // geode->getOrCreateStateSet()->setAttribute( pMaterial, osg::StateAttribute::OVERRIDE ); geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON); geode->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); pAddToThisGroup->addChild(geode); } return pAddToThisGroup; }
osg::ref_ptr<osg::Node> buildTerrain() { // Create new geode to store geometry. osg::ref_ptr< osg::Geode > geode( new osg::Geode() ); osg::Vec3Array* vertices = new osg::Vec3Array; vertices->push_back( osg::Vec3( -12000.0, 0.0, -12000.0 ) ); vertices->push_back( osg::Vec3( -12000.0, 0.0, 12000.0 ) ); vertices->push_back( osg::Vec3( 12000.0, 0.0, -12000.0 ) ); vertices->push_back( osg::Vec3( 12000.0, 0.0, 12000.0 ) ); osg::Vec3Array* normals = new osg::Vec3Array; normals->push_back( osg::Vec3( 0.0, -1.0, 0.0 ) ); normals->push_back( osg::Vec3( 0.0, -1.0, 0.0 ) ); normals->push_back( osg::Vec3( 0.0, -1.0, 0.0 ) ); normals->push_back( osg::Vec3( 0.0, -1.0, 0.0 ) ); // Create new geometry node list of vertex attributes. osg::Geometry* geometry = new osg::Geometry; geometry->setVertexArray( vertices ); geometry->setNormalArray( normals ); geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX ); osg::DrawElementsUShort* drawElements = new osg::DrawElementsUShort( osg::PrimitiveSet::TRIANGLES ); drawElements->reserve( 6 ); drawElements->push_back( 0 ); drawElements->push_back( 1 ); drawElements->push_back( 2 ); drawElements->push_back( 2 ); drawElements->push_back( 3 ); drawElements->push_back( 1 ); // Add primitive set to this geometry node. geometry->addPrimitiveSet( drawElements ); geometry->setUseDisplayList( false ); geode->addDrawable( geometry ); return geode; }
ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* /*options*/) const { std::string ext( osgDB::getLowerCaseFileExtension(fileName) ); if( !acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED; osg::notify(osg::INFO) << "ReaderWriterGLOBE( \"" << fileName << "\" )" << std::endl; // strip the ".globe" pseudo-loader extension std::string tmpName( osgDB::getNameLessExtension(fileName) ); // get the next "extension", which actually contains the globe radius parameter std::string params( osgDB::getFileExtension(tmpName) ); if( params.empty() ) { osg::notify(osg::WARN) << "Missing parameters for " EXTENSION_NAME " pseudo-loader" << std::endl; return ReadResult::FILE_NOT_HANDLED; } // strip the "params extension", which must leave an image subfilename. std::string subFileName( osgDB::getNameLessExtension(tmpName) ); if( subFileName.empty() || subFileName == tmpName ) { osg::notify(osg::WARN) << "Missing image subfilename for " EXTENSION_NAME " pseudo-loader" << std::endl; return ReadResult::FILE_NOT_HANDLED; } osg::notify(osg::INFO) << EXTENSION_NAME " params = \"" << params << "\"" << std::endl; int radius; int count( sscanf( params.c_str(), "%d", &radius ) ); if( count != 1 ) { osg::notify(osg::WARN) << "Bad parameters for " EXTENSION_NAME " pseudo-loader: \"" << params << "\"" << std::endl; return ReadResult::FILE_NOT_HANDLED; } // recursively load the image subfile. osg::Image *image( osgDB::readImageFile(subFileName) ); if( !image ) { // propagate the read failure upwards osg::notify(osg::WARN) << "Image file \"" << subFileName << "\" could not be loaded" << std::endl; return ReadResult::FILE_NOT_HANDLED; } // create an osg::Sphere for the globe geometry osg::Geode* geode( new osg::Geode() ); geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0,0,0), radius))); // apply the image as a texture to the globe osg::Texture2D* tex2d( new osg::Texture2D ); tex2d->setImage( image ); tex2d->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT ); tex2d->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT ); osg::StateSet* stateset( geode->getOrCreateStateSet() ); stateset->setTextureAttributeAndModes( 0, tex2d, osg::StateAttribute::ON ); return geode; }
osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chunkSize, const osg::Vec2f& chunkCenter) { if (chunkSize * mNumSplits > 1.f) { // keep splitting osg::ref_ptr<osg::Group> group (new osg::Group); if (parent) parent->addChild(group); float newChunkSize = chunkSize/2.f; buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, -newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, -newChunkSize/2.f)); return group; } else { float minH, maxH; if (!mStorage->getMinMaxHeights(chunkSize, chunkCenter, minH, maxH)) return NULL; // no terrain defined osg::Vec2f worldCenter = chunkCenter*mStorage->getCellWorldSize(); osg::ref_ptr<SceneUtil::PositionAttitudeTransform> transform (new SceneUtil::PositionAttitudeTransform); transform->setPosition(osg::Vec3f(worldCenter.x(), worldCenter.y(), 0.f)); if (parent) parent->addChild(transform); osg::ref_ptr<osg::Vec3Array> positions (new osg::Vec3Array); osg::ref_ptr<osg::Vec3Array> normals (new osg::Vec3Array); osg::ref_ptr<osg::Vec4Array> colors (new osg::Vec4Array); osg::ref_ptr<osg::VertexBufferObject> vbo (new osg::VertexBufferObject); positions->setVertexBufferObject(vbo); normals->setVertexBufferObject(vbo); colors->setVertexBufferObject(vbo); mStorage->fillVertexBuffers(0, chunkSize, chunkCenter, positions, normals, colors); osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry); geometry->setVertexArray(positions); geometry->setNormalArray(normals, osg::Array::BIND_PER_VERTEX); geometry->setColorArray(colors, osg::Array::BIND_PER_VERTEX); geometry->setUseDisplayList(false); geometry->setUseVertexBufferObjects(true); geometry->addPrimitiveSet(mCache.getIndexBuffer(0)); // we already know the bounding box, so no need to let OSG compute it. osg::Vec3f min(-0.5f*mStorage->getCellWorldSize()*chunkSize, -0.5f*mStorage->getCellWorldSize()*chunkSize, minH); osg::Vec3f max (0.5f*mStorage->getCellWorldSize()*chunkSize, 0.5f*mStorage->getCellWorldSize()*chunkSize, maxH); osg::BoundingBox bounds(min, max); geometry->setComputeBoundingBoxCallback(new StaticBoundingBoxCallback(bounds)); std::vector<LayerInfo> layerList; std::vector<osg::ref_ptr<osg::Image> > blendmaps; mStorage->getBlendmaps(chunkSize, chunkCenter, false, blendmaps, layerList); // For compiling textures, I don't think the osgFX::Effect does it correctly osg::ref_ptr<osg::Node> textureCompileDummy (new osg::Node); std::vector<osg::ref_ptr<osg::Texture2D> > layerTextures; for (std::vector<LayerInfo>::const_iterator it = layerList.begin(); it != layerList.end(); ++it) { layerTextures.push_back(mResourceSystem->getTextureManager()->getTexture2D(it->mDiffuseMap, osg::Texture::REPEAT, osg::Texture::REPEAT)); textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(0, layerTextures.back()); } std::vector<osg::ref_ptr<osg::Texture2D> > blendmapTextures; for (std::vector<osg::ref_ptr<osg::Image> >::const_iterator it = blendmaps.begin(); it != blendmaps.end(); ++it) { osg::ref_ptr<osg::Texture2D> texture (new osg::Texture2D); texture->setImage(*it); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); texture->setResizeNonPowerOfTwoHint(false); blendmapTextures.push_back(texture); textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(0, layerTextures.back()); } // use texture coordinates for both texture units, the layer texture and blend texture for (unsigned int i=0; i<2; ++i) geometry->setTexCoordArray(i, mCache.getUVBuffer()); float blendmapScale = ESM::Land::LAND_TEXTURE_SIZE*chunkSize; osg::ref_ptr<osgFX::Effect> effect (new Terrain::Effect(layerTextures, blendmapTextures, blendmapScale, blendmapScale)); effect->addCullCallback(new SceneUtil::LightListCallback); transform->addChild(effect); #if OSG_VERSION_GREATER_OR_EQUAL(3,3,3) osg::Node* toAttach = geometry.get(); #else osg::ref_ptr<osg::Geode> geode (new osg::Geode); geode->addDrawable(geometry); osg::Node* toAttach = geode.get(); #endif effect->addChild(toAttach); if (mIncrementalCompileOperation) { mIncrementalCompileOperation->add(toAttach); mIncrementalCompileOperation->add(textureCompileDummy); } return transform; } }
osg::ref_ptr<osg::Node> MeshManager::get(size_t idx) { /* Not sure if this cache is a good idea since it shares the whole model * tree. OSG can parent the same sub-tree to multiple points, which should * be okay as long as the individual sub-trees don't need changing. */ auto iter = mModelCache.find(idx); if(iter != mModelCache.end()) { osg::ref_ptr<osg::Node> node; if(iter->second.lock(node)) return node; } if(!mModelProgram) { mModelProgram = new osg::Program(); mModelProgram->addShader(osgDB::readShaderFile(osg::Shader::VERTEX, "shaders/object.vert")); mModelProgram->addShader(osgDB::readShaderFile(osg::Shader::FRAGMENT, "shaders/object.frag")); } DFOSG::Mesh *mesh = DFOSG::MeshLoader::get().load(idx); osg::ref_ptr<osg::Geode> geode(new osg::Geode()); for(auto iter = mesh->getPlanes().begin();iter != mesh->getPlanes().end();) { osg::ref_ptr<osg::Vec3Array> vtxs(new osg::Vec3Array()); osg::ref_ptr<osg::Vec3Array> nrms(new osg::Vec3Array()); osg::ref_ptr<osg::Vec3Array> binrms(new osg::Vec3Array()); osg::ref_ptr<osg::Vec2Array> texcrds(new osg::Vec2Array()); osg::ref_ptr<osg::Vec4ubArray> colors(new osg::Vec4ubArray()); osg::ref_ptr<osg::DrawElementsUShort> idxs(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES)); uint16_t texid = iter->getTextureId(); osg::ref_ptr<osg::Texture> tex = TextureManager::get().getTexture(texid); float width = tex->getTextureWidth(); float height = tex->getTextureHeight(); do { const std::vector<DFOSG::MdlPlanePoint> &pts = iter->getPoints(); size_t last_total = vtxs->size(); vtxs->resize(last_total + pts.size()); nrms->resize(last_total + pts.size()); binrms->resize(last_total + pts.size()); texcrds->resize(last_total + pts.size()); colors->resize(last_total + pts.size()); idxs->resize((last_total + pts.size() - 2) * 3); size_t j = last_total; for(const DFOSG::MdlPlanePoint &pt : pts) { uint32_t vidx = pt.getIndex(); (*vtxs)[j].x() = mesh->getPoints()[vidx].x() / 256.0f; (*vtxs)[j].y() = mesh->getPoints()[vidx].y() / 256.0f; (*vtxs)[j].z() = mesh->getPoints()[vidx].z() / 256.0f; (*nrms)[j].x() = iter->getNormal().x() / 256.0f; (*nrms)[j].y() = iter->getNormal().y() / 256.0f; (*nrms)[j].z() = iter->getNormal().z() / 256.0f; (*binrms)[j].x() = iter->getBinormal().x() / 256.0f; (*binrms)[j].y() = iter->getBinormal().y() / 256.0f; (*binrms)[j].z() = iter->getBinormal().z() / 256.0f; (*texcrds)[j].x() = pt.u() / width; (*texcrds)[j].y() = pt.v() / height; (*colors)[j] = osg::Vec4ub(255, 255, 255, 255); if(j >= last_total+2) { (*idxs)[(j-2)*3 + 0] = last_total; (*idxs)[(j-2)*3 + 1] = j-1; (*idxs)[(j-2)*3 + 2] = j; } ++j; } } while(++iter != mesh->getPlanes().end() && iter->getTextureId() == texid); osg::ref_ptr<osg::VertexBufferObject> vbo(new osg::VertexBufferObject()); vtxs->setVertexBufferObject(vbo); nrms->setVertexBufferObject(vbo); texcrds->setVertexBufferObject(vbo); colors->setVertexBufferObject(vbo); colors->setNormalize(true); osg::ref_ptr<osg::ElementBufferObject> ebo(new osg::ElementBufferObject()); idxs->setElementBufferObject(ebo); osg::ref_ptr<osg::Geometry> geometry(new osg::Geometry); geometry->setVertexArray(vtxs); geometry->setNormalArray(nrms, osg::Array::BIND_PER_VERTEX); geometry->setTexCoordArray(1, binrms, osg::Array::BIND_PER_VERTEX); geometry->setTexCoordArray(0, texcrds, osg::Array::BIND_PER_VERTEX); geometry->setColorArray(colors, osg::Array::BIND_PER_VERTEX); geometry->setUseDisplayList(false); geometry->setUseVertexBufferObjects(true); geometry->addPrimitiveSet(idxs); /* Cache the stateset used for this texture, so it can be reused for * multiple models (should help OSG batch together objects with similar * state). */ auto &stateiter = mStateSetCache[texid]; osg::ref_ptr<osg::StateSet> ss; if(stateiter.lock(ss) && ss) geometry->setStateSet(ss); else { ss = geometry->getOrCreateStateSet(); ss->setAttributeAndModes(mModelProgram); ss->addUniform(new osg::Uniform("diffuseTex", 0)); ss->setTextureAttribute(0, tex); stateiter = ss; } geode->addDrawable(geometry); } mModelCache[idx] = osg::ref_ptr<osg::Node>(geode); return geode; }
osg::ref_ptr<osg::Node> CSVRender::Object::makeMoveOrScaleMarker (int axis) { osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry); float shaftLength = MarkerShaftBaseLength + mBaseNode->getBound().radius(); // shaft osg::Vec3Array *vertices = new osg::Vec3Array; for (int i=0; i<2; ++i) { float length = i ? shaftLength : MarkerShaftWidth; vertices->push_back (getMarkerPosition (-MarkerShaftWidth/2, -MarkerShaftWidth/2, length, axis)); vertices->push_back (getMarkerPosition (-MarkerShaftWidth/2, MarkerShaftWidth/2, length, axis)); vertices->push_back (getMarkerPosition (MarkerShaftWidth/2, MarkerShaftWidth/2, length, axis)); vertices->push_back (getMarkerPosition (MarkerShaftWidth/2, -MarkerShaftWidth/2, length, axis)); } // head backside vertices->push_back (getMarkerPosition (-MarkerHeadWidth/2, -MarkerHeadWidth/2, shaftLength, axis)); vertices->push_back (getMarkerPosition (-MarkerHeadWidth/2, MarkerHeadWidth/2, shaftLength, axis)); vertices->push_back (getMarkerPosition (MarkerHeadWidth/2, MarkerHeadWidth/2, shaftLength, axis)); vertices->push_back (getMarkerPosition (MarkerHeadWidth/2, -MarkerHeadWidth/2, shaftLength, axis)); // head vertices->push_back (getMarkerPosition (0, 0, shaftLength+MarkerHeadLength, axis)); geometry->setVertexArray (vertices); osg::DrawElementsUShort *primitives = new osg::DrawElementsUShort (osg::PrimitiveSet::TRIANGLES, 0); // shaft for (int i=0; i<4; ++i) { int i2 = i==3 ? 0 : i+1; primitives->push_back (i); primitives->push_back (4+i); primitives->push_back (i2); primitives->push_back (4+i); primitives->push_back (4+i2); primitives->push_back (i2); } // cap primitives->push_back (0); primitives->push_back (1); primitives->push_back (2); primitives->push_back (2); primitives->push_back (3); primitives->push_back (0); // head, backside primitives->push_back (0+8); primitives->push_back (1+8); primitives->push_back (2+8); primitives->push_back (2+8); primitives->push_back (3+8); primitives->push_back (0+8); for (int i=0; i<4; ++i) { primitives->push_back (12); primitives->push_back (8+(i==3 ? 0 : i+1)); primitives->push_back (8+i); } geometry->addPrimitiveSet (primitives); osg::Vec4Array *colours = new osg::Vec4Array; for (int i=0; i<8; ++i) colours->push_back (osg::Vec4f (axis==0 ? 1.0f : 0.2f, axis==1 ? 1.0f : 0.2f, axis==2 ? 1.0f : 0.2f, mMarkerTransparency)); for (int i=8; i<8+4+1; ++i) colours->push_back (osg::Vec4f (axis==0 ? 1.0f : 0.0f, axis==1 ? 1.0f : 0.0f, axis==2 ? 1.0f : 0.0f, mMarkerTransparency)); geometry->setColorArray (colours, osg::Array::BIND_PER_VERTEX); setupCommonMarkerState(geometry); osg::ref_ptr<osg::Geode> geode (new osg::Geode); geode->addDrawable (geometry); return geode; }
osg::ref_ptr<osg::Node> get(const ImageVec_t& images) { osg::ref_ptr<osg::Group> rv( new osg::Group() ); for ( const auto& image : images ) { // here we create a quad that will be texture mapped with the image osg::ref_ptr<osg::Vec3Array> quad( new osg::Vec3Array() ); quad->push_back( image.corners[0] ); quad->push_back( image.corners[1] ); quad->push_back( image.corners[2] ); quad->push_back( image.corners[3] ); osg::ref_ptr<osg::Geometry> geo( new osg::Geometry() ); geo->setVertexArray( quad ); // here we create a drawing elelment to draw on osg::ref_ptr<osg::DrawElementsUInt> primitiveSet( new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0) ); primitiveSet->push_back( 0 ); primitiveSet->push_back( 1 ); primitiveSet->push_back( 2 ); primitiveSet->push_back( 3 ); geo->addPrimitiveSet( primitiveSet ); // the texture mappings osg::ref_ptr<osg::Vec2Array> texCoords( new osg::Vec2Array(4) ); (*texCoords)[3].set( 0.0f, 0.0f ); (*texCoords)[2].set( 1.0f, 0.0f ); (*texCoords)[1].set( 1.0f, 1.0f ); (*texCoords)[0].set( 0.0f, 1.0f ); geo->setTexCoordArray( 0, texCoords ); // now create the goede to hold our created geometry osg::ref_ptr<osg::Geode> geode( new osg::Geode() ); geode->addDrawable( geo ); // create the texture for the image osg::ref_ptr<osg::Texture2D> texture( new osg::Texture2D() ); texture->setResizeNonPowerOfTwoHint(false); texture->setDataVariance(osg::Object::STATIC); texture->setImage( image.image ); texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST); texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST); // put this in decal mode osg::ref_ptr<osg::TexEnv> decalTexEnv( new osg::TexEnv() ); decalTexEnv->setMode(osg::TexEnv::DECAL); // set the state set, lighting and such, so we actually display the image osg::ref_ptr<osg::StateSet> stateSet( geode->getOrCreateStateSet() ); stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); stateSet->setTextureAttribute(0, decalTexEnv); stateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); geo->setStateSet(stateSet); // turn off any color binding - we want to use the texture geo->setColorBinding(osg::Geometry::BIND_OFF); // add this image and continue rv->addChild(geode); } return rv; };
osg::Node* postRender( osgViewer::Viewer& viewer ) { osg::Camera* rootCamera( viewer.getCamera() ); // MRT: Attach two color buffers to the root camera, one for // the standard color image, and another for the glow color. osg::Texture2D* tex0 = new osg::Texture2D; tex0->setTextureWidth( winW ); tex0->setTextureHeight( winH ); tex0->setInternalFormat( GL_RGBA ); tex0->setBorderWidth( 0 ); tex0->setFilter( osg::Texture::MIN_FILTER, osg::Texture::NEAREST ); tex0->setFilter( osg::Texture::MAG_FILTER, osg::Texture::NEAREST ); // Full color: attachment 0 rootCamera->attach( osg::Camera::COLOR_BUFFER0, tex0, 0, 0, false, 8, 8 ); osg::Texture2D* tex1 = new osg::Texture2D; tex1->setTextureWidth( winW ); tex1->setTextureHeight( winH ); tex1->setInternalFormat( GL_RGBA ); tex1->setBorderWidth( 0 ); tex1->setFilter( osg::Texture::MIN_FILTER, osg::Texture::NEAREST ); tex1->setFilter( osg::Texture::MAG_FILTER, osg::Texture::NEAREST ); // Glow color: attachment 1 rootCamera->attach( osg::Camera::COLOR_BUFFER1, tex1, 0, 0, false, 8, 8 ); rootCamera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT, osg::Camera::FRAME_BUFFER ); #if( OSGWORKS_OSG_VERSION >= 20906 ) rootCamera->setImplicitBufferAttachmentMask( osg::Camera::IMPLICIT_COLOR_BUFFER_ATTACHMENT|osg::Camera::IMPLICIT_DEPTH_BUFFER_ATTACHMENT, osg::Camera::IMPLICIT_COLOR_BUFFER_ATTACHMENT ); #endif // Post-draw callback on root camera handles resolving // multisampling for the MRT case. MSMRTCallback* msmrt = new MSMRTCallback( rootCamera ); rootCamera->setPostDrawCallback( msmrt ); // Configure postRenderCamera to draw fullscreen textured tri pair. // This will combine the two (resolved) textures into a single image. osg::ref_ptr< osg::Camera > postRenderCamera( new osg::Camera ); postRenderCamera->setClearColor( osg::Vec4( 0., 1., 0., 1. ) ); // should never see this. postRenderCamera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER, osg::Camera::FRAME_BUFFER ); postRenderCamera->setReferenceFrame( osg::Camera::ABSOLUTE_RF ); postRenderCamera->setRenderOrder( osg::Camera::POST_RENDER ); postRenderCamera->setViewMatrix( osg::Matrixd::identity() ); postRenderCamera->setProjectionMatrix( osg::Matrixd::identity() ); osg::Geode* geode( new osg::Geode ); geode->setCullingActive( false ); geode->addDrawable( osg::createTexturedQuadGeometry( osg::Vec3( -1,-1,0 ), osg::Vec3( 2,0,0 ), osg::Vec3( 0,2,0 ) ) ); mrtStateSetTriPair( geode->getOrCreateStateSet(), tex0, tex1 ); postRenderCamera->addChild( geode ); return( postRenderCamera.release() ); }