osg纹理映射

来源:互联网 发布:雪姨王琳撕网络喷子 编辑:程序博客网 时间:2024/05/22 09:41
osg中纹理坐标分别为S T R三个方向,分别对应坐标系中的X Y Z三个坐标轴。
边界截取方案
EnumeratorCLAMP将大于1.0的数值设置为1.0,将小于0.0的数值设置为0.0,即将超出[0.0,1.0]范围的数值截取到[0.0,1.0]范围内,CLAMP_TO_EDGE总是忽略边界。处于纹理边缘或者靠近纹理边缘的纹理单元都用作纹理计算,但是不包括边界上的纹理单元CLAMP_TO_BORDER在[0.0,1.0]范围外的参数值用单独定义的边界颜色或纹理边缘进行绘制REPEAT图象在表面上重复出现。忽略纹理坐标的整数部分,并将纹理图的拷贝粘贴在物体表面上,这样才能做到无缝连接MIRROR图象在物体表面上不断重复,但是每次重复的时候对图象进行镜像或者反转。这样在纹理边缘处比较连贯
滤波方式
EnumeratorMIN_FILTER图像绘制时小于贴图的原始尺寸时采用MAG_FILTER图像绘制时大于贴图的原始尺寸时采用
滤波方案
其中MIPMAP为纹理细化。
EnumeratorLINEAR线性滤波方式NEAREST不光滑滤波方式

在OpenGL中定义了六种纹理表达方式
1:一维纹理
2:二维纹理
3:二维纹理数组
4:三位纹理
5:立方图纹理
6:矩形纹理
而在osg中,继承Texture类的纹理映射类有八种,多了两种分别为Texture2DMultisample类以及
TextureBuffer类,重要讲解一下其中三种纹理映射类。

1:一维纹理
一维纹理只在一个方向上有变化,其余的方向数值皆为1,可以等价于一条线。一维纹理要求纹理宽度为2的幂次方。

//一维纹理
void createTexture1D(osg::StateSet& ss)
{
osg::ref_ptr<osg::Image> image = new osg::Image;
image->setImage(256, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, new unsigned char[4 * 256], osg::Image::USE_NEW_DELETE);
unsigned char* ptr = image->data(); //得到图像数据的首地址
for (unsigned int i = 0; i < 256; i++)
{
*ptr++ = i;
*ptr++ = i;
*ptr++ = 255;
*ptr++ = 255;
}
osg::ref_ptr<osg::Texture1D> texture = new osg::Texture1D;
texture->setImage(image.get()); //设置某个面的纹理图像
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); //设置纹理边界截取方式为重复映射
texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); //设置纹理滤波方式
ss.setTextureAttributeAndModes(0, texture.get()); //设置一个纹理相关的渲染属性,同时设置与之绑定的渲染模式
}

int main()
{
osg::ref_ptr<osg::Geode> quad1 = new osg::Geode;
quad1->addDrawable(osg::createTexturedQuadGeometry(
osg::Vec3f(-3.0, 0.0, -0.5), osg::Vec3f(1.0, 0.0, 0.0), osg::Vec3f(0.0, 0.0, 1.0), 0.0, 0.0, 3.0, 1.0));
createTexture1D(*(quad1->getOrCreateStateSet())); //获取quad1对象的StateSet属性
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
viewer->setSceneData(quad1.get());
return viewer->run();
}

2:二维纹理
二维纹理可以将二维矩形图像映射到三维物体上,其要求图像宽度和高度必须是2的幂次方,单
位是纹素。

//二维纹理
void createTexture2D(osg::StateSet& ss)
{
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
texture->setImage(osgDB::readImageFile("Images/clockface.bmp"));
texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_BORDER);
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_BORDER);
texture->setBorderColor(osg::Vec4f(1.0, 1.0, 1.0, 1.0)); //设置边界纹理颜色为黑色
ss.setTextureAttributeAndModes(0, texture.get()); //设置一个纹理相关的渲染属性,同时设置与之绑定的渲染模式
}
int main()
{
osg::ref_ptr<osg::Geode> quad2 = new osg::Geode;
//使用createTexturedQuadGeometry快速构建一个四边形,设置四边形的纹理坐标范围为(-0.1,-0.1)到(1.1,1.1),会额外绘制纹理的边界
quad2->addDrawable(osg::createTexturedQuadGeometry(
osg::Vec3f(-0.5, 0.0, -0.5), osg::Vec3f(1.0, 0.0, 0.0), osg::Vec3f(0.0, 0.0, 1.0), -0.1, -0.1, 1.1, 1.1));
createTexture2D(*(quad2->getOrCreateStateSet())); //获取quad2对象的StateSet属性

osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
viewer->setSceneData(quad2.get());
return viewer->run();
}

3:立方图纹理
使用六个二维图像来表达一个立方体的六个面,而STR坐标轴的原点为这个立方体的中心点,
例子如下:
//立方图纹理
void createCubeMap(osg::StateSet& ss)
{
osg::ref_ptr<osg::TextureCubeMap> texture = new osg::TextureCubeMap;
texture->setImage(osg::TextureCubeMap::POSITIVE_X, osgDB::readImageFile("Images/posx.bmp"));
texture->setImage(osg::TextureCubeMap::NEGATIVE_X, osgDB::readImageFile("Images/negx.bmp"));
texture->setImage(osg::TextureCubeMap::POSITIVE_Y, osgDB::readImageFile("Images/posy.bmp"));
texture->setImage(osg::TextureCubeMap::NEGATIVE_Y, osgDB::readImageFile("Images/negy.bmp"));
texture->setImage(osg::TextureCubeMap::POSITIVE_Z, osgDB::readImageFile("Images/posz.bmp"));
texture->setImage(osg::TextureCubeMap::NEGATIVE_Z, osgDB::readImageFile("Images/negy.bmp"));
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
texture->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_EDGE);
texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
ss.setTextureAttributeAndModes(0, texture.get()); //设置一个纹理相关的渲染属性,同时设置与之绑定的渲染模式
ss.setTextureAttributeAndModes(0, new osg::TexGen); //设置一个纹理相关的渲染属性,同时设置与之绑定的渲染模式
//TexGen:封装了glTexGen()的功能,用于自动生成纹理坐标
}
int main()
{
osg::ref_ptr<osg::Geode> box = new osg::Geode;
osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints;
hints->setDetailRatio(0.5);
box->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3f(3.0, 0.0, 0.0),2.0),hints.get()));
createCubeMap(*(box->getOrCreateStateSet())); //获取box对象的StateSet属性
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
viewer->setSceneData(box.get());
return viewer->run();
}



原创粉丝点击