OSG geometry 手动设置纹理
一、原理
下面展示一张512*512的地形纹理图,现在要将纹理图,贴到地形表面上,这就需要计算每个顶点对应的纹理坐标了,通过纹理坐标与对应的顶点相关联,这样纹理就可以映射到地形表面了。那么,现在分为2个步骤,首先计算纹理坐标,接着使用OSG环境将纹理坐标与几何顶点相关联,并显示出来。
二、计算纹理坐标
纹理坐标如下图,左下角为(0,0 )右上角为(1,1),也就是每一个轴向在0-1范围内变化,数据类型为浮点型。我们将纹理图映射到地形所覆盖的大小即可(现在我们只考虑完全覆盖的情况)。
现在,我们开始计算纹理坐标了。假设我们的地形大小为128*128(即128*128个顶点),我们这样计算每个顶点的纹理坐标:
osg::ref_ptr<osg::Vec2Array> texcoords= new osg::Vec2Array;
geometry->setTexCoordArray(0,texcoords);
int iY;
int iX;
for( iY=0; iY<m_iSize-1; iY++ )
{
for( iX=0; iX<m_iSize; iX++ )
{
//纹理坐标
float texLeft = (float)iX/(m_iSize-1);
float texbottom = (float)iY/(m_iSize-1);
float texTop = (float)(iY+1)/(m_iSize-1);
texcoords->push_back(osg::Vec2(texLeft,texbottom));
points->push_back(osg::Vec3((float)iX, (float)iY, GetScaledHeightAtPoint(iX,iY)));
texcoords->push_back(osg::Vec2(texLeft,texTop));
points->push_back(osg::Vec3((float)iX, (float)iY+1, GetScaledHeightAtPoint(iX,iY+1)));
}
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::Mode::TRIANGLE_FAN,iY*m_iSize*2,m_iSize*2));
}
osg::StateSet* stateset = geometry->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(0,texture0,osg::StateAttribute::ON);