学了接近一个月的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. java Quartz定时器任务与Spring task定时的几种实现,

    java Quartz定时器任务与Spring task定时的几种实现 基于java 的定时任务实现, Quartz 时间详细配置    请查阅   http://www.cnblogs.com/si ...

  2. 【足迹C++primer】40、动态数组

    动态数组 C++语言定义了第二种new表达式语法.能够分配并初始化一个对象数组.标准库中包括 一个名为allocator的类.同意我们将分配和初始化分离. 12.2.1 new和数组 void fun ...

  3. CSS选项卡

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " http://www.w3.org ...

  4. HDU 4380 Farmer Greedy 计算几何+bitset

    枚举直线,对于直线的某个点在直线的左端还是右端,能够状压出一个数.用bitset记录. 然后三角形就是3个bitset&一下 #include <cstdio> #include ...

  5. js中 正則表達式

    正則表達式使用具体解释 简单介绍 简单的说,正則表達式是一种能够用于模式匹配和替换的强有力的工具.其作用例如以下: 測试字符串的某个模式.比如,能够对一个输入字符串进行測试,看在该字符串是否存在一个电 ...

  6. mysql-定时调用存储过程

    mysql定时调用存储过程,对表数据集表结构进行备份 存储过程实例: BEGIN DECLARE tname varchar(64); set @tname = CONCAT('RENAME TABL ...

  7. Conversion to Dalvik format failed with error 1

    主要和添�的第三方的包有关系. ======================================= 出现,Conversion to Dalvik format failed with e ...

  8. 金色的 SQL注意事项(1)

    page(1-75) 最好是没有意义的主键字段,以方便未来的扩展. PS:主键,以后标书编码填错须要改的时候,关联表都须要跟着改.假设是一个无意义的自增字段是主键就无此原因. 主键最好不要设置为联合主 ...

  9. SQL Server :理解Page Free Space (PFS) 页

    原文:SQL Server :理解Page Free Space (PFS) 页 我们已经讨论了GAM与SGAM页,数据页(Data Page) ,现在我们来看下页面自由空间页(Page Free S ...

  10. ORA-00020的思考

    今天,历史的图书馆例行检查DB,发现alert.log有一"ORA-00020: maximum number of processes (150) exceeded",这是一个常 ...