通过GLSL着色器对cessna.osg进行纹理映射

时间:2016-08-12 00:53:34

标签: opengl opengl-es 3d glsl openscenegraph

我想要做的应该是非常简单,我想,但我没有得到我想要的东西(也许是因为我在这种工具中有点新手)。我只是想通过顶点和片段着色器将某个纹理图像(例如典型的砖块)映射到现有的cessna.osg中。为了完成这项任务,我选择了一个非常简单的顶点和片段着色器,在我有限的理解中,它应该可以工作,但事实并非如此。

以下是代码:

#include <osg/PositionAttitudeTransform>   
#include <osgDB/ReadFile>   
#include <osgDB/FileUtils>   
#include <osgGA/TrackballManipulator>   
#include <osg/Program>   
#include <osg/Shader>   
#include <osgViewer/Viewer>   
#include <iostream>   
#include <osg/Texture2D>   

static const char* VertexShader = {
    "varying vec2 texCoords;\n"
    "void main()\n"
    "{\n"
    "   texCoords = gl_MultiTexCoord0.st;\n"
    "   gl_Position = ftransform();\n"
    "}\n"
};

static const char* FragmentShader = {
    "varying vec2 texCoords;\n"
    "uniform sampler2D tex;\n"
    "void main()\n"
    "{\n"
    "   gl_FragColor = texture2D(tex, texCoords);\n"
    "}\n"
};

int main(int argc, char **argv)
{
    // Assembling scenegraph
    osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("cessna.osg");

    // Assigning program
    osg::ref_ptr<osg::StateSet> ss = model->getOrCreateStateSet();
    osg::ref_ptr<osg::Program> program(new osg::Program);
    osg::ref_ptr<osg::Shader> vShader(new osg::Shader(osg::Shader::VERTEX, VertexShader));
    osg::ref_ptr<osg::Shader> fShader(new osg::Shader(osg::Shader::FRAGMENT, FragmentShader));
    program->addShader(vShader);
    program->addShader(fShader);
    ss->setAttributeAndModes(program.get());

    //Set Texture 1
    osg::ref_ptr<osg::Texture2D> bodyTexture = new osg::Texture2D;
    bodyTexture->setImage(osgDB::readImageFile("Images/Brick-Norman-Brown.TGA"));

    bodyTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
    bodyTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
    bodyTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
    bodyTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);

    ss->setTextureAttributeAndModes(0, bodyTexture.get());
    ss->addUniform(new osg::Uniform("tex", 0));

    // View the scene
    osgViewer::Viewer viewer;
    viewer.setSceneData(model);
    viewer.setUpViewInWindow(0, 0, 512, 384);
    return viewer.run();

    return 0;
}

我得到的是具有纯色的cessna模型(纹理图像的主色),但我从未得到过真正的“纹理化”赛斯纳。

如果这个问题非常愚蠢,我道歉,但我非常感谢任何有助于继续前进的提示。

由于

1 个答案:

答案 0 :(得分:1)

您的代码看起来不错,但您使用的cessna.osg模型肯定没有任何UV(纹理)坐标。

您可以使用记事本检查模型的文本版本(cessna.osgt),并且您只能看到顶点坐标而不是纹理坐标。

使用纹理坐标的任何其他模型运行测试。在osg-data repo中有几个,比如skydome.osgt