学了接近一个月的OpenGL,最终要排上用场了...好吧,就从学到的shader(着色器)开刀吧。

先简单的介绍shader,shader事实上是显卡的功能,就是利用显卡的GPU去做图像处理的工作,而不是CPU,这样能够在一些复杂的大程序中释放CPU空间而提高效率。这篇文章仅仅是简单的介绍shader的使用,并没有介绍着色语言的语法结构等方面内容。后面等自己研究好了继续更新。

使用shader,一般要经过一下几个步骤:

1、创建shader,这里会使用到glew的拓展库,应该包括glew.h和glew32.lib。利用一下函数创建:

GLhandleARB frag_shader;
//创建fragment Shader
//--------------------------------------------------------------------
// GLuint glCreateShader(GLenum shaderType);
// 參数:
// ·shaderType – GL_VERTEX_SHADER or GL_FRAGMENT_SHADER.
//--------------------------------------------------------------------
frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);

2、向shader中导入着色程序,利用一下函数:

//---------------------------------------------------------------------------------------------------------------------
//void glShaderSource(GLuint shader, int numOfStrings, const char **strings, int *lenOfStrings);
//參数:
//·shader – the handler to the shader.
//·numOfStrings – the number of strings in the array.
//·strings – the array of strings.
//·lenOfStrings – an array with the length of each string, or NULL, meaning that the strings are NULL terminated.
//----------------------------------------------------------------------------------------------------------------------
glShaderSourceARB(frag_shader,1,(const char**)&inShader,NULL);

3、编译shader,就是将着色程序编译成shader能够识别的程序,以便使用:

//---------------------------------------------------------
//void glCompileShader(GLuint shader);
//參数:
//.shader – the handler to the shader.
//----------------------------------------------------------
glCompileShaderARB(frag_shader);

4、查询shader的状态,shader并不能向C/C++编译器那样能够print信息出来以參考,可是能够通过logInfo来看:

glGetObjectParameterivARB(frag_shader,GL_OBJECT_COMPILE_STATUS_ARB,&result);

if(!result)
{
char str[4096] = {0};
//------------------------------------------------------------------------------------
//将调试信息放入infoLog中
//void glGetShaderInfoLog(GLuint object, int maxLen, int *len, char *log);
//void glGetProgramInfoLog(GLuint object, int maxLen, int *len, char *log);
//參数:
//·object – the handler to the object. Either a shader or a program
//·maxLen – The maximum number of chars to retrieve from the InfoLog.
//·len – returns the actual length of the retrieved InfoLog.
//·log – The log itself.
//------------------------------------------------------------------------------
glGetInfoLogARB(frag_shader,sizeof(str),NULL,str);
glDeleteObjectARB(frag_shader);
return ;
}

5、连接shader,前面仅仅是把着色程序编译OK,如今要给创建好的shader使用:

shader = link(1,frag_shader);

6、link()函数是我自己写的,以下是link函数的代码:

GLhandleARB CShader::link(int shader_count,...)
{
//创建一个程序
GLhandleARB program = glCreateProgramObjectARB();
GLhandleARB shaderT = NULL; va_list marker; //初始化
va_start(marker,shader_count);
for(int i = 0; i< shader_count; i++)
{
shaderT = va_arg(marker,GLhandleARB);
//------------------------------------------------------------
//void glAttachShader(GLuint program, GLuint shader);
//參数:
// ·program – the handler to the program.
// ·shader – the handler to the shader you want to attach.
//-------------------------------------------------------------
glAttachObjectARB(program,shaderT);
}
va_end(marker); //连接程序
glLinkProgramARB(program); int result = 0;
glGetObjectParameterivARB(program,GL_OBJECT_LINK_STATUS_ARB,&result);
if(!result)
{
char str[4096] = {0};
glGetInfoLogARB(program,sizeof(str),NULL,str);
glDeleteObjectARB(program); return NULL;
}
return program;
}

事实上这个函数能够将多个着色程序给一个shader使用。

7、后面就是怎么使用Shader了,使用glUseProgram(program)和glUseProgram(NULL)要使用和卸载shader,

还有能够从C++代码中传递给着色程序的參数。

8、还有就是怎么把着色程序导入到shader中,这里事实上是一个纯读取文档的过程,并不难。

这里给出整个shader的程序:

CShader.h

#pragma once 

#ifndef GL_ARB_shader_objects
typedef GLhandleARB
typedef GLcharARB
#endif class CShader
{
public:
CShader(void);
public:
~CShader(void); public:
//初始化shader
void init(const char* inShader); //绑定纹理
void bind(); //撤销纹理
void unBind(); bool setParameter(char* keyword, GLfloat fv);
bool setParameter(char* keyword, GLuint texID);
char* loadShaderTex(const char* fileName); private:
GLhandleARB link(int shader_count,...);
public:
GLhandleARB shader; };

CShader.cpp

