|
由于不会在回复里贴图,只好发个新话题了。
我对TexEnv的理解有限,经过各种模式的尝试,发现TexEnv影响到的是纹理的色泽等因素,而对于纹理贴图的方式没有改变,例如,用REPLACE模式依旧如下图:
可以看到有很明显的一条接缝。请问是纹理坐标的原因吗?
完整代码如下:class MoveEarthySkyWithEyePointTransform : public osg::Transform
{
public:
/** Get the transformation matrix which moves from local coords to world coords.*/
virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
{
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
if (cv)
{
osg::Vec3 eyePointLocal = cv->getEyeLocal();
matrix.preMultTranslate(osg::Vec3(eyePointLocal.x(),eyePointLocal.y(),0.0f));
}
return true;
} /** Get the transformation matrix which moves from world coords to local coords.*/
virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
{
std::cout<<"computing transform"<<std::endl;
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
if (cv)
{
osg::Vec3 eyePointLocal = cv->getEyeLocal();
matrix.postMultTranslate(osg::Vec3(-eyePointLocal.x(),-eyePointLocal.y(),0.0f));
}
return true;
}
};osg::ref_ptr<osg::Node> createSky()
{
int i, j;
float lev[] = { -5, -1.0, 1.0, 15.0, 30.0, 60.0, 90.0 };
float x, y, z;
float alpha, theta;
float radius = 150.0f;
int nlev = sizeof( lev )/sizeof(float); osg::ref_ptr<osg::Geode> geode = new osg::Geode();
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();
//设置顶点、纹理坐标
osg::Vec3Array& coords = *(new osg::Vec3Array(19*nlev));
osg::Vec2Array& tcoords = *(new osg::Vec2Array(19*nlev));
int ci = 0;
for( i = 0; i < nlev; i++ )
{
for( j = 0; j <= 18; j++ )
{
//转换为角度
alpha = osg:egreesToRadians(lev);
theta = osg::DegreesToRadians((float)(j*20));
//计算顶点的alpha,theta角
x = radius * sinf( alpha ) * cosf( theta );
y = radius * sinf( alpha ) * sinf( theta );
z = radius * cosf( alpha );
//计算从原点到该顶点的矢量
coords[ci][0] = x;
coords[ci][1] = y;
coords[ci][2] = z;
//纹理坐标
tcoords[ci][0] = (float)j/18.0;
tcoords[ci][1] = (float)i/(float)(nlev-1);
ci++;
}
}
geom->setVertexArray( &coords );//设置顶点坐标
geom->setTexCoordArray( 0, &tcoords );//设置纹理坐标
//添加图元
for( i = 0; i < nlev-1; i++ )
{
osg::ref_ptr<osg::DrawElementsUShort> drawElements = new osg::DrawElementsUShort(osg:rimitiveSet::TRIANGLE_STRIP);
drawElements->reserve(38); for( j = 0; j <= 18; j++ )
{
drawElements->push_back((i+1)*19+j);
drawElements->push_back((i+0)*19+j);
}
geom->addPrimitiveSet(drawElements.get());
}
osg::ref_ptr<osg::TexEnv> te = new osg::TexEnv();
te->setMode(osg::TexEnv::REPLACE);
//设置纹理贴图
osg::ref_ptr<osg::Image> image = osgDB::readImageFile("sky1.jpg");
osg::ref_ptr<osg::Texture2D> tex = new osg::Texture2D;
tex->setImage(image.get());
//设置渲染状态
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
stateset->setTextureAttributeAndModes(0,tex.get(),osg::StateAttribute::ON);
stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
stateset->setMode( GL_CULL_FACE, osg::StateAttribute::ON );
stateset->setTextureAttributeAndModes(0, te.get(), osg::StateAttribute::ON);
//将深度设置为远平面
osg::ref_ptr<osg::Depth> depth = new osg::Depth;
depth->setFunction(osg::Depth::ALWAYS);
depth->setRange(1.0,1.0);
stateset->setAttributeAndModes(depth,osg::StateAttribute::ON );
//设置渲染顺序
stateset->setRenderBinDetails(-1,"RenderBin");
geom->setStateSet(stateset.get());
//绘制
geode->addDrawable(geom.get());
//设置变换
/*osg::ref_ptr<osg::Transform> transform = new MoveEarthySkyWithEyePointTransform;
transform->setCullingActive(false);
transform->addChild(geode.get());*/
return geode.get();
/*osg::ref_ptr<osg::ClearNode> clearNode = new osg::ClearNode;
clearNode->setRequiresClear(false);
clearNode->addChild(transform.get());*/
//return clearNode.get();
//return transform.get();
} int _tmain(int argc, _TCHAR* argv[])
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
osg::ref_ptr<osg::Group> root = new osg::Group(); osg::ref_ptr<osg::Node> node = createSky();
root->addChild(node.get());
osgUtil::Optimizer optimizer;
optimizer.optimize(root.get());
viewer->setSceneData(root.get());
viewer->realize();
viewer->run();
return 0;
} |
|