OSG环境下GLSL实现几何着色器的纹理采样

最近在写着色器的学习例子,此个例子为原创 ,翻阅了挺多资料的,最后竟发现原来原理如此简单,里面涉及到glsl的基础知识,还有osg的一些应用,主要是作为外部应用程序的设置。

在这里,使用的是一维纹理,部分代码解释放在注释里。

直接看代码:

#include <osgViewer/Viewer>

#include <osg/Geometry>
#include <osg/Material>
#include <osgDB/ReadFile>
#include <osg/Image>
#include <osg/Texture1D>
#include <osg/GL>


void configureShaders(osg::StateSet* stateSet)
{
const std::string vertexSource =
"#version 330                            \n"
"layout (location = 0) in vec4 Position; \n"
"layout (location = 1) in vec4 color;    \n"
"layout (location = 2) in vec3 Normal; \n"
"layout (location = 3) in vec2 Texcoord; \n"
"uniform mat3 osg_NormalMatrix; \n"
"out vec4 vcolor;                             \n"
"out vec3 Norm;  \n"
"out VS_OUT \n"//使用接口块来保存纹理坐标
"{\n"
"vec2 texcoord; \n"
"}vs_out;\n"
"uniform sampler1D Tex1D;\n"
"void main()                             \n"
"{                                       \n"
"    gl_Position = Position;             \n"
"    vcolor = color;                       \n"
"    Norm = osg_NormalMatrix * Normal; \n"
"   vs_out.texcoord = Texcoord;  \n"
"} \n";
osg::Shader* vShader = new osg::Shader(osg::Shader::VERTEX, vertexSource);


const std::string geomSource =
"#version 330                                                                       \n"
"layout(triangles_adjacency) in;                                           \n"
"layout(triangle_strip) out;                                    \n"
"layout(max_vertices = 10) out;                                    \n"
"uniform mat4 osg_ModelViewProjectionMatrix;                                        \n"
"in vec4 vcolor[];\n"/*<数组大小由输入图元的顶点数来定,下标索引为0,1,2...>*/
"in vec3 Norm[]; \n"
"in VS_OUT \n"
"{\n"
"vec2 texcoord; \n"
"}gs_in[];\n"
"out vec2 tex; \n"
"out vec4 fcolor;                                                                   \n"
"out vec3 norm;   \n"
"uniform sampler1D Tex1D;\n"
"void main(void)                                    \n"
"{                                    \n"
"float index00=1.0;\n"
"float index01=6.0;\n"
"float Index0=index00/8.0;\n"
"float Index1=index01/8.0;\n"
"       tex=gs_in[0].texcoord;   \n"
"       fcolor=texture(Tex1D,0.0);                                                       \n"/*<设置每个顶点颜色都不一样>*/
"       norm=Norm[0]; \n"
" gl_Position = osg_ModelViewProjectionMatrix*vec4(0.0,0.0,0.0,1.0);    \n"
" EmitVertex();                                                            \n"
"       tex=gs_in[3].texcoord;   \n"
"       fcolor=texture(Tex1D,Index0);                                                       \n"/*<设置每个顶点颜色都不一样>*/
"       norm=Norm[3]; \n"
" gl_Position = osg_ModelViewProjectionMatrix*vec4(1.0,0.0,0.0,1.0);    \n"
" EmitVertex();                                                            \n"
"       tex=gs_in[2].texcoord;   \n"
"       fcolor=texture(Tex1D,Index1);                                                       \n"/*<设置每个顶点颜色都不一样>*/
"       norm=Norm[0]; \n"
" gl_Position = osg_ModelViewProjectionMatrix*vec4(0.0,1.0,0.0,1.0);    \n"
" EmitVertex();                                                            \n"
" EndPrimitive();                                    \n"
"} \n";

osg::Shader* gShader = new osg::Shader(osg::Shader::GEOMETRY, geomSource);
const std::string fragmentSource =
"#version 330 \n"
" \n"
"layout (location = 0) out vec4 fragData; \n"
" \n"
"uniform sampler1D Tex1D;\n"
"in vec4 fcolor;                           \n"
"in vec3 norm;   \n"//这里片元着色器传进了法向量,但是斌没有参与计算。
"in vec2 tex; \n"
"void main() \n"
"{ \n"
"  fragData = fcolor; \n"
"} \n";
osg::Shader* fShader = new osg::Shader(osg::Shader::FRAGMENT, fragmentSource);


osg::Program* program = new osg::Program;


program->addShader(vShader);
program->addShader(gShader);
program->addShader(fShader);


stateSet->setAttribute(program);
}


