#include
#include
#include
#include
#include
#include
static char * vertexShader = {
"varying vec4 color;\n"
"void main(void ){\n"
"color = gl_Vertex;\n"
"gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;\n"
"}\n"
};
static char * fragShader = {
"varying vec4 color;\n"
"void main(void){\n"
" gl_FragColor = clamp(color,0.0,1.0);\n"
"}\n"
};
int main()
{
osg::ref_ptr viewer = new osgViewer::Viewer;
osg::ref_ptrnode = osgDB::readNodeFile("glider.osg");
osg::StateSet * ss = node->getOrCreateStateSet();
osg::Program * program = new osg::Program;
program->addShader(new osg::Shader(osg::Shader::FRAGMENT,fragShader));
program->addShader(new osg::Shader(osg::Shader::VERTEX,vertexShader));
ss->setAttributeAndModes(program,osg::StateAttribute::ON);
viewer->addEventHandler(new osgViewer:: WindowSizeHandler);
viewer->setSceneData(node.get());
return viewer->run();
}
OSG 中使用GLSL 4.3版本
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static char * vertexShader= {
"#version 430 \n"
"layout (location=0) in vec3 VertexPosition;\n"
"layout (location=1) in vec4 VertexColor;\n"
"uniform mat4 MVP;"
"out vec4 Color;\n"
"void main()\n"
"{\n"
" Color = VertexColor;\n"
" gl_Position = MVP * vec4(VertexPosition,1.0);\n"
" }\n"
};
static char * fragShader ={
"#version 430 \n"
"in vec4 Color;\n"
"layout (location=0) out vec4 FragColor;\n"
"void main() {\n"
" FragColor = Color;//vec4(0.5,0.5,0.5,0.4);\n"
"}\n"
};
osg::Node * CreateNode()
{
osg::Geode * geode = new osg::Geode;
osg::Geometry* polyGeom = new osg::Geometry();
osg::Vec3Array* vertices = new osg::Vec3Array();
vertices->push_back(osg::Vec3(-5,0,0));
vertices->push_back(osg::Vec3(5,0,0));
vertices->push_back(osg::Vec3(0,0,5));
//polyGeom->setVertexArray(vertices);
osg::ref_ptr colorsArray = new osg::Vec4Array;
colorsArray->push_back(osg::Vec4(1.0f,0.0f,0.0f,1.0f));
colorsArray->push_back(osg::Vec4(0.0f,0.0f,1.0f,1.0f));
colorsArray->push_back(osg::Vec4(0.0f,1.0f,0.0f,1.0f));
// polyGeom->setColorArray(colorsArray.get());
//polyGeom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,0,3));
/*
The osg::Geometry class uses the setVertexAttribArray() and
setVertexAttribBinding() methods to bind vertex attributes to shaders. They should
be provided per vertex. GLSL's built-in vertex attributes include the gl_Position, gl_
Normal, and gl_MultiTexCoord* variables. However, you may still specify your own
vertex attributes, such as tangents or vertex weights.
Try declaring an attribute in the vertex shader and make use of the osg::Geometry's vertex
attribute arrays. Another important task that you need to perform is to bind the external
attribute array and the GLSL attribute, with the help of the addBindAttribLocation()
method of osg::Program. It has a name and an index parameter, the first of which
indicates the attribute name in the shader source code, and the second should correspond
to the input index value of setVertexAttribArray().
*/
polyGeom->setVertexAttribArray(0,vertices);
polyGeom->setVertexAttribBinding(0, osg::Geometry::BIND_PER_VERTEX);
polyGeom->setVertexAttribArray(1,colorsArray.get());
polyGeom->setVertexAttribBinding(1, osg::Geometry::BIND_PER_VERTEX);
geode->addDrawable(polyGeom);
return geode;
}
class MVPCallback: public osg::Uniform::Callback
{
public:
MVPCallback(osg::Camera * camera):mCamera(camera){
}
virtual void operator()( osg::Uniform* uniform, osg::NodeVisitor* nv){
osg::Matrix modelView = mCamera->getViewMatrix();
osg::Matrix projectM = mCamera->getProjectionMatrix();
uniform->set(modelView * projectM);
}
private:
osg::Camera * mCamera;
};
int main(int argc, char *argv[]) {
osgViewer::Viewer viewer;
osg::Group * root = new osg::Group;
osg::ref_ptrnode = CreateNode();
osg::StateSet * ss = node->getOrCreateStateSet();
osg::Program * program = new osg::Program;
program->addBindFragDataLocation("VertexPosition",0);
program->addBindFragDataLocation("VertexColor",1);
osg::Shader * vS = new osg::Shader(osg::Shader::FRAGMENT,fragShader);
osg::Shader * fS = new osg::Shader(osg::Shader::VERTEX,vertexShader);
osg::Uniform* MVPUniform = new osg::Uniform( "MVP",osg::Matrix());
MVPUniform->setUpdateCallback(new MVPCallback(viewer.getCamera()));
ss->addUniform(MVPUniform);//对应的Program和Uniform要加到同一个Node下的StateSet中
program->addShader(vS);
program->addShader(fS);
ss->setAttributeAndModes(program,osg::StateAttribute::ON);
root->addChild(node);
viewer.setSceneData(root);
viewer.run();
return 0;
}