加载着色器程序:
参考链接:
https://juejin.cn/post/7134356782452834334
对应于代码实现:
ps:一个是着色器对象,表示一段具体的着色器代码的抽象,另一个是着色器程序,表示整个图形渲染管线的着色器程序集合
initShader(vertexSimpleShape, GL_VERTEX_SHADER);
initShader(fragSimpleShape, GL_FRAGMENT_SHADER):创建着色器对象,加载着色器代码到对应的着色器对线上面,编译着色器对象
glCreateProgram();:创建程序Program对象
glAttachShader(program, vsh);:绑定着色器对象到Program程序对象上(attach)
glLinkProgram(program);:链接着色器到程序上
glGetProgramiv(program, GL_LINK_STATUS, &status);:打印链接异常信息
glUseProgram(program);:使用程序Program(这步就意味着渲染流程管线被激活,可以使用具体的着色器代码进行编辑了)
具体流程
创建着色器加载着色器代码编译着色器对象
initShader方法中接受两个参数,一个是source代表着色器代码,一个是type代表创建的着色器类型是什么
其包含glCreateShader,glShaderSource,glShaderSource,glGetShaderiv四个方法
glCreateShader:创建着色器对象,type表示着色器类型,比如顶点着色器为GL_VERTEX_SHADER,片段着色器为GL_FRAGMENT_SHADER。返回值为一个类似引用的数字。
ps:拿到这个引用整数,就犹如将绑着该着色器对象的绳子牢牢抓住,以后只要操控着色器对象,就靠这根绳子。
glShaderSource:着色器对象加载着色器对象代码source,可指定多个source着色器代码
ps:此时的着色器对象还是空的,只是一个壳,所以我们需要通过glShaderSource方法将着色器代码注入进去。
glCompileShader:编译着色器对象
ps:代码注入进去了,就要类似C程序一样需要一个编译过程,用的是glCompileShader方法。
glGetShaderiv:打印出编译异常信息
ps:当然有编译就有可能有编译错误,由于着色器程序是在GPU中编译运行的,所以目前并不像我们平时写在CPU运行的程序那样有详细的编译错误信息以及可以断点调试这些高端操作,但是至少还是可以通过glGetShaderiv方法看到一些报错信息的。
创建程序Program对象
通过glCreateProgram方法创建一个着色器程序对象。
glAttachShader(program, vsh)
此时着色器程序对象还是空空如也,所以需要glAttachShader方法,将前面创建的着色器对象关联给它,它才是一个有实质内容的着色器程序对象。
glLinkProgram(program)
此时着色器程序还是没有真正和我们的OpenGL程序关联上,所以需要通过glLinkProgram方法链接着色器程序,类似我们C语言程序链接一个动态链接库一样,去关联上。
glGetProgramiv(program, GL_LINK_STATUS, &status)
当然,链接可能会发生异常,所以通过glGetProgramiv方法打印异常信息
glUseProgram(program)
名正言顺宣告 ,该着色器程序将被当前OpenGL程序使用。
到这里就代表着色器被激活了,该是用着色器了,接下来就和状态机相关了,可以对着色器进行操作