#include "stdafx.h"
#include <gl/glew.h>
#include "CShader.h"
#include <stdlib.h>
#include <stdarg.h> #pragma comment(lib,"glew32.lib") CShader::CShader(void)
{ } CShader::~CShader(void)
{ } void CShader::init(const char* inShader)
{
GLhandleARB frag_shader;
//创建fragment Shader
//--------------------------------------------------------------------
// GLuint glCreateShader(GLenum shaderType);
// 參数:
// ·shaderType – GL_VERTEX_SHADER or GL_FRAGMENT_SHADER.
//--------------------------------------------------------------------
frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); //---------------------------------------------------------------------------------------------------------------------
//void glShaderSource(GLuint shader, int numOfStrings, const char **strings, int *lenOfStrings);
//參数:
// ·shader – the handler to the shader.
// ·numOfStrings – the number of strings in the array.
// ·strings – the array of strings.
// ·lenOfStrings – an array with the length of each string, or NULL, meaning that the strings are NULL terminated.
//----------------------------------------------------------------------------------------------------------------------
glShaderSourceARB(frag_shader,1,(const char**)&inShader,NULL); //---------------------------------------------------------
//void glCompileShader(GLuint shader);
//參数:
// .shader – the handler to the shader.
//----------------------------------------------------------
glCompileShaderARB(frag_shader); int result = 0;
//查询状态
glGetObjectParameterivARB(frag_shader,GL_OBJECT_COMPILE_STATUS_ARB,&result); if(!result)
{
char str[4096] = {0};
//------------------------------------------------------------------------------------
//将调试信息放入infoLog中
//void glGetShaderInfoLog(GLuint object, int maxLen, int *len, char *log);
//void glGetProgramInfoLog(GLuint object, int maxLen, int *len, char *log);
//參数:
// ·object – the handler to the object. Either a shader or a program
// ·maxLen – The maximum number of chars to retrieve from the InfoLog.
// ·len – returns the actual length of the retrieved InfoLog.
// ·log – The log itself.
//------------------------------------------------------------------------------
glGetInfoLogARB(frag_shader,sizeof(str),NULL,str);
glDeleteObjectARB(frag_shader);
return ;
}
//Compile shader
shader = link(1,frag_shader);
glDeleteObjectARB(frag_shader);
} GLhandleARB CShader::link(int shader_count,...)
{
//创建一个程序
GLhandleARB program = glCreateProgramObjectARB();
GLhandleARB shaderT = NULL; va_list marker; //初始化
va_start(marker,shader_count);
for(int i = 0; i< shader_count; i++)
{
shaderT = va_arg(marker,GLhandleARB);
//------------------------------------------------------------
//void glAttachShader(GLuint program, GLuint shader);
//參数:
// ·program – the handler to the program.
// ·shader – the handler to the shader you want to attach.
//-------------------------------------------------------------
glAttachObjectARB(program,shaderT);
}
va_end(marker); //连接程序
glLinkProgramARB(program); int result = 0;
glGetObjectParameterivARB(program,GL_OBJECT_LINK_STATUS_ARB,&result);
if(!result)
{
char str[4096] = {0};
glGetInfoLogARB(program,sizeof(str),NULL,str);
glDeleteObjectARB(program); return NULL;
}
return program;
} void CShader::bind()
{
//if shader link successfully,then use it
glUseProgram( shader);
}
bool CShader::setParameter(char* keyword,GLfloat fv)
{
//find out where the flicker constant lives
GLint ret = glGetUniformLocation(shader, keyword);
if(ret != -1)
{
glUniform1f(ret,fv);
return true;
}
return false;
} bool CShader::setParameter(char* keyword,GLuint texID)
{
//Find out where the flicker constant lives
GLint ret = glGetUniformLocation(shader,keyword); if(ret != -1)
{
glUniform1iARB(ret, texID);
return true;
}
return false;
} void CShader::unBind()
{
glUseProgramObjectARB(NULL);
} char* CShader::loadShaderTex(const char* fileName)
{
char* shaderText = NULL;
GLint shaderLength = 0;
FILE *fp; fp = fopen(fileName,"r");
if(fp != NULL)
{
//get the char length
while(fgetc(fp) != EOF)
{
shaderLength++;
}
rewind(fp); shaderText = (GLchar*)malloc(shaderLength);
if(shaderText != NULL)
{
fread(shaderText,1,shaderLength,fp);
}
shaderText[shaderLength] = '\0';
fclose(fp);
}
return shaderText;
}

上面有把shader仅仅用写成接口,并没有给出着色程序的代码,你须要将着色程序保存为文本文档,然后用loadShaderText()读取程序,然后就是init(),利用setParameter()设置好參数就能够了。

