Hi,
I've met a very strange problem when I tried to set mipmaps in a osg::Image
object.
If I use the sample code in osgParticle/PrecipitationEffect.cpp, I can get
correct mipmap texture, however, if I try to read texture data from files to
set mipmap texture, it didn't work. I'll be mad, somebody met this problem
before? help~~
p.s.
sample code(texturemipmaps.cpp) : change from
osgParticle/PrecipitationEffect.cpp and work well
my code(Mymipmap.cpp): could not work appropriately, with no texture on
that plane..
#include osg/MatrixTransform
#include osg/PositionAttitudeTransform
#include osg/Texture2D
#include osg/Geometry
#include osg/Geode
#include osgDB/Registry
#include osgDB/ReadFile
#include osgViewer/Viewer
osg::ref_ptrosg::Geometry createPlane( float length, float width )
{
osg::ref_ptrosg::Vec3Array vec = new osg::Vec3Array;
vec-resize( 8 );
(*vec)[0] = osg::Vec3f( -2, 0, -2 );
(*vec)[1] = osg::Vec3f( -2, 0, 2 );
(*vec)[2] = osg::Vec3f( 2, 0, 2 );
(*vec)[3] = osg::Vec3f( 2, 0, -2 );
osg::ref_ptrosg::Vec3Array nor = new osg::Vec3Array;
nor-push_back( osg::Vec3f( 0.0, -1.0, 0.0 ) );
osg::ref_ptrosg::Vec2Array tex = new osg::Vec2Array;
tex-push_back( osg::Vec2f(0.0, 0.0) );
tex-push_back( osg::Vec2f(0.0, 1.0) );
tex-push_back( osg::Vec2f(1.0, 1.0) );
tex-push_back( osg::Vec2f(1.0, 0.0) );
osg::ref_ptrosg::Geometry geo = new osg::Geometry;
geo-setVertexArray( vec.get() );
geo-setTexCoordArray( 0, tex.get() );
geo-setNormalArray( nor.get() );
geo-setNormalBinding( osg::Geometry::BIND_PER_PRIMITIVE_SET );
geo-addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0,
4 ) );
return geo;
}
static void fillSpotLightImage(unsigned char* ptr, const osg::Vec4
centerColour, const osg::Vec4 backgroudColour, unsigned int size, float power)
{
if (size==1)
{
float r = 0.5f;
osg::Vec4 color = centerColour*r+backgroudColour*(1.0f-r);
*ptr++ = (unsigned char)((color[0])*255.0f);
*ptr++ = (unsigned char)((color[1])*255.0f);
*ptr++ = (unsigned char)((color[2])*255.0f);
*ptr++ = (unsigned char)((color[3])*255.0f);
return;
}
float mid = (float(size)-1.0f)*0.5f;
float div = 2.0f/float(size);
for(unsigned int r=0;rsize;++r)
{
//unsigned char* ptr = image-data(0,r,0);
for(unsigned int c=0;csize;++c)
{
float dx = (float(c) - mid)*div;
float dy = (float(r) - mid)*div;
float r = powf(1.0f-sqrtf(dx*dx+dy*dy),power);
if (r0.0f) r=0.0f;
osg::Vec4 color =
centerColour*r+backgroudColour*(1.0f-r);
*ptr++ = (unsigned char)((color[0])*255.0f);
*ptr++ = (unsigned char)((color[1])*255.0f);
*ptr++ = (unsigned char)((color[2])*255.0f);
*ptr++ = (unsigned char)((color[3])*255.0f);
}
}
}
int main(int, char **)
{
osgViewer::Viewer viewer;
osg::ref_ptrosg::Group root = new osg::Group;
osg::ref_ptrosg::PositionAttitudeTransform mypat1 = new
osg::PositionAttitudeTransform;
osg::ref_ptrosg::PositionAttitudeTransform mypat2 = new
osg::PositionAttitudeTransform;
osg::ref_ptrosg::Geode mygeode1 = new osg::Geode;
osg::ref_ptrosg::Geode mygeode2 = new osg::Geode;
osg::StateSet* mystate0 = root-getOrCreateStateSet();
osg::StateSet* mystate1 = mypat1-getOrCreateStateSet();
osg::Image* image = new osg::Image;
osg::Image::MipmapDataType mipmapData;
unsigned int s = 32;
unsigned int totalSize = 0;
unsigned i;
for(i=0; s0; s=1, ++i)
{
if (i0) mipmapData.push_back(totalSize);
totalSize += s*s*4;
}
unsigned char* ptr = new unsigned char[totalSize];
image-setImage(32, 32, 32, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, ptr,
osg::Image::USE_NEW_DELETE,1);
image-setMipmapLevels(mipmapData);
s = 32;
for(i=0; s0; s=1, ++i)
{
fillSpotLightImage(ptr, osg::Vec4(1.0f,1.0f,1.0f,1.0f),
osg::Vec4(1.0f,0.1f*s,1.0f/s,1.0f), s, 1.0);
ptr += s*s*4;
}
osg::Texture2D* mytex1 = new osg::Texture2D;
mytex1-setImage( 0, image );
mytex1-setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
mytex1-setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
mytex1-setFilter(osg::Texture::MIN_FILTER,
osg::Texture::NEAREST_MIPMAP_NEAREST);
mytex1-setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);