利用GLSL和OSG进行三维渲染项目实战

本文介绍了如何使用OpenGL和OpenSceneGraph(OSG)结合GLSL着色器进行三维渲染。内容包括:1) 用GLSL实现五颜六色的奶牛;2) GLSL 4.3.0绘制三角形;3) 动态颜色变化的奶牛效果;4) 创建半透明地板及奶牛倒影效果。文章详细解析了着色器代码和关键概念,如顶点着色器、片段着色器、模型视图投影矩阵等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1. 前言

2. 用GLSL实现五颜六色的奶牛

3. 用GLSL 4.3.0实现绘制三角形

4. 动态颜色变化的奶牛

5. 半透明地板奶牛倒影

6. 其它


1. 前言

        OpenGL 3.3及以后版本抛弃了glEnable(),glColor(),glVertex(),glEnable()等这一套传统流程函数和管线,采用着色器语言GLSL来渲染三维场景。相对于传统的管线模式,色器语言GLSL渲染模型具有高度灵活性、高度可编程性,更能实现一些非常复杂的效果。本博文用osg和着色器语言GLSL来实现几个特效,以到达掌握在osg下操作着色器语言GLSL的效果。

2. 用GLSL实现五颜六色的奶牛

本项目通过着色器绘制奶牛,代码如下:

#include <osg/Node>
#include <osgViewer/Viewer>
#include <osg/Program>
#include <osgDB/ReadFile>
#include <osg/Shader>
#include <osgViewer/ViewerEventHandlers>


static const char* vertexShader = {
	"varying vec4 color;\n"
	"void main(void ){\n"
		"color = gl_Vertex;\n"
		"gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
	"}\n"
};
static const 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<osg::Node>node = osgDB::readNodeFile("cow.osg");
	if (nullptr == node)
	{
		OSG_WARN << "cow node is null!";
		return 1;
	}

	osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;

	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::Program类从 osg::StateAttribute继承,封装了OPenGL中对着色器操作的glProgram之类的函数,通过addShader函数加入顶点着色器和片段着色器,之后加入奶牛节点的状态集类osg::StateSet对象中。
  • 在顶点着色器vertexShader中通过如下代码:             
"color = gl_Vertex;\n"

将奶牛未经过视图投影矩阵变换过的原始顶点(gl_Vertex表示的坐标)作为颜色值传递给color,接下来在片段着色器中利用该颜色,考虑到顶点坐标值可能不在[0, 1]区间,故用clamp进行截取,以保证颜色值在[0, 1]区间。该例子运行效果如下:

  •  对于顶点着色器,必须对gl_Position赋值;对于片段着色器,必须对gl_FragColor赋值,也就说gl_Position、gl_FragColor必须都要赋值,否则奶牛不会显示。
  • 注意:gl_FragColor、varying类型、gl_ModelViewProjectionMatrix 、gl_Vertex在GLSL 1.40之后的版本中移除了,因此在1.40以后的版本使用这些关键字会报错。

3. 用GLSL 4.3.0实现绘制三角形

      GLSL 4.30实现绘制三角形代码如下:

#include <osg/shader>
#include <osg/Node>
#include <osgDB/ReadFile>
#include <osgDB/fileutils>
#include <osg/Geometry>
#include <osgViewer/viewer>

static const char* vertexShader = {
		"#version 430 \n"
		"layout (location=0) in vec3 VertexPosition;\n"
		"layout (location=1) in vec4 VertexColor;\n"
		"uniform mat4 mvp;\n"
		"out vec4 Color;\n"
	    "out  vec4 Position;\n"
		"void main()\n"
		"{\n"
			"	Color = VertexColor;\n"
			"	gl_Position = mvp*vec4(VertexPosition, 1.0);\n"
	       
	"	}\n"
};

static const 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<osg::Vec4Array> colorsArray = new osg::Vec4Array;
	colorsArray->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
	colorsArray->push_back(osg::Vec4(0.0f,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值