OSG 一个简单的着色器例子



#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;
}




你可能感兴趣的:(OSG)