void main()
{
osg::ref_ptr<osg::Group> root = new osg::Group;
/*<顶点坐标>*/
osgViewer::Viewer viewer;
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
vertices->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
vertices->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));
vertices->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));
vertices->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));
vertices->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));
/*<顶点颜色>*/
osg::ref_ptr<osg::Vec4Array> V_C = new osg::Vec4Array;
V_C->push_back(osg::Vec4(0.0, 1.0, 1.0, 1.0));
V_C->push_back(osg::Vec4(0.0, 0.0, 1.0, 1.0));
V_C->push_back(osg::Vec4(1.0, 1.0, 1.0, 1.0));
V_C->push_back(osg::Vec4(0.0, 1.0, 0.0, 1.0));
/*<顶点法线>*/
osg::ref_ptr<osg::Vec3Array> V_N = new osg::Vec3Array;
V_N->push_back(osg::Vec3(0.0, 1.0, 0.0));
/*<顶点纹理坐标>*/
osg::ref_ptr<osg::Vec2Array> V_T = new osg::Vec2Array;
V_T->push_back(osg::Vec2(0.0, 0.0));
V_T->push_back(osg::Vec2(1.0, 0.0));
V_T->push_back(osg::Vec2(1.0, 1.0));
V_T->push_back(osg::Vec2(0.0, 1.0));


osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();
/*<设置顶点>*/
geom->setVertexArray(vertices);
/*<顶点颜色>*/
geom->setVertexAttribArray(1, V_C);
geom->setVertexAttribBinding(1, osg::Geometry::BIND_PER_VERTEX);
/*<顶点法线>*/
geom->setVertexAttribArray(2, V_N);
geom->setVertexAttribBinding(2, osg::Geometry::BIND_OVERALL);
/*<顶点纹理坐标>*/
geom->setTexCoordArray(0, V_T);
osg::Texture1D* MyTex1D = new osg::Texture1D;
MyTex1D->setDataVariance(osg::Object::DYNAMIC);
/*<使用一维纹理来保存顶点数据>*/
osg::Image* MyImage1D = new osg::Image;
unsigned char Vert1D[10] = { 100, 45, 76, 23, 78, 154, 345, 432, 321, 22 };
MyImage1D->setImage(8, 1, 1, 4, GL_RGBA, GL_FLOAT, Vert1D, osg::Image::USE_MALLOC_FREE);
MyImage1D->setColor(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f), 0);
MyImage1D->setColor(osg::Vec4(0.0f, 1.0f, 1.0f, 1.0f), 1);
MyImage1D->setColor(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f), 2);
MyImage1D->setColor(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f), 3);
MyImage1D->setColor(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f), 4);
MyImage1D->setColor(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f), 5);
MyImage1D->setColor(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f), 6);
MyImage1D->setColor(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f), 7);
MyTex1D->setImage(MyImage1D);
geom->getOrCreateStateSet()->setTextureAttributeAndModes(0, MyTex1D, osg::StateAttribute::ON);
geom->getOrCreateStateSet()->addUniform(new osg::Uniform("Tex1D", 0));


geom->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES_ADJACENCY, 0, 6));
configureShaders(geom->getOrCreateStateSet());
root->addChild(geom);


/*<版本指定>*/
const int width(800), height(450);
const std::string version("3.1");
osg::ref_ptr< osg::GraphicsContext::Traits > traits = new osg::GraphicsContext::Traits();
traits->x = 50; traits->y = 30;
traits->width = width; traits->height = height;
traits->windowDecoration = true;
traits->doubleBuffer = true;
traits->glContextVersion = version;
osg::ref_ptr< osg::GraphicsContext > gc = osg::GraphicsContext::createGraphicsContext(traits.get());
if (!gc.valid())
{
osg::notify(osg::FATAL) << "Unable to create OpenGL v" << version << " context." << std::endl;
return;
}
// Create a Camera that uses the above OpenGL context.
osg::Camera* cam = viewer.getCamera();
cam->setGraphicsContext(gc.get());
// Must set perspective projection for fovy and aspect.
cam->setProjectionMatrix(osg::Matrix::perspective(30., (double)width / (double)height, 1., 100.));
// Unlike OpenGL, OSG viewport does *not* default to window dimensions.
cam->setViewport(new osg::Viewport(0, 0, width, height));
// for non GL3/GL4 and non GLES2 platforms we need enable the osg_ uniforms that the shaders will use,
// you don't need thse two lines on GL3/GL4 and GLES2 specific builds as these will be enable by default.
gc->getState()->setUseModelViewAndProjectionUniforms(true);
gc->getState()->setUseVertexAttributeAliasing(true);


viewer.setSceneData(root.get());
viewer.run();
return;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值