一个简单的GLSL Shader例子

摘要:
//首先查看顶点着色器temp.vert:uniformfloatColestTemp;uniformfloatTempRange;attributefloatVertexTemp;//每个固定点对应一个温度值,变量为floatTemperature//将其传递给片段处理器,以便后续处理void main{//Interpolate temperature=/TempRange;gl_Position=gl_ModelViewProjectionMatrix*gl_Vertex;}//碎片着色器temp.frag:uniformwec3CoolestColor;uniformvec3热测试颜色;浮动温度;Void main{//通过温度值查找最冷和最热vec3color=mix;gl_FragColor=vec4;}之间的对应颜色让我们看看如何链接着色器和应用程序,同时,指定了一些一致变量/*public*/intinstallShaders的值{GLintvertCompiled,fragCompiled;//statusvaluesGLintlinked;//CreateavetexshaderobjectandfragmentshaderobjectVertexShaderObject=glCreateShader;FragmentShader Object=glCreateShader;//将源代码字符串加载到shadersglShaderSource;glShader源;//编译brickvertexshader,并打印输出//编译器日志文件编译阴影;glGetShadriv;如果(!linked)返回0;//将程序对象安装为当前状态UseProgram;//设置初始统一值glUniform1f;gl统一1f;gl统一3f;gl统一3f;返回1;}某些函数用于读取外部着色器代码。顶点着色器后缀自定义为。vert,并且分段着色器被自定义为。碎片。我们还可以将着色器存储在程序中的字符串中。

