OpenGL Insights
Cover Table of Contents Pipeline Map Tips Contributors Reviews BibTeX Errata Code Blog Buy

OpenGL Tips

OpenGL Insights includes short tips for OpenGL, OpenGL ES, and WebGL that were assembled by the contributors. We include the tips below.

If you would like to share your own tips on this page, please email them to editors@openglinsights.com. If they are selected, they will be posted here along with your name.

To the left of each tip, a combination of OpenGL, WebGL, and OpenGL ES tags identify what APIs the tip is relevant to.

OpenGL glCreateShaderProgram may provide faster build performance than a sequence of glCompilerShader and glLinkProgram. However, it only creates a single shader stage program.
OpenGL
WebGL
OpenGL ES
Not all shader objects need a main() function. Multiple shader objects can be linked together in the same program to allow sharing the same code between different programs.
OpenGL
WebGL
OpenGL ES
Build all GLSL shaders and programs first, and then query the results to hide build and query latency.
OpenGL
WebGL
OpenGL ES
Call glDeleteShader after attaching a shader to a program to simplify cleanup later.
OpenGL Five OpenGL 4.2 functions generate info logs:
  • glCompileShader
  • glCreateShaderProgram
  • glLinkProgram
  • glValidateProgram
  • glValidateProgramPipeline
OpenGL
OpenGL ES
Functions like glGenTextures do not create an object, they return a name for use with a new object. Objects are typically created with glBind* unless they are based on direct state access, in which case any other function may actually create the object.
OpenGL
WebGL
OpenGL ES
glGenerateMipmap may execute on the CPU, and therefore may be especially slow. Generate mipmaps offline or profile this function.
OpenGL
WebGL
OpenGL ES
When using the default texture scanline alignment, GL_PACK_ALIGNMENT, of four bytes, with glTexImage2D or glTexSubImage2D, the end of each row of pixel data may need to be padded to the next multiple of the alignment.
OpenGL Integer textures, GL_EXT_texture_integer, do not support filtering.
OpenGL A buffer texture is a 1D texture with a buffer object as storage which can only be fetched, not sampled.
OpenGL
WebGL
OpenGL ES
Unmap buffers as soon as possible to allow the driver to start the transfer or to schedule the transfer.
OpenGL
WebGL
OpenGL ES
Use buffer usage flags appropriately: COPY, GL to GL; DRAW, APP to GL; READ, GL to APP; STREAM, update always, DYNAMIC, update often, STATIC, update rarely.
OpenGL
WebGL
OpenGL ES
Set a GLSL sampler uniform to the texture unit number, not the OpenGL texture ID.
OpenGL
WebGL
OpenGL ES
glGetUniformLocation returns −1 but doesn’t generate an error if the uniform name does not correspond to an active uniform. All declared uniforms are not active; uniforms that do not contribute to the shader's output can be optimized out by the compiler.
OpenGL An OpenGL context must always be current for the duration of OpenGL/compute interoperability.
OpenGL An OpenGL object should not be accessed by OpenGL while it is mapped for usage within the compute portion.
OpenGL
WebGL
OpenGL ES
Avoid extraneous glBindFramebuffer calls. Use multiple attachments to a FBO rather than managing multiple FBOs.
OpenGL
WebGL
OpenGL ES
FBOs must always be validated before use to ensure that the selected format is renderable.
OpenGL Only one OpenGL query per query type, e.g., timer or occlusion, can be active at a time.
OpenGL For occlusion queries, using GL_ANY_SAMPLES_PASSED may be more effective than GL_SAMPLES_PASSED, as a rendering doesn't have to continue as soon as one fragment passed.
OpenGL
WebGL
OpenGL ES
For image-space rendering on GPUs with a large clipping guard band clipping, e.g., GeForce, Radeon, and PowerVR series 6 use a large clipped triangle instead of a quad. Measure both if in doubt.
OpenGL
WebGL
OpenGL ES
To test vertex throughput, do not render to a 1×1 viewport because parallelism is lost; instead, render outside of the view frustum.
OpenGL
WebGL
OpenGL ES
glGetError is particularly slow, especially in multi-process WebGL architectures. Only use it in debug builds or instead use GL_ARB_debug output when available.
OpenGL Geometry shaders are usually output bound so spending ALU time to reduce the amount of data output is a performance win.
WebGL In addition to #defining GL_OES_standard_derivatives before using dFdx, dFdy, and fwidth, also remember to call context.getExtension("OES standard derivatives") in JavaScript.
OpenGL
WebGL
OpenGL ES
To accurately compute the length of a gradient, avoid fwidth(v); instead use sqrt(dFdx(v) * dFdx(v) + dFdy(v) * dFdy(v)).
WebGL
OpenGL ES
highp is only available in fragment shaders if GL_FRAGMENT_PRECISION_HIGH is #defined. Beware of the performance implications of using highp in vertex or fragment shaders.
OpenGL In OpenGL, precision qualifiers were reserved in GLSL 1.20 and OpenGL 2.1 but actually introduced with GLSL 1.30 and OpenGL 3.0. From GLSL 1.40 and OpenGL 3.1, and for the purpose of convergence with OpenGL ES 2.0, GL_FRAGMENT_PRECISION_HIGH is defined as 1 in a fragment shader.
OpenGL By default, precision for vertex, tessellation, and geometry shader stages is highp for int types, and mediump for the fragment shader stage int types. This may lead to warnings on some implementations. float is always highp by default.
WebGL Given a WebGL context gl, gl.TRUE is undefined. When porting OpenGL or OpenGL ES code, do not change GL_TRUE to gl.TRUE because it will silently evaluate to false.
OpenGL
WebGL
OpenGL ES
Depth writes only occur if GL_DEPTH_TEST is enabled.
OpenGL
WebGL
OpenGL ES
The noise functions are still unimplemented in GLSL. Chapter 7 fixes this.
OpenGL gl_VertexID gets values in [first, first+count-1] when generated from a DrawArray* command, and not in [0, count-1]. Especially useful when using a zero input attributes vertex shader.
OpenGL There are two ways to work with point size: glPointSize in the client-side code or gl_PointSize in the GLSL code if PROGRAM_POINT_SIZE is enabled.