1. attribute不可以定义为结构和数组,只支持如下数据类型:
float, vec2,
vec3, vec4, mat2, mat3, and mat4.
2. 除了用客户端数组指定顶点数据,可以用VBO指定,如何确定哪个VBO对应哪个attribute,书中没有给出明确文字
应该是执行glBindBuffer(GL_ARRAY_BUFFER, vboIds[0]);绑定到一个buffer 数组时,执行glEnableVertexAttribArray(VERTEX_POS_INDX);这样VERTEX_POS_INDX指定的attribute就合当前绑定的VBO关联起来。后面再通过函数glVertexAttribPointer,指定VBO中数据的偏移值。
3.可以使用glMapBufferOES来映射VBO在显卡的内存到手机内存中,然后通过修改该函数返回的指针数据,从而修改了VBO的数据。如果该VBO中数据正要被用于写到显示频上,则该函数会等待。这样效率会很低。有一个方法可以避免,先调用glBufferData(null),告诉GL状态机该VBO中数据已无用,再执行glMapBufferOES
4. 指定Point sprite的坐标时,坐标原点是在左上角,而不是通常的左下角
5. glDrawElements 使用VBO无需做多余操作,只需要在调用该函数之前已绑定数据,该函数最好一个参数传0即可
6. gl_PointCoord是一个内建变量,用于fragment shader, 类型为vec2,当它的值从0.0到1.0变化时,对应的坐标是从左到右,或者从下到上变化,演示代码:
uniform sampler2D s_texSprite;
void
main(void)
{
gl_FragColor = texture2D(s_texSprite, gl_PointCoord);
}
7.只支持两种Drawing Primitives:glDrawArrays, glDrawElements
8. 坐标变换顺序,局部坐标经过vertex shader的modelview matrix变换,perspective matrix变换后生成裁剪坐标,所谓裁剪,意思是如果vertex的坐标不在perspective matrix定义的6面体内,将会把该点删除。裁剪坐标再经过透视除尘(Perspective Division)变换,生成规范化设备坐标,(normalized device coordinates),变换过程为裁剪坐标(xc, yc, zc, wc)变为(xc/wc), (yc/wc),(zc/wc),所谓normalized,应该就是让坐标除以Wc,书中说变换后的坐标位于[–1.0 … 1.0],这个不太理解,照理通常情况下Wc始终为1,除以该值后不应该规范到[–1.0 … 1.0]之间才对, 这之后进行视口变换(Viewport Transformation),该变换所需参数是通过函数glViewport(GLint x, GLint y, GLsizei w, GLsizei h),glDepthRange(GLclampf n, GLclampf f)传入,变换的数学公式为
xw = (w / 2)xd + ox
yw = (h / 2)yd + oy
zw = ((f – n) / 2)zd + (n + f) / 2
其中ox = (x + w)/2,oy = (y + h)/2, n, f代表glDepthRange传入的值。变换不难理解,ox代表x方向的原点位置坐标,xd是-1.0到1.0之间的值,(w / 2)xd 正好是-w/2到w/2之间的值
上面描述的整个过程称为Primitive Assembly。
9. primitive assmbly之后进行Rasterization,即把vertex shader中画出来的图形转换为一个个像素
这个阶段会执行culling face. 和Polygon Offset, culling face 用于去掉那些看不见的三角形,提高性能, Polygon Offset用于防止两个图形由于深度值 的误差 而在光栅化的时候部分地方重合,这个被称为Z-fighting artifacts, 是因为在光栅化是只能保留浮点数的一部分位数导致片段的深度值误差。如何使用:
const float polygonOffsetFactor = -1.0f;
const float polygonOffsetUnits = -2.0f;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// load vertex shader
// set the appropriate transformation matrices
// set the vertex attribute state
// draw the RED triangle
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
// set the depth func to <= as polygons are coplanar
glDepthFunc(GL_LEQUAL);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(polygonOffsetFactor, polygonOffsetUnits);// set the vertex attribute state
// draw the GREEN triangle
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);