学了接近一个月的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. windows使用nginx+memcached实现负载均衡和session或者缓存共享

    windows使用nginx+memcached实现负载均衡和session或者缓存共享 两台server server1:115.29.186.215 windows2008 64位操作系统 ser ...

  2. Qt Creator 代码自动补全设置

    Qt Creator具有自己的代码补全快捷键[Ctrl]+[Space] 但是在使用过程中,效果不明显,或者没有效果.可能是与输入法的切换冲突了.因此可以通过设置,避免这个问题. 解决方法: 1.打开 ...

  3. poj1236 有向图加边变成强连通图

    给我们一个有向图,有两个问题 1.最少要给多少个点发消息,才能使得所有的点都收到消息(消息可以随边传递) 2.最少需要多少条边才能使得图变成强连通图 对于一个强连通分量,可以当做一个点来考虑,所以我们 ...

  4. Sybase Unwired Platform(SUP) 经常使用资源整理(不断更新中)

    提示:建议刚開始学习的人看三个东西,详见以下的详细内容.然后再去看论坛,官方技术支持站点等资源. SUP移动开发平台 中文视频讲座 SUP入门讲座(Wang Jun) SUP系列学习笔记 SUP实验 ...

  5. IOS成长之路-Nsstring搜索方法rangeOfString

    NSString *str1 = @"can you \n speak English"; NSString *str = @"\n"; //在str1该字符串 ...

  6. 玩转web之javaScript(五)---js和jquery一些不可不知的方法(input篇)

    很多时候我们都利用js和jquery中操作input,比如追加属性,改变属性值等等,我在这里简单的整理了一下,并在以后逐步补充. 1:删除input的某一属性. <input name=&quo ...

  7. OpenStack Dashboard

    OpenStackDashboard 为管理员和普通用户提供了一个图形化管理界面.用户能够通过该界面訪问.分配或者自己主动化分配基于云的资源.可扩展的设计使得与第三方产品和服务融合变得非常easy,比 ...

  8. 什么是“Bash”破绽?

    摘要:近来的linux系统出现"Bash"漏洞可以被认为是第一个互联网造成安全讨论和思考.错的资料. 什么是"Bash"漏洞?它是怎样工作的?它是否可以成为新的 ...

  9. kNN(K-Nearest Neighbor)最近的分类规则

    KNN最近的规则,主要的应用领域是未知的鉴定,这一推断未知的哪一类,这样做是为了推断.基于欧几里得定理,已知推断未知什么样的特点和最亲密的事情特性: K最近的邻居(k-Nearest Neighbor ...

  10. Razor button

    比起Web Form開發,在後端(.cs)寫法上大同小異,可選擇C#或VB.NET來撰寫:而在前端(.cshtml..vbhtml)則有比較大的差別,自 MVC3版本後,就以Razor為前端檢視引擎, ...