{
osg::Geometry* geom = new osg::Geometry;
osg::Vec3Array* coords = new osg::Vec3Array(4);
(*coords)[0] = corner;
(*coords)[1] = corner+width;
(*coords)[2] = corner+width+height;
(*coords)[3] = corner+height;
geom->setVertexArray(coords);
osg::Vec3Array* norms = new osg::Vec3Array(1);
(*norms)[0] = width^height;
(*norms)[0].normalize();
geom->setNormalArray(norms);
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
// 纹理坐标
osg::Vec2Array* tcoords = new osg::Vec2Array(4);
(*tcoords)[0].set(0.0f,0.0f);
(*tcoords)[1].set(1.0f,0.0f);
(*tcoords)[2].set(1.0f,1.0f);
(*tcoords)[3].set(0.0f,1.0f);
geom->setTexCoordArray(0,tcoords);
// 顶点索引
osg::UByteArray* coordIndices = new osg::UByteArray; // assumes we are using less than 256 points...
// 注意:4个顶点的顺序
coordIndices->push_back(0);
coordIndices->push_back(1);
coordIndices->push_back(2);
coordIndices->push_back(3);
geom->setVertexIndices(coordIndices);
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,coordIndices->size()));
if (image)
{
osg::StateSet* stateset = new osg::StateSet;
osg::Texture2D* texture = new osg::Texture2D;
texture->setImage(image);
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
geom->setStateSet(stateset);
}
return geom;
}
void cOSG::Test()
{
const osg::Vec3 corner( 0,0,0 );
const osg::Vec3 width( 1,0,0 );
const osg::Vec3 height( 0,1,0 );
osg::Image* image=NULL ;
image = osgDB::readImageFile("d:\\00_OSG\\dataTest\\000.jpg");
osg::Geode* geode = new osg::Geode;
geode->addDrawable(createSquare(corner, width, height, image));
mRootData->addChild(geode);
}
上面的代码绘制出来一个正确纹理的正方形,贴图正确,为什么就不能绘制多个正方形呢?替换为下面的代码,贴图不对啊?
osg::Drawable* createSquare(const osg::Vec3& corner,const osg::Vec3& width,const osg::Vec3& height, osg::Image* image=NULL)
{
osg::Geometry* geom = new osg::Geometry;
osg::Vec3Array* coords = new osg::Vec3Array( 9);
(*coords)[0] = corner;
(*coords)[1] = corner+width;
(*coords)[2] = corner+width+width;
(*coords)[3] = corner+height;
(*coords)[4] = corner+height+width;
(*coords)[5] = corner+height+width+width;
(*coords)[6] = corner+height+height;
(*coords)[7] = corner+height+height+width;
(*coords)[8] = corner+height+height+width+width;
geom->setVertexArray(coords);
osg::Vec3Array* norms = new osg::Vec3Array(1);
(*norms)[0] = width^height;
(*norms)[0].normalize();
geom->setNormalArray(norms);
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
// 纹理坐标
osg::Vec2Array* tcoords = new osg::Vec2Array(9);
(*tcoords)[0].set(0.0f,0.0f);
(*tcoords)[1].set(0.5f,0.0f);
(*tcoords)[2].set(1.0f,0.0f);
(*tcoords)[3].set(0.0f,0.5f);
(*tcoords)[4].set(0.5f,0.5f);
(*tcoords)[5].set(1.0f,0.5f);
(*tcoords)[6].set(0.0f,1.0f);
(*tcoords)[7].set(0.5f,1.0f);
(*tcoords)[8].set(1.0f,1.0f);
geom->setTexCoordArray(0,tcoords);
// 顶点索引
osg::UByteArray* coordIndices = new osg::UByteArray;
// 注意:4个顶点的顺序
coordIndices->push_back(0);
coordIndices->push_back(1);
coordIndices->push_back(4);
coordIndices->push_back(3);
geom->setVertexIndices(coordIndices);
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,coordIndices->size()));
//geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,0,coordIndices->size()));
if (image)
{
osg::StateSet* stateset = new osg::StateSet;
osg::Texture2D* texture = new osg::Texture2D;
texture->setImage(image);
texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
//stateset->setTextureAttributeAndModes(0, texture);
geom->setStateSet(stateset);
}
return geom;
}
2 个解决方案
#1
我也是深深的感到蛋疼,原来 纹理坐标 数目要和 索引数组一一对应,我用索引生成了一个正方形,所以,纹理应该是:
(*tcoords)[0].set(0.0f,0.0f);
(*tcoords)[1].set(0.5f,0.0f);
(*tcoords)[2].set(0.5f,0.5f);
(*tcoords)[3].set(0.0f,0.5f);
和
coordIndices->push_back(0);
coordIndices->push_back(1);
coordIndices->push_back(4);
coordIndices->push_back(3);
对应。问题解决。
不过,我理解,一个实体定点应该就一个纹理坐标,这样纹理不就有重复?
貌似我理解的不对,假如一个立方体,公用定点,但是三个面可能使用不同的纹理文件和不同的纹理坐标,那么,一个实体点就会有多个纹理坐标,所以,纹理坐标和索引数目一致是正确的。
(*tcoords)[0].set(0.0f,0.0f);
(*tcoords)[1].set(0.5f,0.0f);
(*tcoords)[2].set(0.5f,0.5f);
(*tcoords)[3].set(0.0f,0.5f);
和
coordIndices->push_back(0);
coordIndices->push_back(1);
coordIndices->push_back(4);
coordIndices->push_back(3);
对应。问题解决。
不过,我理解,一个实体定点应该就一个纹理坐标,这样纹理不就有重复?
貌似我理解的不对,假如一个立方体,公用定点,但是三个面可能使用不同的纹理文件和不同的纹理坐标,那么,一个实体点就会有多个纹理坐标,所以,纹理坐标和索引数目一致是正确的。
#2
或者,使用纹理索引,让坐标索引和纹理索引使用同一个 索引表!!!
#1
我也是深深的感到蛋疼,原来 纹理坐标 数目要和 索引数组一一对应,我用索引生成了一个正方形,所以,纹理应该是:
(*tcoords)[0].set(0.0f,0.0f);
(*tcoords)[1].set(0.5f,0.0f);
(*tcoords)[2].set(0.5f,0.5f);
(*tcoords)[3].set(0.0f,0.5f);
和
coordIndices->push_back(0);
coordIndices->push_back(1);
coordIndices->push_back(4);
coordIndices->push_back(3);
对应。问题解决。
不过,我理解,一个实体定点应该就一个纹理坐标,这样纹理不就有重复?
貌似我理解的不对,假如一个立方体,公用定点,但是三个面可能使用不同的纹理文件和不同的纹理坐标,那么,一个实体点就会有多个纹理坐标,所以,纹理坐标和索引数目一致是正确的。
(*tcoords)[0].set(0.0f,0.0f);
(*tcoords)[1].set(0.5f,0.0f);
(*tcoords)[2].set(0.5f,0.5f);
(*tcoords)[3].set(0.0f,0.5f);
和
coordIndices->push_back(0);
coordIndices->push_back(1);
coordIndices->push_back(4);
coordIndices->push_back(3);
对应。问题解决。
不过,我理解,一个实体定点应该就一个纹理坐标,这样纹理不就有重复?
貌似我理解的不对,假如一个立方体,公用定点,但是三个面可能使用不同的纹理文件和不同的纹理坐标,那么,一个实体点就会有多个纹理坐标,所以,纹理坐标和索引数目一致是正确的。
#2
或者,使用纹理索引,让坐标索引和纹理索引使用同一个 索引表!!!