iOS开发-OpenGLES 入门的大杂烩

熊猫镇楼

理解下上图的元素,总共有6个顶点,一张贴图。

纹理贴上去的规则是什么?

每个顶点都有纹理坐标,按照纹理坐标对应在图片上面有一个点,三个点形成一个三角形,从纹理(图片)上面切下来。

 

点积几何意义其实就是表示两个向量之间夹角的 cos 值
dot也是GLSL内置的函数提供向量的点乘, normalize也是内置函数。
 
 
 
 
正如你在vertex shader中必须设置gl_Position, fragment shader中必须设置gl_FragColor.
gl_Position 是一个内建的传出变量。这是一个在 vertex shader中必须设置的变量。
gl_Position — contains the position of the current vertex
 
 
glDrawElements
GL_ELEMENT_ARRAY_BUFFER
 glDrawArrays 和 glDrawElements 的作用都是从一个数据数组中提取数据渲染基本图元。( render primitives from array data )
 
 

 

表示顶点可以用 (x、y、z、w)

表示颜色可以用 (r、g、b、a)

表示纹理坐标用 (s、t、p、q)

 
glActiveTexture(GL_TEXTURE0);
glBindTexture(tex0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(tex1);
 
对应shader:
        "uniform sampler2D sTexture2;\n" 
        "uniform sampler2D sTexture1;\n" 
为uniform赋值的时候
l = glGetUniformLocation(u, "sTexture1");
glUniform1i(l, 0);// 代表GL_TEXTURE0
l = glGetUniformLocation(u, "sTexture2");
glUniform1i(l, 1);

这样使用sTexture1的时候用的就是tex0,使用sTexture2的时候用的就是tex1。

 
第一个参数决定你使用哪一个采样器进行纹理采样。每个采样器有自己的一套状态,例如绑定纹理过滤参数什么的
通过texture2D函数我们可以得到一个纹素(texel),这是一个纹理图片中的像素。函数参数分别为simpler2D以及纹理坐标:
函数的返回值已经考虑了所有在OpenGL程序中定义的纹理设置,比如过滤、mipmap、clamp等
 

颜色缓冲区

  颜色缓冲区(COLOR_BUFFER)就是帧缓冲区(FRAME_BUFFER),你需要渲染的场景最终每一个像素都要写入该缓冲区,然后由它在渲染到屏幕上显示.

深度缓冲区

  深度缓冲区(DEPTH_BUFFER)与帧缓冲区对应,用于记录上面每个像素的深度值,通过深度缓冲区,我们可以进行深度测试,从而确定像素的遮挡关系,保证渲染正确.

模板缓冲区

  模版缓冲(STENCIL_BUFFER)与深度缓冲大小相同,通过设置模版缓冲每个像素的值,我们可以指定在渲染的时候只渲染某些像素,从而可以达到一些特殊的效果.
 
 
glBufferData函数执行向所绑定的缓冲区写入数据的操作,target参数是枚举类型,只能取预设的几个值,该参数用来指定缓冲区类型,而不是内存地址。
执行渲染操作的时候,也是先绑定某个缓冲区,然后调用适当的函数,从该缓冲区某个指定偏移量开始,取一定量的数据进行指定方式的渲染。渲染过程是由程序控制GPU完成的,不是说你把数据写入缓冲区之后,显卡自己就知道要显示什么了。
由于OpenGL制定的是C语言接口,而C不是面向对象的,所以封装性和可读性比较差,需要以C这种面向过程的思维方式来理解OpenGL。程序里每个函数都不能孤立地看,都要看它的上下文,比如上文中绑定了某个缓冲区,那么接下来的操作就是针对这个缓冲区的。
 
OC代码
    GLuint position = glGetAttribLocation(self.myProgram, "position3");
    position = glGetAttribLocation(self.myProgram, "position");
    position = glGetAttribLocation(self.myProgram, "position3");
    position = glGetAttribLocation(self.myProgram, "position2");
    position = glGetAttribLocation(self.myProgram, "position1");
    position = glGetAttribLocation(self.myProgram, "position");
 
 
glsl文件
attribute vec4 position;
attribute vec4 position1;
attribute vec4 position2;
attribute vec4 position3;

void main()
{
    gl_Position = position3 + vec4(0.1, 0.1, 0.1, 0);
    gl_Position = position2 + vec4(0.1, 0.1, 0.1, 0);
//    gl_Position = position1 + vec4(0.1, 0.1, 0.1, 0);
    gl_Position = position + vec4(0.1, 0.1, 0.1, 0);
}

position的数值,如果有用到那么会那么会有对应的顶点的编号;如果没用到(position1),那么返回值为-1.

 

If you are reusing the same data in multiple frames, using glBufferData as part of your setup/initialization will transfer data from the CPU to the GPU only once. Whereas glVertexAttribPointer must be called every frame, so using it to transfer data results in using a lot more bus bandwidth.

If you're updating the attribute array every frame, there's not much advantage one way or the other.

 
Drawing (via glDraw[Elements|Arrays]) will read from the pointer previously supplied by glVertexAttribPointer if no buffer is bound (client memory).
It will read from the buffer if one is bound, treating the glVertexAttribPointer pointer argument as an offset into the buffer. Drawing from a buffer that has not been initialized is obviously not defined.
 
glBufferData只会把数据从CPU传向GPU一次。
drawing函数会读glVertexAttribPointer提供的顶点数据(如果没有buffer);
如果buffer存在,那么pointer会被认为是offset,从buffer读取数据;
 
 

顶点属性就是顶点shader里面声明的一个attribute变量,有两种类型的attribute变量,一种是const属性,一种是顶点属性数组 

 
 

posted on 2016-03-17 16:15  loying  阅读(398)  评论(0编辑  收藏  举报

导航