This site is for the first edition of the book covering OpenGL ES 2.0. If you are looking for the OpenGL ES 3.0 Programming Guide please visit http://www.opengles-book.com.
Errata
This page contains a list of all known errata from the book. Please report any errata to errors@opengles-book.comThe following errors were present in the first printing of the OpenGL ES 2.0 Programming Guide, but were fixed in the second printing.
- Page 21 - in Example 2-1, the parameters shaderSrc and shaderType are swapped in the function definition for LoadShader(). The function definition is correct in the sample code downloadable from the website (reported by Frederic Jacques).
- Page 39 - the function declaration for eglChooseConfig was misspelled eglChooseChofig (reported by Changsu Kim). Also, the type for numConfigs should be EGLint and not ELGint.
- Page 44 - EGL_FRONT_BUFFER should be EGL_SINGLE_BUFFER in Table 3-2 (reported by Johannes Vuorinen).
- Page 45 - eglCreatWindowSurface should be eglCreateWindowSurface.
- Page 47 - in the sentence "which indicates that that the pbuffer..." should only have one "that"
- Page 48 - in the sentence "This error occurs any of EGL_TEXTURE_FORMAT..." should read "This error occurs if any of EGL_TEXTURE_FORMAT...".
- Page 51 - the variable type for attribList should be EGLint and not ELGint
- Page 104 - the description for glVertexAttribPointer is missing a description of the const void *ptr parameter. It should read, "ptr - Pointer to the buffer holding vertex attribute data" (reported by Timo Finnil�).
- Page 113 - line 3 of the first paragraph of the new section it says glGetProgamiv. The "r" is missing, it should be glGetProgramiv (reported by Berk Ozer).
- Page 116 - in Example 6-4, there should be a comma after GLuint numIndices in the list of function parameters to initVertexBufferObjects(...).
- Page 122 and Page 123 - in Example 6-5 and Example 6-6, glBindAttribLocation() is called to bind generic attribute indices and then glDrawElements() is invoked. In order for these bindings to take effect, it is necessary to call glLinkProgram() before calling glDrawElements(). This call is missing from both examples in the book (reported by Greg Szober).
- Page 140 - glDepthRange should be glDepthRangef (reported by Johannes Vuorinen).
- Page 156 - "The code a_matrixweights[i] and a_matrixindices[i] highlighted in bold is not required to be supported and can therefore fail to compile." The variables are not in bold in the printed text (reported by Kouichi Matsuda).
- Page 162 - in Example 8-2, it is assumed (but not stated) that backface culling is enabled. If backface culling were not enabled, it would be necessary to to add the diffuse contribution only when ndotl is greater than 0. Likewise, on page 284, Example 13-1 also assumes that backface culling is enabled. Both of these examples take this shortcut in order to conserve shader instructions and reduce performance overhead. However, the text fails to mention this fact and thus the lighting equations appear incomplete (reported by Andrew J. Hanson).
- Page 162 - in Example 8-2, the function void directional_light(vec3 normal) should be vec4 direction_light(vec3 normal) (reported by Johannes Vuorinen).
- Page 220 - in the section Built-In Constants, the first bullet should read gl_MaxTextureImageUnits instead of gl_TextureImageUnits (reported by Berk Ozer).
- Page 246 - the blending equation provided in the Blending section has a typo where fdestination is mispelled fdestingation.
- Page 249 - In the second paragraph in the Multisampled Antialiasing section a sentence reads "What makes this process special .... about how many samples for a particular sample ..." The "particular sample" should be "particular pixel".
- Page 268 - the second bullet from the bottom of the page GL_FRAMEBUFFER_MISSING_ATTACHMENT should be GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT (reported by Joyce Wu)
- Page 291 - in Example 13-5, the last three lines of code should have been indented at the same level as the else case.
- Page 328 - the description for GL_STENCIL_WRITEMASK should read "Current write mask for front-facing polygons" and GL_STENCIL_BACK_WRITEMASK should read "Current write mask for back-facing polygons" (reported by Kouichi Matsuda).
- Page 345-346 - the Init() and Draw() function headers are mistakenly commented out in the printed text
- Page 365 - the description for cross() says the function returns a dot product. This function returns the cross product.
- Page 389 - in the description for esGenCube, TRIANGLES should be GL_TRIANGLES
- Page 390 - in the declaration for the ESMatrix typedef there is a missing "}"
- Page 394 - in the description for esMatrixMultiply the function returns the multiplied matrices, not the identity matrix.
- Several of the examples in the sample code pass GL_UNSIGNED_INT in to glDrawElements for the parameter "type", but this is only supported if the OES_element_index_uint extension is supported. The example code on the website for iPhone were update to use GL_UNSIGNED_SHORT (reported by Vidyasagar Gopireddy)
The following errors are present in the current printing of the OpenGL ES 2.0 Programming Guide:
- Page 19 - first paragraph, last sentence it reads: “There are number of concepts”. It should be “There are a number of concepts” (reported by Christopher Anderson - added 07/16/12).
- Page 24 - inside the main function, the statement esInitialize should instead be written esInitContext (reported by Robert Burnson - added 8/15/10).
- Page 26 - esInitialize should be esInitContext, where stated within the four line code snip, as well as the reference to it in the last paragraph(reported by Robert Burnson - added 8/16/10).
- Page 38 - the reference to function eglGetConfigAttribute should instead be eglGetConfigAttrib (reported by Daniel Kim - added 12/12/09).
- Page 39 - in the function declaration for eglChooseConfig, the type EGLDisplay is misspelled EGLDiplay (reported by Robert Burnson - added 8/15/10).
- Page 42 - the third line from the bottom, GL_NONE should be EGL_NONE (reported by Bill Rozzi - added 3/27/10).
- Page 43 - EGL_ALHPA_MASK_SIZE should be EGL_ALPHA_MASK_SIZE (added 07/16/12).
- Page 45 - in Example 3-4, the call to eglCreateWindowSurface() has its second and third parameters interchanged. Also, the second parameter should have been native_window, as currently window is used as both the EGLRenderSurface and NativeWindowType (reported Joonas It�ranta - added 7/26/09). Also, the code on line 6 of Example 3-4 should be "};" and not ");".
- Page 45 and 49 - in Example 3-4, the variable window should be declared of type EGLSurface and not EGLRenderSurface. This same error is present in Example 3-5 (reported by Joshua Ranjan - added 12/12/09).
- Page 50 - the second to last paragraph incorrectly states the context sharing will be discussed in Chapter 13 (reported by Dale Luck - added 07/16/12).
- Page 53 - in Example 3-7, the call to eglGetNativeDisplay() should be eglGetDisplay().
- Page 67 - under Uniforms and Attributes it says “there a number of queries” it should be “there are a number of queries” (reported by Christopher Anderson - added on 07/16/12)
- Page 80 - the last line of code should read myVec4 = vec4(myVec2, temp); // myVec4 = {myVec2.x, myVec2.y, temp.x, temp.y } (originally reported by Kouichi Matsuda - 12/12/09, corrected again by Josh Gargus and updated 07/16/12).
- Page 81 - fifth line after the heading "Vector and Matrix Components" it should read {s, t, p, q} instead of {s, t, r, q} (reported by Guenter Baszenski - added 07/16/12).
- Page 90 - the second to last line references "Chapter 6 on rasterization", this should be "Chapter 7 on rasterization" (reported by Oscar Alcantara, added 10/22/12).
- Page 95 - in Figure 5-1, M[0].x should be m[0].x. Also in the bottom right cell of Figure 5-1 it should read "-" instead of "-6" (reported by Kouichi Matsuda - added 12/12/09).
- Page 105 - in Example 6-1, the definition for #define VERTEX_ATTRIB_SIZE should be enclosed in parentheses. If it is not enclosed in parentheses, when the value is multiplied by sizeof(float) when passed to glVertexAttribPointer the result is incorrect (reported by Stephane Piquemal - added 07/16/12).
- Page 112 - on line 4, glGetProgamiv should be glGetProgramiv (reported by Domingo Gomez Maza - added 07/16/12).
- Page 120 - in Example 6-5, the calls to glBindAttribLocation() reference "v_position", "v_normal", and "v_texcoord". These should instead be "a_position", "a_normal", and "a_texcoord" (reported by Tan Zhiming - added 3/28/10).
- Page 123 - in Example 6-6, there is an error that will prevent the example from drawing anything. The calls to glBindVertexAttribPointer() need to be called after each call to glBindBuffer(). The example currently reads:
glBindBuffer(GL_ARRAY_BUFFER, vboIds[0]);
glEnableVertexAttribArray(VETEX_POS_INDX);
glBindBuffer(GL_ARRAY_BUFFER, vboIds[1]);
glEnableVertexAttribArray(VETEX_NORMAL_INDX);
glBindBuffer(GL_ARRAY_BUFFER, vboIds[2]);
glEnableVertexAttribArray(VETEX_TEXCOORD0_INDX);
glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE, vtxStrides[0], 0);
glVertexAttribPointer(VERTEX_NORMAL_INDX, VERTEX_NORMAL_SIZE, GL_FLOAT, GL_FALSE, vtxStrides[1], 0);
glVertexAttribPointer(VERTEX_TEXCOORD0_INDX, VERTEX_TEXCOORD0_SIZE, GL_FLOAT, GL_FALSE, vtxStrides[2], 0);
but it should be:
glBindBuffer(GL_ARRAY_BUFFER, vboIds[0]);
glEnableVertexAttribArray(VETEX_POS_INDX);
glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE, GL_FLOAT,
GL_FALSE, vtxStrides[0], 0);
glBindBuffer(GL_ARRAY_BUFFER, vboIds[1]);
glEnableVertexAttribArray(VETEX_NORMAL_INDX);
glVertexAttribPointer(VERTEX_NORMAL_INDX, VERTEX_NORMAL_SIZE, GL_FLOAT,
GL_FALSE, vtxStrides[1], 0);
glBindBuffer(GL_ARRAY_BUFFER, vboIds[2]);
glEnableVertexAttribArray(VETEX_TEXCOORD0_INDX);
glVertexAttribPointer(VERTEX_TEXCOORD0_INDX, VERTEX_TEXCOORD0_SIZE,
GL_FLOAT, GL_FALSE, vtxStrides[2], 0);
(reported by Michael Polster - added 3/27/10).
- Page 131 - in Figure 7-3, the 't' texture coordinate value shown in the diagram is increasing in the wrong direction (the text on the previous page describes it correctly). The top-left coordinate should be (0,0) and the bottom-right coordinate should be (1,1). The diagram has the t coordinate inverted (reported by otaku690 - added 12/30/10).
- Page 133 - the array indices defined for the cube at the bottom of page 133 do not have a consistent winding order resulting in some faces facing the inside of the cube. The correct index ordering would be as follows:
GLubyte indices[36] = {
0, 1, 2,
0, 2, 3,
0, 3, 4,
0, 4, 5,
0, 5, 6,
0, 6, 1,
7, 1, 6,
7, 2, 1,
7, 5, 4,
7, 6, 5,
7, 3, 2,
7, 4, 3
};
(thanks to Martin Kraus for reporting this error - added 8/15/10).
- Page 134 - "as seen in Figure 7-2" should read "as seen in Figure 7-5" (reported by Tan Zhiming - added 12/12/09).
- Page 135 - in the triangle strip example in the last paragraph, the index list and highlighted degenerate triangles were not correct. The index list should be (0, 1, 2, 3, 4, 4, 4, 8, 8, 9, 10, 11) and the list of triangle should be (0, 1, 2), (2, 1, 3), (2, 3, 4), (4, 3, 4), (4, 4, 4), (4, 4, 8), (4, 8, 8), (8, 8, 9), (8, 9, 10), (10, 9, 11) (reported by Tan Zhiming - added 12/12/09).
- Page 139 - the final word in the 3rd sentence of the section on "Clipping triangles" should read "against the appropriate planes" and not "...plans" (reported by Thomas Inzinga - added 08/15/10).
- Page 140 - there is an error in the equations given for ox and oy. The equations should read ox = x + w / 2 and oy = y + h / 2 rather than ox = (x + w) / 2 and oy = (y + h) / 2 (reported by Fisher Yu - added 8/15/10).
- Page 170 - There are two errors in the skin_normal function in Example 8-6 on page 170. The first problem is that the argument out vec3 skinned_normal should be qualified with inout rather than out. The second error is that the last line should read skinned_normal += m_wt * tmp; rather than using skinned_position (reported by Kouichi Matsuda - added 12/12/09).
- Page 174 - the variable named inv_modelview_matrix in Example 8-8 was not given the correct name. This variable is supposed to be the equivalent of the fixed-function gl_NormalMatrix which is in fact the inverse transpose of the upper 3x3 of the modelview matrix (not just the inverse). For clarity, this variable should either be named normal_matrix or inv_transpose_modelview_matrix (reported by Luu Bach Tan - added 12/30/10).
- Page 176 - The declaration of vec3 VPpli should be above the if statement, not embedded in it. The way it is currently written, there is no declaration in scope for the instance of VPpli in the "else" portion of the statement. You end up with an undefined identified (reported by Stephen Kavanagh - added 3/27/10).
- Page 178 - the GLSL syntax doesn't recognize c-style type casts. "j = (int)c_zero;" should be changed to "j = int(c_zero);". Also, in the loop just below that instead of "for (i=(int)c_zero; i<8; i++)" it should be "for(i=int(c_zero); i<8; i++)" (reported by Stephen Kavanagh and Jonathan E. F. Fulkerson - added 3/27/10).
- Page 197 - on line 4, the reference to glGetIntegeriv should have been glGetIntegerv (reported by Thibault Jochem - added 12/12/09.)
- Page 198 - in Example 9-4, the comments describing the faces in GLubyte cubePixels[6][3] = ... are mislabeled for Face 3 -> 6. They should be Face 2 - > 5 (reported by Kouichi Matsuda - added 12/12/09).
- Page 206 and 212 - glCopyTexSubImage2D and glCopyTexSubImage3DOES list the GLint level parameter twice (reported by Changsu Kim - added 7/26/09).
- Page 213 - the references to the token GL_FLOAT_OES should be GL_FLOAT. There is no GL_FLOAT_OES token (reported by Stephane Lenclud - added 8/15/10).
- Page 226 and 227 - the linear fog equation provided in the book does not match the traditional fixed-function fog equation exactly. It should be gl_FragColor = baseColor * fogFactor + u_fogColor * (1.0 - fogFactor); (reported by Thibault Jochem - added 12/12/09).
- Page 230 - in Example 10-5 the name of u_clipDist should be v_clipDist since it is a varying not a uniform (reported by Kouichi Matsuda - added 12/12/09).
- Page 251 - in the code the variables GLenum readType, readFormat; should instead be GLint readType, readFormat; (reported by G.J.W. van den Braak - added 07/16/12).
- Page 265 and 266 - in the descriptions for glFramebufferTexture2D and glFrameBufferTexture3DOES the parameter being described should be target rather than textarget (reported by Kouichi Matsuda - added 12/12/09).
- Page 276 - in Example 12-2, the last three lines of cleanup code at the end of the example are incorrect. The glDeleteRenderBuffers() call should be removed and the call to glDeleteTextures(1, &texture) should be glDeleteTextures(2, textures) (reported by Kouichi Matsuda - added 12/12/09).
- Page 295 and Particle_System (sample code) - in the sample code for the particle system in Chapter 13, the code calls glEnable(GL_TEXTURE2_2D) which will generate an error. While the example code will still work, this is not correct (reported by David Kvasnica - added 8/15/10).
- Simple_Texture2D example - the texture coordinates in this example put the lower-left corner of the 2D texture at the upper-left corner of the polygon such that the texture is rendered upside-down. The texture coordinates need to be flipped in the y-direction in order to not flip the texture upside down (reported by Guiseppe Maione - added 12/12/09).
- Page 362-363 - the function definitions for clamp and mix are incorrect. All of the clamp functions should take a third argument "maxVal". All of the mix functions should take a third argument "a". The type of "maxVal" or "a" can be either the same type as the first two arguments or a float (originally reported as fixed in second printing, but we missed it. Thanks Jeff Paciga for reporting this - added 3/27/10).
- Page 362-364. There are duplicate entries for each of the mod, min, max, clamp, step, and smoothstep common functions (reported by Thomas Inzinga - added 8/15/10).
- Color Plate 3 - "Her shadow that is cast onto the ground..." should be "Her shadow is cast onto the ground..." (reported by Robert Burnson - added 12/30/10).