着色器和程序

1.创建和编译一个着色器

  1. 使用着色器对象的第一步是创建着色器,用glCreateShader完成

GLuint glCreateShader(GLenum type)

typeValue对象
typeGL_VERTEX_SHADER顶点着色器
typeGL_FRAGMENT_SHADER片段着色器
返回值指向新着色器对象的句柄

当完成着色器对象时,可以用glDeleteShader删除

void glDeleteShader(GLuint shader)
shader 要删除的着色器对象的句柄
如果一个着色器连接到一个程序对象,那么调用glDeleteShader不会立刻删除着色器,而是将着色器标记为删除,在着色器不再连接到任何程序对象时,它的内存将被释放
2.一旦创建了着色器对象,下一件事通常是用glShaderSource提供着色器源代码。

void glShaderSource(GLuint shader,GLsizei count,
const GLchar * const * string, const GLint * length)

shader指向着色器对象的句柄
count着色器源字符串的数量
string指向保存数量为count的着色器源字符串的数组指针
length指向保存每个着色器字符串大小且元素数量为count的整数数组指针

3.指定着色器源代码之后,下一步是用glCompileShader编译着色器

void glCompileShader(GLuint shader)

shader需要编译的着色器对象句柄

调用glCompileShader将编译已经保存在着色器对象的着色器源代码。

glGetShaderiv查询这一信息和其他有关着色器对象的信息。


GLuint LoadShader( GLenum type,const char *shaderSrc){
GLuint shader;
GLint compiled;
shader = glCreateShader(type); 
if(shader == 0){
   return 0;
}
//Load the shader source
glShaderSource(shader,1,&shaderSrc,NULL);

//Compile the shader
glCompileShader(shader);

//Check the compile status
glGetShaderiv(shader,GL_COMPILE_STATUS,&compiled);

if(!compiled){
GLint infoLen = 0;
glGetShaderiv(shader,GL_INFO_LOG_LENGTH,&inforLen);
if(infoLen > 1){
char* infoLog = malloc(sizeof()*infoLen);
glGetShaderInfoLog(shader,infoLen,NULL,infoLog);
esLogMessage("Error comiling shader:\n%s\n",infoLog);
}
   glDeleteShader();
   return 0;
}

return shader;

2 创建和链接程序

程序对象时一个容器对象,可以将着色器与之连接,并链接一个最终的可执行程序》

函数说明
GLuint glCreateProgram()创建一个程序对象
void glDeleteProgram(GLuint program)删除一个程序对象
void glAttachShader(GLuint program, GLuint shader)连接着色器和程序
void glLinkProgram(GLuint program)生成最终的可执行文件
void glUseProgram(GLuint program)将程序对象设置为活动程序

在OpenGL ES 3.0中,每个程序对象必须连接一个顶点着色器和一个片段着色器。
着色器可以在任何时候连接,在连接到程序之前不一定需要编译,甚至可以没有源代码。唯一的要求是,每个程序对象必须有且只有一个顶点着色器和片段着色器与之连接。除了连接着色器之外,你还可以用glDetachShader断开着色器的连接。

一旦连接了着色器(并且着色器已经成功编译),就最终为链接着色器做好了准备。程序对象的链接用glLinkProgram完成。

链接操作负责生成最终的可执行程序。链接程序将检查各种对象的数量,确保成功链接。

链接程序之后,必须检查链接是否成功,可以使用glGetProgramiv检查链接状态
void glGetProgramiv(GLuint program,GLenum pname,GLint *params)

void glGetProgramInfoLog(GLuint program,GLsizei maxLength,
GLsizei * length,GLchar *infoLog )

在渲染之前,用glUseProgram将程序对象设置为活动程序

//Create the program object
programObject = glCreateProgram();

if(programObject == 0){
   return 0;
}

glAttachShader(programObject,vertexShader);
glAttachShader(programObject,fragmentShader);

//Link the program
glLinkProgram(programObject);
//Check the link status
glGetProgramiv(programObject,GL_LINK_STATUS,&linked);

if(!linked){
//Retrieve compiler error messages when linking fails
GLint infoLen = 0;
glGetProgramiv(programObject,GL_INFO_LOG_LENGTH,&infoLen);
if(infoLen > 1){
   char* infoLog = malloc(sizeof(char)*infoLen);
   glGetProgramInfoLog(programObject,infoLen,NULL,infoLog);
   esLogMessage("Error linking program:\n%s\n",infoLog);
   free(infoLog);
}
glDeleteProgram(programObject);
return FALSE;
}
//Use the program object
glUseProgram(programObject);


着色器编译器

编译器代码通常解析成某种中间表现形式。编译器必须将抽象表示形式转化为硬件的机器指令。理想状态下,这个编译器还应该进行大量的优化,如无用代码删除,常量传播等。

程序二进制码

程序二进制码是完全编译和链接的程序的二进制表现形式。因为可以保存到文件系统供以后使用,从而避免在线编译的代价,使用程序二进制码,就没有必要在实现中分发着色器源代码
OpenGL ES 规范不强制使用任何特定的二进制格式,相反,二进制格式完全取决于供应商。这意味着程序的可移植性较差。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值