Hi all, I am trying to show instanced geometry using a texture1D like a vertex buffer. In fact I have it working more or less... but if my Texture 1D is non power of two then my shader does not render some of the instances. Attached is the code and two images, one with a non power of two texture(9 elements) that fails to draw last element, and other with 256 elements that is drawn correctly.
I am using TransferFunction1D to pass my geometry array to a texture1D. Anybody knows what I'm doing wrong? Of course I have set texture->setResizeNonPowerOfTwoHint(false); Thank you in advance! Jordi. -- Jordi Torres Fabra gvSIG 3D blog http://gvsig3d.blogspot.com Instituto de Automática e Informática Industrial http://www.ai2.upv.es
<<attachment: 9instances.png>>
<<attachment: 256instances.png>>
#include <osg/Texture1D>
#include <osg/TransferFunction>
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/Uniform>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/StateSetManipulator>
#include <osgGA/TrackballManipulator>
#include <osg/ShapeDrawable>
#include <iostream>
osg::Texture1D* geometryArrayToTexture(osg::Vec3dArray* geometryArray)
{
osg::Texture1D* texture= new osg::Texture1D();
osg::Image* im= new osg::Image();
int size = geometryArray->size();
osg::TransferFunction1D::ColorMap geometryMap;
int value =0;
for (osg::Vec3dArray::iterator it= geometryArray->begin(); it!= geometryArray->end();++it)
{
geometryMap[(float)value/(float)geometryArray->size()] = osg::Vec4((float)it->x(),(float)it->y(),(float)it->z(),0.);
++value;
}
if (geometryMap.empty())
{
std::cout<<"Error: No values read from geometry: "<<std::endl;
return 0;
}
osg::TransferFunction1D* transferFunction = new osg::TransferFunction1D;
transferFunction->allocate(geometryArray->size());
transferFunction->assign(geometryMap);
texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::NEAREST);
texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::NEAREST);
texture->setResizeNonPowerOfTwoHint(false);
im = transferFunction->getImage();
im->setInternalTextureFormat(GL_RGBA32F_ARB);
im->setPixelFormat(GL_RGBA);
im->setDataType(GL_FLOAT);
texture->setImage(im);
return texture;
}
int main (int argc, char *argv[])
{
const float halfDimX( .5 );
const float halfDimZ( .5 );
osg::Geometry *geom = new osg::Geometry();
osg::Geometry *auxgeom = new osg::Geometry();
osg::Vec3Array* instaceArray = new osg::Vec3Array;
osg::Geode* g= new osg::Geode();
//Create a geometry for use as instance
//** Borrowed from osgdrawinstaced example**
instaceArray->resize( 4 );
geom->setVertexArray( instaceArray );
geom->setUseDisplayList( false );
geom->setUseVertexBufferObjects( true );
// Geometry for a single quad.
(*instaceArray)[ 0 ] = osg::Vec3( -halfDimX, 0., -halfDimZ );
(*instaceArray)[ 1 ] = osg::Vec3( halfDimX, 0., -halfDimZ );
(*instaceArray)[ 2 ] = osg::Vec3( halfDimX, 0., halfDimZ );
(*instaceArray)[ 3 ] = osg::Vec3( -halfDimX, 0., halfDimZ );
//SET number of instances
float ninstances=9;
// Use the DrawArraysInstanced PrimitiveSet and tell it to draw ninstances.
geom->addPrimitiveSet( new osg::DrawArrays( GL_QUADS, 0, 4, ninstances ) );
osg::BoundingBox bb( -1, -1, -1, 10., 10., 10. );
geom->setInitialBound( bb );
osg::Vec3dArray* geometryArray = new osg::Vec3dArray;
// Fill geometry array
for(int i=0;i<ninstances/sqrt(ninstances);++i)
for(int j =0 ;j<ninstances/sqrt(ninstances);++j)
geometryArray->push_back( osg::Vec3( i*2., 0., j*2.));
//Uniform stuff
osg::ref_ptr<osg::Texture1D> tex = geometryArrayToTexture(geometryArray);
osg::ref_ptr<osg::StateSet>ss= g->getOrCreateStateSet();
ss->setTextureAttribute(0, tex);
osg::Uniform* guniform= new osg::Uniform("texturePos", tex );
guniform->set(0);
ss->addUniform(guniform);
ss->addUniform( new osg::Uniform( "color", osg::Vec4(1.,1.,0.,0.) ));
ss->addUniform( new osg::Uniform( "nInstances", ninstances));
//shader
std::string vertexSource =
"#extension GL_EXT_gpu_shader4 : enable\n"
"uniform sampler1D texturePos;\n"
"uniform float nInstances;\n"
"void main() \n"
"{ \n"
"vec4 pos= gl_Vertex+ vec4(texture1D(texturePos,(float(gl_InstanceID)/nInstances)).xyz,0.);\n"
"gl_Position= gl_ModelViewProjectionMatrix*pos;\n"
"} \n";
std::string fragSource =
"uniform vec4 color;\n"
"void main() \n"
"{ \n"
"gl_FragColor = color; \n"
"} \n";
//shader activation stuff
osg::ref_ptr< osg::Shader > vertexShader = new osg::Shader();
vertexShader->setType( osg::Shader::VERTEX );
vertexShader->setShaderSource( vertexSource );
osg::ref_ptr< osg::Shader > fragmentShader = new osg::Shader();
fragmentShader->setType( osg::Shader::FRAGMENT);
fragmentShader->setShaderSource( fragSource );
osg::ref_ptr< osg::Program > program = new osg::Program();
program->addShader( vertexShader.get() );
program->addShader( fragmentShader.get() );
ss->setAttribute( program.get(),osg::StateAttribute::ON );
geom->setStateSet(ss);
osg::Group* root= new osg::Group();
root->addChild(g);
g->addDrawable(geom);
osgViewer::Viewer* viewer= new osgViewer::Viewer();
viewer->setSceneData( root );
viewer->addEventHandler(new osgViewer::StatsHandler());
viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));
viewer->addEventHandler(new osgViewer::WindowSizeHandler());
return viewer->run();
}
_______________________________________________ osg-users mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

