您的位置:首页 > 运维架构

如何在自己的opengl程序中使用GLSL

2010-06-03 19:37 531 查看
GLSL,即GL Shading Language,用自己写的程序取代opengl的固定渲染管线的一种语言。

之前看了下RenderMonkey,虽然功能不算弱,但使用RenderMonkey却不知道在里面怎么用自己的shader去渲染自己的opengl程序,所以就去找下了关于把shader链接到自己的程序里的方法。

因为Microsoft仅支持到opengl1.1,所以使用了glew扩展。

测试用的vertex shader和fragment shader非常简单,即把物体显示为红色,代码如下:

//filename:temp.vert
void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

//filename:temp.frag
void main(void)
{
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}


shader的类的定义:

class Shader
{
public:
Shader();
~Shader();
bool ReadVertextShader(char *_fn);
bool ReadFragmentShader(char *_fn);
void SetShader();
void UseShader();
private:
bool TextFileRead(char *_fn,GLchar *&_shader);
GLchar *m_VertexShader;
GLchar *m_FragmentShader;

GLhandleARB m_Program;
GLhandleARB m_Vert,m_Frag;
};


其中m_VertexShader和m_FragmentShader存放shader的字符串,m_Vert、m_Frag和m_Program分别为顶点着色器对象、片段着色器对象和着色器程序对象的句柄。

在用ReadVertextShader()和ReadFragmentShader()方法来读取shader源代码之后,我们就使用SetShader()来编译着色器代码,然后当我们需要使用shader的时候就调用UseShader()即可。

SetShader()代码如下:

void Shader::SetShader()
{
//创建shader对象
m_Vert = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
m_Frag = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);

const GLcharARB *vv = m_VertexShader;
const GLcharARB *ff = m_FragmentShader;
//添加shader
glShaderSourceARB(m_Vert,1,&vv,NULL);
glShaderSourceARB(m_Frag,1,&ff,NULL);

//编译shader
glCompileShaderARB(m_Vert);
glCompileShaderARB(m_Frag);

//创建程序对象
m_Program = glCreateProgramObjectARB();

//绑定shader到程序对象
glAttachObjectARB(m_Program,m_Vert);
glAttachObjectARB(m_Program,m_Frag);

//链接程序
glLinkProgramARB(m_Program);
}


UseShader()代码如下:

void Shader::UseShader()
{
//使用程序
glUseProgramObjectARB(m_Program);
}


不过我并没有使用函数来获取编译和链接的日志,这个有待进一步改进。

当我们不需要再使用shader时,要先取消shader对象与程序对象的绑定关系,然后再删除这些对象,我把这些步骤放在了析构函数里执行:

Shader::~Shader()
{
if(NULL != m_VertexShader)
delete[] m_VertexShader;
if(NULL != m_FragmentShader)
delete[] m_FragmentShader;

//解除shader与program的绑定关系
glDetachShader(m_Program,m_Vert);
glDetachShader(m_Program,m_Frag);

//删除shader和program
glDeleteObjectARB(m_Vert);
glDeleteObjectARB(m_Frag);
glDeleteObjectARB(m_Program);
}


当我们写好类的实现方法后,就可以在程序里调用这些方法来使用shader了。

我是在WM_CREATE消息里执行这些的,可以根据需要来自行调用。

同时在WM_CREATE消息里使用了glewInit()来初始化glew,不初始化glew的话无法正常使用glew扩展的函数,并且glew的初始化要放在opengl资源创建之后……这个问题弄了我好久才把其解决……

程序运行图:



源代码下载:

http://download.csdn.net/source/2422990
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