本例子选自OpenGL Shading Language中的第一个Shader例子,使用颜色平滑地表示一个表面的温度。温度及其颜色的范围在应用程序中进行设置。
//先看顶点着色器temp.vert:
uniform float CoolestTemp;
uniform float TempRange;
attribute float VertexTemp;//每个定点都对应一个温度值
varying float Temperature;//传递到片段处理器进行后续处理
void main(void)
{
//进行插值
Temperature = (VertexTemp - CoolestTemp) / TempRange;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
//片段着色器temp.frag:
uniform vec3 CoolestColor;
uniform vec3 HottestColor;
varying float Temperature;
void main(void)
{
//通过温度值寻找一个相应的颜色,位于最冷和最热之间
vec3 color = mix(CoolestColor, HottestColor,Temperature);
gl_FragColor = vec4(color,1.0);
}
下面看看如何将着色器和应用程序进行链接(第一步是创建着色器对象,指定着色器源代码,进行编译,并程序对象和着色器进行绑定和链接),同时指定了一些一致变量的值
/*public*/
int installShaders(const GLchar *Vertex, const GLchar *Fragment)
{
GLint vertCompiled, fragCompiled;
// status values
GLint linked;
// Create a vertex shader object and a fragment shader object
VertexShaderObject = glCreateShader(GL_VERTEX_SHADER);
FragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER); /
/ Load source code strings into shaders
glShaderSource(VertexShaderObject, 1, &Vertex, NULL);
glShaderSource(FragmentShaderObject, 1, &Fragment, NULL);
// Compile the brick vertex shader, and print out
// the compiler log file.
glCompileShader(VertexShaderObject);
glGetShaderiv(VertexShaderObject, GL_COMPILE_STATUS, &vertCompiled);
// Compile the brick vertex shader, and print out
// the compiler log file.
glCompileShader(FragmentShaderObject);
glGetShaderiv(FragmentShaderObject, GL_COMPILE_STATUS, &fragCompiled);
if (!vertCompiled || !fragCompiled)
return 0;
// Create a program object and attach the two compiled shaders
ProgramObject = glCreateProgram();
glAttachShader(ProgramObject, VertexShaderObject);
glAttachShader(ProgramObject, FragmentShaderObject);
// Link the program object and print out the info log
glLinkProgram(ProgramObject);
glGetProgramiv(ProgramObject, GL_LINK_STATUS, &linked);
if (!linked)
return 0;
// Install program object as part of current state
glUseProgram(ProgramObject);
// Set up initial uniform values
glUniform1f(glGetUniformLocation(ProgramObject, "CoolestTemp"), 0.0f);
glUniform1f(glGetUniformLocation(ProgramObject, "TempRange"), 1.0f);
glUniform3f(glGetUniformLocation(ProgramObject, "CoolestColor"), 0.0, 0.0, 1.0);
glUniform3f(glGetUniformLocation(ProgramObject, "HottestColor"), 1.0, 0.0, 0.0);
return 1;
}
这其中用到了一些读取外部着色器代码的函数,顶点着色器后缀自定义为.vert,片段着色器自定义为.frag,我们也可以将着色器放在程序中存储在一个字符串中。
//Shader related functions static int shaderSize(char *fileName, EShaderType shaderType)
{
//返回顶点着色器或者片段着色器的大小
char name[100];
strcpy(name, fileName);
switch (shaderType)
{
case EVertexShader:
strcat(name, ".vert");
break;
case EFragmentShader:
strcat(name, ".frag");
break;
default:
printf("ERROR: unknown shader file type ");
exit(1);
break;
}
int count = -1;
// Open the file, seek to the end to find its length
int fd = _open(name, _O_RDONLY);
if (fd != -1)
{
count = _lseek(fd, 0, SEEK_END) + 1;
_close(fd);
}
return count;
}
static int readShader(char *fileName, EShaderType shaderType, char *shaderText, int size)
{
// Reads a shader from the supplied file and returns the shader in the
// arrays passed in.
Returns 1 if successful, 0 if an error occurred.
// The parameter size is an upper limit of the amount of bytes to read.
// It is ok for it to be too big.
FILE *fh;
char name[100];
int count;
strcpy(name, fileName);
switch (shaderType)
{
case EVertexShader:
strcat(name, ".vert");
break;
case EFragmentShader:
strcat(name, ".frag");
break;
default:
printf("ERROR: unknown shader file type ");
exit(1);
break;
}
// Open the file
fh = fopen(name, "r");
if (!fh)
return -1;
// Get the shader from a file.
fseek(fh, 0, SEEK_SET);
count = (int) fread(shaderText, 1, size, fh);
shaderText[count] = '

免责声明:内容来源于网络,仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇PHP的深copy和浅copyjava中表示二进制、八进制、十进制、十六进制下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

OpenGL编程逐步深入(四)Shaders

OpenGl 中的 Shader在一些中文书籍或资料中都被翻译为“着色器”, 单从字面意思也看不出Shader到底是什么,Shader实际上就是一段代码,用于完成特定功能的一个模块。Shader分为Vertex Shader(顶点着色器)和Pixel Shader(像素着色器)两种,其中Pixel Shader在本文中又被称为Fragment Shade...

shader 的 nounroll

刚刚解决了一个特别坑的问题。 客户有个需求 需要shader里面 loop 的iterator数量 在运行时确定。z 这样对于里面存在  sample的loop就会被force unroll但因为count不确定 就没法unroll就编译不过了 我发现只有一个方法就是 关掉unroll  我试验了各种 在shader里面用预编译指令 关unroll 的方法...

(转载)Cocos2dx-OpenGL ES2.0教程:初识MVP(3)

在上一篇文章中,我在介绍vertex shader的时候挖了一个坑:CC_MVPMatrix。它其实是一个uniform,每一个cocos2d-x预定义的shader都包含有这个uniform, 但是如果你在shader里面不使用这个变量的话,OpenGL底层会把它优化掉。 但是,CC_MVPMatrix是在什么时候设置进来的呢?我在shader里面明...

webgl学习笔记一-绘图单点

写在前面   WebGl(全称:Web Graphics Library : web图形库) 是基于OpenGL ES 2.0的3D绘图协议。   WebGL完美地解决了现有的Web交互式三维动画的两个问题:第一,它通过HTML脚本本身实现Web交互式三维动画的制作,无需任何浏览器插件支持;第二,它利用底层的图形硬件加速功能进行的图形渲染,是通过统一的、...

unity shader 变种(多重编译 multi_compile)

一、定义 在unity中我们可以通过使用#pragma multi_compile或#pragma shader_feature指令来为shader创建多个稍微有点区别的shader变体。这个Shader被称为宏着色器(mega shader)或者超着色器(uber shader)。实现原理:根据不同的情况,使用不同的预处理器指令,来多次编译Shader代...

Cesium深入浅出之3dtiles渲染【转】

引子 接触Cesium一年有余了,期间靠胡吃海塞吸收了很多有用的、没用的知识和技术,感觉有点消化不良,今天终于有时间来梳理一下了。之前一直搞二维的,对三维技术只能算是半路出家,不敢写太深的原理性文章,以免误人子弟,但写写心得还是可以的。我想写一个Cesium深入浅出系列,即将深刻的道理用浅显的语言表述出来,纵观大部分的技术类文章,应该没几个能真正的做到这一...