cessna.osg 通过 GLSL 着色器的纹理映射
Texture mapping of the cessna.osg via GLSL shaders
我想我想做的应该很简单,但我没有得到我想要的(可能是因为我是这类工具的新手)。我只想通过顶点和片段着色器将某个纹理图像(例如典型的砖块)映射到现有 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;
}
我得到的是纯色(纹理图像的主要颜色)的塞斯纳模型,但我从来没有得到真正的"texturized"塞斯纳。
如果问题非常愚蠢,我深表歉意,但我非常感谢任何有助于继续前进的提示。
谢谢
您的代码看起来不错,但是您使用的 cessna.osg 模型肯定没有任何 UV(纹理)坐标。
您可以使用记事本检查模型的文本版本 (cessna.osgt),您只会看到顶点坐标,而看不到纹理坐标。
运行 您使用任何其他具有纹理坐标的模型进行测试。在osg-data repo里面有好几个,比如skydome.osgt
我想我想做的应该很简单,但我没有得到我想要的(可能是因为我是这类工具的新手)。我只想通过顶点和片段着色器将某个纹理图像(例如典型的砖块)映射到现有 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;
}
我得到的是纯色(纹理图像的主要颜色)的塞斯纳模型,但我从来没有得到真正的"texturized"塞斯纳。
如果问题非常愚蠢,我深表歉意,但我非常感谢任何有助于继续前进的提示。
谢谢
您的代码看起来不错,但是您使用的 cessna.osg 模型肯定没有任何 UV(纹理)坐标。
您可以使用记事本检查模型的文本版本 (cessna.osgt),您只会看到顶点坐标,而看不到纹理坐标。
运行 您使用任何其他具有纹理坐标的模型进行测试。在osg-data repo里面有好几个,比如skydome.osgt