OpenGL中shader使用
学了接近一个月的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使用的更多相关文章
- OpenGL中shader读取实现
1.需要shader在OpenGL中工作,必须经过如下过程 2.代码实现 /********** * loadshader.h **********/ #pragma once #define _CR ...
- GLSL 在OpenGL中向shader传递信息【转】
http://blog.csdn.net/hgl868/article/details/7872219 引言 一个OpenGL程序可以用多种方式和shader通信.注意这种通信是单向的,因为shade ...
- 【GLSL教程】(三)在OpenGL中向shader传递信息 【转】
http://blog.csdn.net/racehorse/article/details/6634830 引言 一个OpenGL程序可以用多种方式和shader通信.注意这种通信是单向的,因为sh ...
- 【OpenGL】Shader实例分析(九)- AngryBots中的主角受伤特效
转发请保持地址:http://blog.csdn.net/stalendp/article/details/40859441 AngryBots是Unity官方的一个非常棒的样例.非常有研究价值. 曾 ...
- Modern OpenGL用Shader拾取VBO内单一图元的思路和实现
Modern OpenGL用Shader拾取VBO内单一图元的思路和实现 什么意思? 拾取 最简单的理解拾取的方式大概是到(http://www.yakergong.net/nehe/course/t ...
- Modern OpenGL用Shader拾取VBO内单一图元的思路和实现(2)
Modern OpenGL用Shader拾取VBO内单一图元的思路和实现(2) 上一篇里介绍了Color-Coded Picking的思路和最基本的实现.在处理GL_POINTS时已经没有问题,但是处 ...
- Modern OpenGL用Shader拾取VBO内单一图元的思路和实现(3)
Modern OpenGL用Shader拾取VBO内单一图元的思路和实现(3) 到上一篇为止,拾取一个VBO里的单个图元的问题已经彻底解决了.那么来看下一个问题:一个场景里可能会有多个VBO,此时每个 ...
- CSharpGL(6)在OpenGL中绘制UI元素
CSharpGL(6)在OpenGL中绘制UI元素 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo,更适合入 ...
- OpenGL中glVertex、显示列表(glCallList)、顶点数组(Vertex array)、VBO及VAO区别
OpenGL中glVertex.显示列表(glCallList).顶点数组(Vertex array).VBO及VAO区别 1.glVertex 最原始的设置顶点方法,在glBegin和glEnd之间 ...
随机推荐
- windows使用nginx+memcached实现负载均衡和session或者缓存共享
windows使用nginx+memcached实现负载均衡和session或者缓存共享 两台server server1:115.29.186.215 windows2008 64位操作系统 ser ...
- Qt Creator 代码自动补全设置
Qt Creator具有自己的代码补全快捷键[Ctrl]+[Space] 但是在使用过程中,效果不明显,或者没有效果.可能是与输入法的切换冲突了.因此可以通过设置,避免这个问题. 解决方法: 1.打开 ...
- poj1236 有向图加边变成强连通图
给我们一个有向图,有两个问题 1.最少要给多少个点发消息,才能使得所有的点都收到消息(消息可以随边传递) 2.最少需要多少条边才能使得图变成强连通图 对于一个强连通分量,可以当做一个点来考虑,所以我们 ...
- Sybase Unwired Platform(SUP) 经常使用资源整理(不断更新中)
提示:建议刚開始学习的人看三个东西,详见以下的详细内容.然后再去看论坛,官方技术支持站点等资源. SUP移动开发平台 中文视频讲座 SUP入门讲座(Wang Jun) SUP系列学习笔记 SUP实验 ...
- IOS成长之路-Nsstring搜索方法rangeOfString
NSString *str1 = @"can you \n speak English"; NSString *str = @"\n"; //在str1该字符串 ...
- 玩转web之javaScript(五)---js和jquery一些不可不知的方法(input篇)
很多时候我们都利用js和jquery中操作input,比如追加属性,改变属性值等等,我在这里简单的整理了一下,并在以后逐步补充. 1:删除input的某一属性. <input name=&quo ...
- OpenStack Dashboard
OpenStackDashboard 为管理员和普通用户提供了一个图形化管理界面.用户能够通过该界面訪问.分配或者自己主动化分配基于云的资源.可扩展的设计使得与第三方产品和服务融合变得非常easy,比 ...
- 什么是“Bash”破绽?
摘要:近来的linux系统出现"Bash"漏洞可以被认为是第一个互联网造成安全讨论和思考.错的资料. 什么是"Bash"漏洞?它是怎样工作的?它是否可以成为新的 ...
- kNN(K-Nearest Neighbor)最近的分类规则
KNN最近的规则,主要的应用领域是未知的鉴定,这一推断未知的哪一类,这样做是为了推断.基于欧几里得定理,已知推断未知什么样的特点和最亲密的事情特性: K最近的邻居(k-Nearest Neighbor ...
- Razor button
比起Web Form開發,在後端(.cs)寫法上大同小異,可選擇C#或VB.NET來撰寫:而在前端(.cshtml..vbhtml)則有比較大的差別,自 MVC3版本後,就以Razor為前端檢視引擎, ...