OpenGL中shader使用的更多相关文章

  1. OpenGL中shader读取实现

    1.需要shader在OpenGL中工作,必须经过如下过程 2.代码实现 /********** * loadshader.h **********/ #pragma once #define _CR ...

  2. GLSL 在OpenGL中向shader传递信息【转】

    http://blog.csdn.net/hgl868/article/details/7872219 引言 一个OpenGL程序可以用多种方式和shader通信.注意这种通信是单向的,因为shade ...

  3. 【GLSL教程】(三)在OpenGL中向shader传递信息 【转】

    http://blog.csdn.net/racehorse/article/details/6634830 引言 一个OpenGL程序可以用多种方式和shader通信.注意这种通信是单向的,因为sh ...

  4. 【OpenGL】Shader实例分析(九)- AngryBots中的主角受伤特效

    转发请保持地址:http://blog.csdn.net/stalendp/article/details/40859441 AngryBots是Unity官方的一个非常棒的样例.非常有研究价值. 曾 ...

  5. Modern OpenGL用Shader拾取VBO内单一图元的思路和实现

    Modern OpenGL用Shader拾取VBO内单一图元的思路和实现 什么意思? 拾取 最简单的理解拾取的方式大概是到(http://www.yakergong.net/nehe/course/t ...

  6. Modern OpenGL用Shader拾取VBO内单一图元的思路和实现(2)

    Modern OpenGL用Shader拾取VBO内单一图元的思路和实现(2) 上一篇里介绍了Color-Coded Picking的思路和最基本的实现.在处理GL_POINTS时已经没有问题,但是处 ...

  7. Modern OpenGL用Shader拾取VBO内单一图元的思路和实现(3)

    Modern OpenGL用Shader拾取VBO内单一图元的思路和实现(3) 到上一篇为止,拾取一个VBO里的单个图元的问题已经彻底解决了.那么来看下一个问题:一个场景里可能会有多个VBO,此时每个 ...

  8. CSharpGL(6)在OpenGL中绘制UI元素

    CSharpGL(6)在OpenGL中绘制UI元素 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo,更适合入 ...

  9. OpenGL中glVertex、显示列表(glCallList)、顶点数组(Vertex array)、VBO及VAO区别

    OpenGL中glVertex.显示列表(glCallList).顶点数组(Vertex array).VBO及VAO区别 1.glVertex 最原始的设置顶点方法,在glBegin和glEnd之间 ...

随机推荐

  1. .net数据根据字段进行分类(linq语句)

    var items = List<实体>; var models = items.GroupBy(r => r.分类字段).ToDictionary(d => d.Key, d ...

  2. android旋转动画和平移动画具体解释,补充说一下假设制作gif动画放到csdn博客上

    先上效果图: 我这里用的是GifCam来制作的gif动画,能够在http://download.csdn.net/detail/baidu_nod/7628461下载, 制作过程是先起一个模拟器,然后 ...

  3. 安装Python和pip

    windows下面安装Python和pip终极教程 在大二的时候接触过一段时间的Python,最近又开始玩起了这门语言.总的来说,个人很喜欢Python的语言风格,但是这门语言对于windows并不算 ...

  4. JFinal开发8个常见问题

    下面是8个最常见的问题总结. 1.Can not create instance of class: demo.DemoConfig. 觉得应该是你的路径有问题, 打开你项目的java build p ...

  5. POJ 2536 Gopher II(二分图的最大匹配)

    题目链接:http://poj.org/problem?id=2536 题意:已知有n仅仅老鼠的坐标,m个洞的坐标,老鼠的移动速度为V,S秒以后有一仅仅老鹰要吃老鼠,问有多少个老鼠被吃. 非常明晰,二 ...

  6. zoj3822 期望dp

    每天在一个n*m的棋盘上放棋子,问使得每一行,每一列都有棋子的期望天数 dp[n][m][k] 表示用k个棋子占据了n行,m列,距离目标状态还需要的期望天数 那么dp[n][m][k] = p1 * ...

  7. Windows Phone开发(33):路径之其它Geometry

    原文:Windows Phone开发(33):路径之其它Geometry 上一节中,我们把最复杂的PathGeometry给干了,生剩下几个家伙就好办事了.一起来见见他们的真面目吧. 一.LineGe ...

  8. 6月27日CTO俱乐部下午茶印象

    作者:朱金灿 来源:http://blog.csdn.net/clever101 感谢CSDN的邀请,有幸参加了6月27日“CTO俱乐部下午茶时光:CTO在团队管理中所遇到的那些事”活动.本期的主讲嘉 ...

  9. 加入指数(IOS开发)

    该指数是用来协助查询. 原则上: - 索引的标题是不完全一样的标题显示: - 指数应该具有一定的代表性,它可表示一组数据: - 假设索引列表视图.在一般情况下不再使用扩展视图. (easy指向) 会又 ...

  10. WPF命令參数CommandParameter

    XAML代码例如以下: <Window x:Class="Demo006.MainWindow" xmlns="http://schemas.microsoft.c ...