OSG:4.纹理贴图

步骤:

     a 指定用户几何体的纹理坐标。

       指定纹理坐标和相应的纹理单元。

        OSG不支持非多重纹理接口,用户程序必须指定一个纹理单元,以对应纹理坐标数据和纹理状态。如果要使用单一纹理的话,只需要指定到纹理单元 0 即可。

     b 创建纹理属性对象并保存纹理图形数据.

       用户程序可以使用两个类来实现基本的 2D 纹理映射:osg::Texture2D和

      osg::Image。 Texture2D属于 StateAttribute 的派生类, 用于管理 OpenGL 纹理对象,而Image用于管理图像像素数据。 如果要使用2D图像文件作为纹理映射的图形,只要将        文件名赋给Image 对象并将Image关联到 Texture2D即可。

    c 为StateSet设置合适的纹理属性和模式.

tietu.cpp

#include
#include
#include
#include
#include
#include
#include
#include
#include


osg::ref_ptr createGeodes()
{
//创建一个用于保存几何信息的图像
osg::ref_ptr geom = new osg::Geometry;

//向Geode类添加几何体(Drawable)
osg::ref_ptr geode = new osg::Geode;
geode->addDrawable(geom.get());


//创建4个顶点的数组
osg::ref_ptr vArr = new osg::Vec3Array;
/*vArr->push_back(osg::Vec3(x, y, z));
vArr->push_back(osg::Vec3(x + w, y, z));
vArr->push_back(osg::Vec3(x + w, y + h, z));
vArr->push_back(osg::Vec3(x, y + h, z));*/


vArr->push_back(osg::Vec3(-1.0f,0.0f,-1.0f));
vArr->push_back(osg::Vec3(1.0f,0.0f,-1.0f));
    vArr->push_back(osg::Vec3(1.0f,0.0f,1.0f));
vArr->push_back(osg::Vec3(-1.0f,0.0f,1.0f));
geom->setVertexArray(vArr.get());




//由保存的数据绘制四个顶点的多边形
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));


//为法线创建数组
osg::ref_ptr nArr = new osg::Vec3Array;
nArr->push_back(osg::Vec3(0.0, 0.0, 1.0));
geom->setNormalArray(nArr.get());
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);


//为颜色创建数组
osg::ref_ptr cArr = new osg::Vec4Array;
cArr->push_back(osg::Vec4(1.0,1.0,1.0,1.0));
geom->setColorArray(cArr.get());
geom->setColorBinding(osg::Geometry::BIND_OVERALL);


//为纹理创建数组
osg::ref_ptr tArr0 = new osg::Vec2Array;//创建一个 Vec2Array对象以保存纹理单元 0 的纹理坐标
tArr0->push_back(osg::Vec2(0,0));
tArr0->push_back(osg::Vec2(0,4));
tArr0->push_back(osg::Vec2(4,4));
tArr0->push_back(osg::Vec2(4,0));
geom->setTexCoordArray(0,tArr0.get());


return geode.get();


}


osg::ref_ptr createPlane()//创建一个平面
{
osg::ref_ptr node = createGeodes();
osg::StateSet* state = node->getOrCreateStateSet();


state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
    state->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );

//std::string fileName("E:/SZAX_Yvonny/NY/Data/Images/sun.png");
std::string fileName("Images/sun.png");
    osg::ref_ptr image = osgDB::readImageFile( fileName );
    if (!image.valid())
    {
        osg::notify( osg::FATAL ) << "Unable to load data file Exiting." << std::endl;
        return NULL;
    }


//将图像关联到Texture 2D对象
osg::ref_ptr tex = new osg::Texture2D;
tex->setImage(image.get());


// 创建纹理对象后,释放内部的ref_ptr,删除Image图像。
    tex->setUnRefImageDataAfterApply( true );
    state->setTextureAttributeAndModes( 0, tex.get() );//关联材质属性与模式到材质单元0


//打开混合
osg::BlendFunc* bf = new osg::BlendFunc(
        osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA );
    state->setAttributeAndModes( bf );


    // 打开Alpha测试
    osg::AlphaFunc* af = new osg::AlphaFunc(
        osg::AlphaFunc::GREATER, 0.05f );
    state->setAttributeAndModes( af );




    return node.get();
}


main.cpp

#include
#include
#include
#include
#include
#include


using std::endl;


extern osg::ref_ptr createGeodes();
extern osg::ref_ptr createPlane();


int main(int argc, char *argv[])
{
osg::ref_ptr root = createPlane(); 


osgViewer::Viewer viewer;
viewer.setSceneData(root.get());
return viewer.run();
}




//注意纹理设置的几个变量区别:
//GL_REPEAT: 进行重复贴图;
//GL_CLAMP: 纹理坐标大于1.0时设置为1.0处的颜色, 小于0.0时设置为0.0处的颜色;
//GL_CLAMP_TO_EDGE: 简单忽略边界的采样值;
//CL_CLAMP_TO_BORDER: 在0.0或1.0以外的纹理坐标只使用边界纹理值;


你可能感兴趣的:(OSG)