Hi, Robert.
I've managed to render to 3D texture and I wrote a simple demo to show how to use it. Everyone with Nvidia Geforce 8800 Series can run this program. But I found it has very slow performance. In this example, with 256*256*256 3D texture, only 8 fps was show on my 8800GTS 320M. I see the StatsHandler's value here:
FPS 8.56
Cull 38.24
Draw 70.70
GPU 82.50
It wastes a lot of time do Culling and Drawing. Is there any way to reduce the cull time and draw time? Thanks!
#include <osg/Node>
#include <osg/Geometry>
#include <osg/Drawable>
#include <osg/ShapeDrawable>
#include <osgGA/TrackballManipulator>
#include <osgViewer/Viewer>
#include <osg/Texture3D>
#include <osgViewer/ViewerEventHandlers>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgViewer/ViewerEventHandlers>
#include <osgUtil/Optimizer>
#include <osg/MatrixTransform>

using namespace osg;
using namespace osgViewer;

int _tmain(int argc, _TCHAR* argv[])
{
        ref_ptr<Group> root= new Group;
        
        ref_ptr<Image> img=new Image;
        img->allocateImage(256,256,256, GL_RGBA, GL_UNSIGNED_BYTE);

        ref_ptr<Texture3D> txt3D=new Texture3D;
        txt3D->setFilter(Texture3D::MIN_FILTER, Texture3D::LINEAR);
        txt3D->setFilter(Texture3D::MAG_FILTER, Texture3D::LINEAR);
        txt3D->setImage(img.get());
        txt3D->setTextureSize(256,256,256);
        txt3D->setInternalFormat(GL_RGBA);
        const unsigned char TEXTURE_3D=0;

        for(int z=0;z<256;z++)
        {
                ref_ptr<Camera> camera=new Camera;
                camera->setClearColor(Vec4(0,0,0,0));
                camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                camera->setReferenceFrame(Transform::ABSOLUTE_RF);
                camera->setRenderOrder(osg::Camera::PRE_RENDER);
                
camera->setRenderTargetImplementation(Camera::FRAME_BUFFER_OBJECT);
                camera->attach(Camera::COLOR_BUFFER, txt3D.get(), 0, z, false);
                camera->setViewport(0,0, 256,256);
        
                ref_ptr<Geode> box=new Geode();
                box->addDrawable(new ShapeDrawable(new 
Sphere(Vec3(1/256.0*z,0,0), 1)));

                camera->addChild(box.get());
                root->addChild(camera.get());
        }
        
        ref_ptr<Geode> geode=new Geode;
        ref_ptr<Geometry> geo=new Geometry;
        geode->addDrawable(geo.get());
        ref_ptr<Vec3Array> vertex=new Vec3Array;
        ref_ptr<Vec3Array> txtcoord=new Vec3Array;
        for(int z=0;z<256;z++)
        {
                vertex->push_back(Vec3(0,0,z/256.0));
                vertex->push_back(Vec3(1,0,z/256.0));
                vertex->push_back(Vec3(1,1,z/256.0));
                vertex->push_back(Vec3(0,1,z/256.0));

                txtcoord->push_back(Vec3(0,0,z/256.0));
                txtcoord->push_back(Vec3(1,0,z/256.0));
                txtcoord->push_back(Vec3(1,1,z/256.0));
                txtcoord->push_back(Vec3(0,1,z/256.0));
        }
        
        geo->setVertexArray(vertex.get());      
        geo->setTexCoordArray(TEXTURE_3D, txtcoord.get());

        geo->addPrimitiveSet(new 
osg::DrawArrays(osg::PrimitiveSet::QUADS,0,vertex->size()));
        geo->getOrCreateStateSet()->setTextureAttributeAndModes(TEXTURE_3D, 
txt3D.get(),osg::StateAttribute::ON);

        root->addChild(geode.get());
        
root->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF | 
osg::StateAttribute::OVERRIDE);

        osgUtil::Optimizer optimzer;
        optimzer.optimize(root.get());

        ref_ptr<Viewer> viewer=new Viewer;

        osg::ref_ptr<osg::GraphicsContext::Traits> traits = new 
osg::GraphicsContext::Traits;
        traits->x = 100;
        traits->y = 100;
        traits->width = 1024;
        traits->height = 768;
        traits->windowDecoration = true;
        traits->doubleBuffer = true;
        traits->sharedContext = 0;
        ref_ptr<GraphicsContext> gc = 
osg::GraphicsContext::createGraphicsContext(traits.get());
        viewer->getCamera()->setGraphicsContext(gc.get());
        viewer->getCamera()->setViewport(0,0, 1024,768);
        viewer->setSceneData(root.get());
        viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
        viewer->addEventHandler(new osgViewer::StatsHandler);
        viewer->run();
}

_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to