2016-08-12 68 views
1

我想要做的應該是非常簡單的,我猜,但我沒有得到我想要的東西(也許是因爲我是這種工具的新手)。我只想通過頂點和片段着色器將某個紋理圖像(例如典型的磚)映射到現有的cessna.osg中。爲了完成這個任務,我選擇了一個非常簡單的頂點和片段着色器,在我的有限理解中,它應該可以工作,但事實並非如此。通過GLSL着色器的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; 
} 

我得到的是塞斯納模型用素色(紋理圖像的主色),但我從來沒有得到一個真正的「膨鬆」塞斯納。

我很抱歉如果問題很愚蠢,但我真的很感激任何一種幫助繼續前進的提示。

感謝

+0

您使用OpenGL或OpenGL ES? –

+0

在這個例子中,我使用的是OpenGL,但想法是學習如何在Open GL ES 2.0中完成同樣的事情(但現在我對OpenGL更感興趣) – user3417052

+1

你確定'cessna.osg '包含紋理座標? – SurvivalMachine

回答

1

您的代碼看起來不錯,但你一定使用不具有任何UV(紋理)的cessna.osg模型座標。

您可以用記事本檢查模型的文本版本(cessna.osgt),您將只看到頂點座標而不看紋理座標。

用任何其他具有紋理座標的模型運行測試。在osg-data repo有幾個,如skydome.osgt

+0

嗨rickyviking,非常感謝您的快速回答。這可能是原因,但是當我再次運行代碼時,現在加載skydome.osgt而不是cessna.osg,我得到了具有原始紋理(雲層天空)的skydome.osg。 我應該在我的代碼中進行任何進一步的修改,以獲得具有磚塊紋理的天幕板嗎? – user3417052

+0

哦,沒錯,在加載模型的StateSet中指定的紋理被使用,而不是你的,因爲它在場景圖中的節點下方。你可以從文本文件中刪除它自己的紋理,或者用這個調用覆蓋紋理屬性'ss-> setTextureAttributeAndModes(0,bodyTexture.get(),osg :: StateAttribute :: ON | osg :: StateAttribute :: OVERRIDE); ' – rickyviking

+0

完美,終於奏效了!非常感謝 ! – user3417052