[osg-users] [StateSet] Handle .png as a texture

Stephane Mas stephane.mas at gmail.com
Wed Dec 9 08:47:39 PST 2015


Hi,

I experience problems to display a .png image as an osg::Geode.

The thing is that it was perfectly working when I was using version 3.2.0 of osg library, but now that I use version 3.2.1, it no more works. 

Here are samples from my code (sorry for bad indentation) :

I first load the image :

Code:

osg::Image * image;
image = osgDB::readImageFile(pathToTheImage);




I create a osg::Geometry :


Code:


// Retrieve image dimension
_imageWidth = image->s();
_imageHeight = image->t();

// Build the plane geometry
osg::Geometry* planeGeometry = new osg::Geometry();

//---------------------------------------
// Compute vertices to keep the image ratio.
// Max dimension (width or height) will be considered 1 unit long
//---------------------------------------
double vertexLeft;
double vertexBottom;
double vertexRight;
double vertexTop;

// Center on the image
if( _imageWidth > _imageHeight ){
vertexLeft = - 0.5 * (_imageHeight / _imageWidth);
vertexBottom = - 0.5;
vertexRight = + 0.5 * (_imageHeight / _imageWidth);
vertexTop = + 0.5;
}
else{
vertexLeft = - 0.5;
vertexBottom = - 0.5 * (_imageWidth / _imageHeight);
vertexRight = + 0.5;
vertexTop = + 0.5 * (_imageWidth / _imageHeight);
}

int verticesScale = 1; // We could specify a scale there, but it would be harder to change it in a second time in another function call ...
osg::Vec3Array * vertices = new osg::Vec3Array;
vertices->push_back(osg::Vec3(verticesScale*vertexLeft, verticesScale*vertexBottom, 0));
vertices->push_back(osg::Vec3(verticesScale*vertexRight, verticesScale*vertexBottom, 0));
vertices->push_back(osg::Vec3(verticesScale*vertexRight, verticesScale*vertexTop, 0));
vertices->push_back(osg::Vec3(verticesScale*vertexLeft, verticesScale*vertexTop, 0));

osg::DrawElementsUInt * indices = new osg::DrawElementsUInt(osg::PrimitiveSet::POLYGON, 0);
indices->push_back(0);
indices->push_back(1);
indices->push_back(2);
indices->push_back(3);

osg::Vec4Array * colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); // no transparency

osg::Vec2Array * textureCoords = new osg::Vec2Array(4);
(*textureCoords)[0].set(0.0f, 0.0f);
(*textureCoords)[1].set(1.0f, 0.0f);
(*textureCoords)[2].set(1.0f, 1.0f);
(*textureCoords)[3].set(0.0f, 1.0f);

planeGeometry->setTexCoordArray(0, textureCoords);

osg::Vec3Array * normals = new osg::Vec3Array;
normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
planeGeometry->setNormalArray(normals);

planeGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
planeGeometry->addPrimitiveSet(indices);
planeGeometry->setVertexArray(vertices);
planeGeometry->setColorArray(colors);

planeGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);



I fill a geode with the built geometry


Code:

osg::Geode * texturedPlaneGeode = new osg::Geode();
texturedPlaneGeode->addDrawable(planeGeometry);



	
Then I handle the state set of the geode :	

Code:

texturedPlaneGeode->setStateSet(createTextureStateFromSingleImage(image));




Here is how I handle the state set from a given osgImage :


Code:

osg::StateSet * createTextureStateFromSingleImage(osg::Image * singleImage)
{
// create the StateSet to store the texture data
osg::StateSet* texturedPlaneStateSet = new osg::StateSet;

// Build the texture
osg::Texture2D * texture = new osg::Texture2D;
texture->setDataVariance(osg::Object::DYNAMIC);
texture->setImage(singleImage);

// Update StateSet to use the texture
texturedPlaneStateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);

// Turn blending on (so alpha texture looks right)
texturedPlaneStateSet->setMode(GL_BLEND, osg::StateAttribute::ON);

// Turn lighting off (to keep exact - inside image - colors when rendering)
texturedPlaneStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

// Disable depth testing so geometry is drawn regardless of depth values
// of geometry already draw.
texturedPlaneStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);

texturedPlaneStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);

// Need to make sure this geometry is draw last. RenderBins are handled
// in numerical order so set bin number to 11
texturedPlaneStateSet->setRenderBinDetails(11, "RenderBin");


return texturedPlaneStateSet;
}




The result is a plane with correct dimensions, but with only grey content.
Do you have any idea on what I do wrong ?

Thank you in advance for any help !
Stephane

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=65831#65831







More information about the osg-users mailing list