查看: 1338|回复: 4

osg的纹理过滤好像有问题

[复制链接]

该用户从未签到

发表于 2010-8-18 02:03:55 | 显示全部楼层 |阅读模式
本帖最后由 yonjin 于 2010-8-18 02:06 编辑

我把一个纹理贴在一个梯形上时,osg好像不能进行双线性过滤。
如下图所示,第一个图是正确结果(在Creator中显示的),第二个图是osg绘制的结果。
creator is right.PNG     osg is wrong.PNG
程序很简单,主要代码如下:
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/Geode>
#include <osg/Group>
#include <osg/Image>
#include <osg/TexGen>
#include <osg/Texture1D>
#include <osg/TexEnv>
#include <osg/StateSet>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgUtil/Optimizer>
//创建一个四边形节点
osg::ref_ptr<osg::Node> createNode()
{
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();
//设置顶点
osg::ref_ptr<osg::Vec3Array> vc= new osg::Vec3Array();
vc->push_back(osg::Vec3( -7.15861, 0, 5.30002));
vc->push_back(osg::Vec3(7.15861, 0, 5.30001));
vc->push_back(osg::Vec3(58.0787, 0, 159.665));
vc->push_back(osg::Vec3(-58.0788, 0, 159.665));
geom->setVertexArray(vc.get());
//设置纹理坐标
osg::ref_ptr<osg::Vec2Array> vt= new osg::Vec2Array();
vt->push_back(osg::Vec2(0.0f,0.0f));
vt->push_back(osg::Vec2(1.0f,0.0f));
vt->push_back(osg::Vec2(1.0f,1.0f));
vt->push_back(osg::Vec2(0.0f,1.0f));
geom->setTexCoordArray(0,vt.get());
//设置法线
osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array();
nc->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
geom->setNormalArray(nc.get());
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
//添加图元
geom->addPrimitiveSet(new osg:rawArrays(osg:rimitiveSet:UADS,0,4));
//绘制
geode->addDrawable(geom.get());
return geode.get();
}
//创建二维纹理状态对象
osg::ref_ptr<osg::StateSet> createTexture2DState(osg::ref_ptr<osg::Image> image)
{
//创建状态集对象
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
//创建二维纹理对象
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D();
texture->setDataVariance(osg::Object::DYNAMIC);
//设置贴图
texture->setImage(image.get());
texture->setFilter( osg::Texture::MIN_FILTER, osg::Texture:INEAR_MIPMAP_LINEAR );
texture->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
texture->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
texture->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
stateset->setTextureAttributeAndModes(0,texture.get(),osg::StateAttribute::ON);
return stateset.get() ;
}
int main()
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
osg::ref_ptr<osg::Group> root = new osg::Group();
//读取贴图文件
osg::ref_ptr<osg::Image> image = osgDB::readImageFile("ScreenShot0000.bmp");
osg::ref_ptr<osg::Node> node = createNode();
//创建状态集对象
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
stateset = createTexture2DState(image.get());
//使用二维纹理
node->setStateSet(stateset.get());
//osg::Node* node = osgDB::readNodeFile("quad.flt");
root->addChild(node);
//优化场景数据
osgUtil::Optimizer optimizer ;
optimizer.optimize(root.get()) ;
viewer->setSceneData(root.get());
viewer->realize();
viewer->run();
return 0 ;
}

具体测试程序在附件中。

二维纹理有问题.rar

617.03 KB, 下载次数: 66, 下载积分: 威望 1

该用户从未签到

发表于 2010-8-18 09:16:42 | 显示全部楼层
这个恐怕并不是双线性或者三线性滤波的问题,它们在OpenGL中是用来实现纹理数据在拉近或者拉远时的平滑处理的

您的问题恐怕是由于OpenGL纹理坐标的默认插值方式造成的,您可以考虑用TexGen的方式来自动映射纹理坐标,或者使用shader

该用户从未签到

 楼主| 发表于 2010-8-18 11:06:20 | 显示全部楼层
好像不是纹理坐标的问题,我用shader绘出了每个片元的纹理坐标,看起来是对的。
片元的代码为:gl_FragColor = vec4(gl_TexCoord[0].st, 0, 1);
显示的结果如下图:
texCoords.png

该用户从未签到

发表于 2010-8-18 12:36:39 | 显示全部楼层
我想这恰恰说明了您的纹理图中圆环被扭曲的原因所在

该用户从未签到

 楼主| 发表于 2010-8-18 15:05:20 | 显示全部楼层
array: 你说的对,确实是由于OpenGL默认的纹理坐标插值方式造成。
这样看来,建模时非矩形面上贴的矩形纹理在默认显示时都是有问题的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表