<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7705158385874906782</id><updated>2012-01-30T20:47:55.084-08:00</updated><category term='buffers'/><category term='antialiasing'/><category term='Shaders'/><category term='multiple draw buffers'/><category term='framebuffer object'/><category term='texture'/><category term='render to texture'/><category term='FBO'/><category term='pixel buffer object'/><category term='attributes'/><category term='optimization'/><category term='format'/><category term='version'/><category term='vertex'/><category term='fragment'/><title type='text'>OpenGL Tip of the Day</title><subtitle type='html'>A collection of handy tips on using OpenGL</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ogltotd.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ogltotd.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Alex Scarborough</name><uri>http://www.blogger.com/profile/00587680319916164177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>11</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7705158385874906782.post-2159840984001994734</id><published>2007-12-29T01:39:00.000-08:00</published><updated>2007-12-29T01:52:43.020-08:00</updated><title type='text'>Default Uniform Values</title><content type='html'>In GLSL 1.10 all uniforms are assigned a default value of 0 when a program is successfully linked.  In GLSL 1.20 all uniforms, except for samplers, can have an initializer, like so:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;uniform vec3 color = vec3(0.7, 0.7, 0.2);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All uniforms without initializers are assigned a default value of 0.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;References:&lt;/div&gt;&lt;div&gt;GLSL 1.20 specification, p. 24&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7705158385874906782-2159840984001994734?l=ogltotd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ogltotd.blogspot.com/feeds/2159840984001994734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7705158385874906782&amp;postID=2159840984001994734' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/2159840984001994734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/2159840984001994734'/><link rel='alternate' type='text/html' href='http://ogltotd.blogspot.com/2007/12/default-uniform-values.html' title='Default Uniform Values'/><author><name>Alex Scarborough</name><uri>http://www.blogger.com/profile/00587680319916164177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7705158385874906782.post-4266738005460371138</id><published>2007-12-27T11:37:00.000-08:00</published><updated>2007-12-27T17:29:40.231-08:00</updated><title type='text'>Active Shader Uniforms and Vertex Attributes</title><content type='html'>A uniform is only active if the GLSL compiler and/or linker determine that it is used in the shader, or cannot conclusively determine that it is not used in the shader.  As an example, in the following shader pair &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;foo&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;rex&lt;/span&gt;, and &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;gl_LightModel.ambient&lt;/span&gt; are the only active uniforms.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;[vertex]&lt;br /&gt;uniform vec4 foo, bar, baz, rex;&lt;br /&gt;varying vec4 var;&lt;br /&gt;void main()&lt;br /&gt;{&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   var = rex;&lt;br /&gt;   gl_Position = foo;&lt;br /&gt;}&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;[fragment]&lt;br /&gt;uniform vec4 color, size, rex, throwaway;&lt;br /&gt;varying vec4 var;&lt;br /&gt;void main()&lt;br /&gt;{&lt;br /&gt;   gl_FragColor = (rex + var) * gl_LightModel.ambient;&lt;br /&gt;}&lt;/span&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In this more complex example &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;posMod&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;baz&lt;/span&gt; are the only active uniforms.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;[vertex]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;uniform vec4 v_color, posMod, foo, bar;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;varying vec4 colMod;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;void main()&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;   &lt;/span&gt;colMod = v_color * gl_Vertex;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;   &lt;/span&gt;gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex + posMod;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;[fragment]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;uniform vec4 f_color, rex, baz;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;varying vec4 colMod;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;void main()&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   vec4 finalColor = f_color * colMod;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   finalColor += rex;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   gl_FragColor = baz;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Even though &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;v_color&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;f_color&lt;/span&gt;, and &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;rex&lt;/span&gt; are all used in the code as written they do not have any affect on the final vertex position or fragment color.  As such, a good GLSL compiler/linker will determine that they are unused.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Vertex attributes have similar rules.  In order to be considered active they must in some way affect the final vertex position or fragment color.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This differentiation between active and inactive can be important, especially if you are dealing with procedurally generated shaders.  Only active uniforms and attributes count towards implementation defined limits.  That is, if your implementation has a limit of 16 vertex attributes you can still declare more than 16 as long as 16 or fewer actually affect the final vertex position or fragment color.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;References:&lt;/div&gt;&lt;div&gt;OpenGL 2.1 Specification (12/01/2006) pp. 76-79&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7705158385874906782-4266738005460371138?l=ogltotd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ogltotd.blogspot.com/feeds/4266738005460371138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7705158385874906782&amp;postID=4266738005460371138' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/4266738005460371138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/4266738005460371138'/><link rel='alternate' type='text/html' href='http://ogltotd.blogspot.com/2007/12/active-shader-uniforms-and-vertex.html' title='Active Shader Uniforms and Vertex Attributes'/><author><name>Alex Scarborough</name><uri>http://www.blogger.com/profile/00587680319916164177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7705158385874906782.post-125741883147950984</id><published>2006-12-12T20:15:00.000-08:00</published><updated>2006-12-12T20:17:43.762-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FBO'/><category scheme='http://www.blogger.com/atom/ns#' term='multiple draw buffers'/><category scheme='http://www.blogger.com/atom/ns#' term='framebuffer object'/><title type='text'>Rendering to multiple textures</title><content type='html'>To render to multiple textures, you still use the &lt;span style="font-family: courier new;"&gt;glDrawBuffers&lt;/span&gt; function.   However, you use the enums from &lt;a href="http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt"&gt;GL_EXT_framebuffer_object&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;glDrawBuffers(2, buffers);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If a framebuffer object is bound with textures attached to &lt;span style="font-family: courier new;"&gt;GL_COLOR_ATTACHMENT0_EXT&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;GL_COLOR_ATTACHMENT1_EXT&lt;/span&gt;, they will both be rendered to now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7705158385874906782-125741883147950984?l=ogltotd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ogltotd.blogspot.com/feeds/125741883147950984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7705158385874906782&amp;postID=125741883147950984' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/125741883147950984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/125741883147950984'/><link rel='alternate' type='text/html' href='http://ogltotd.blogspot.com/2006/12/rendering-to-multiple-textures.html' title='Rendering to multiple textures'/><author><name>Alex Scarborough</name><uri>http://www.blogger.com/profile/00587680319916164177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7705158385874906782.post-3955697420717576746</id><published>2006-12-11T21:19:00.001-08:00</published><updated>2006-12-11T21:19:23.374-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='buffers'/><category scheme='http://www.blogger.com/atom/ns#' term='Shaders'/><category scheme='http://www.blogger.com/atom/ns#' term='multiple draw buffers'/><title type='text'>Rendering to multiple buffers</title><content type='html'>Rendering to multiple buffers, known as MRT to the Direct3D world, can be accomplished with the GL_ARB_draw_buffers extension.  Using this extension is incredibly simple.  For example, to draw to the back and AUX0 buffers simultaneously, you would use the following code:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;GLenum buffers[] = { GL_BACK, GL_AUX0 };&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;glDrawBuffersARB(2, buffers)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And there you have it.&lt;br /&gt;&lt;br /&gt;Of course, this is rather dull unless we can actually write different colors to different buffers.  In order to do this, shaders must be used.  In GLSL, you can select which buffer is written to by writing to gl_FragData[n] in place of gl_FragColor.  If you are using GL_ARB_fragment_program, you can select which buffer is written to by writing to result.color[n].&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.opengl.org/registry/specs/ARB/draw_buffers.txt"&gt;GL_ARB_draw_buffers specification&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7705158385874906782-3955697420717576746?l=ogltotd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ogltotd.blogspot.com/feeds/3955697420717576746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7705158385874906782&amp;postID=3955697420717576746' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/3955697420717576746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/3955697420717576746'/><link rel='alternate' type='text/html' href='http://ogltotd.blogspot.com/2006/12/rendering-to-multiple-buffers.html' title='Rendering to multiple buffers'/><author><name>Alex Scarborough</name><uri>http://www.blogger.com/profile/00587680319916164177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7705158385874906782.post-1665149138641522886</id><published>2006-12-10T15:50:00.001-08:00</published><updated>2006-12-10T15:50:52.073-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='texture'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><category scheme='http://www.blogger.com/atom/ns#' term='pixel buffer object'/><title type='text'>Streaming texture updates</title><content type='html'>It is possible to stream updates to a texture, often skipping a costly data copy, using the GL_ARB_pixel_buffer_object extension which was promoted to core in OpenGL 2.1&lt;br /&gt;&lt;br /&gt;To do this, you must bind a buffer to GL_PIXEL_UNPACK_BUFFER_ARB, map it, write your texture data into the mapped buffer, unmap it, and call glTexSubImage2D referencing into the buffer.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// Bind buffer&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, myBuffer);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// Null existing data&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, width * height * bytesPerPixel, NULL, GL_STREAM_DRAW);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// Map buffer.  Returns pointer to buffer memory&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;void *pboMemory = glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;writeImage(pboMemory); // Writes data into pboMemory&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// Unmaps buffer, indicating we are done writing data to it&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, (char *)NULL);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// Unbind buffer&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Normally the driver must copy the data you pass into glTexSubImage2D.  However, by storing the data in a buffer, which is memory managed by the driver, we can avoid this copy.  Furthermore, by using a universally hardware accelerated texture format (see &lt;a href="http://ogltotd.blogspot.com/2006/12/what-is-optimal-32-bit-texture-format.html"&gt;this&lt;/a&gt; tip) we prevent any data processing, ensuring the fastest possible download to the GPU.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.opengl.org/registry/specs/ARB/pixel_buffer_object.txt"&gt;GL_ARB_pixel_buffer_object specification&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7705158385874906782-1665149138641522886?l=ogltotd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ogltotd.blogspot.com/feeds/1665149138641522886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7705158385874906782&amp;postID=1665149138641522886' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/1665149138641522886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/1665149138641522886'/><link rel='alternate' type='text/html' href='http://ogltotd.blogspot.com/2006/12/streaming-texture-updates.html' title='Streaming texture updates'/><author><name>Alex Scarborough</name><uri>http://www.blogger.com/profile/00587680319916164177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7705158385874906782.post-7472085373511767506</id><published>2006-12-09T10:32:00.001-08:00</published><updated>2006-12-09T10:32:56.655-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Shaders'/><category scheme='http://www.blogger.com/atom/ns#' term='attributes'/><category scheme='http://www.blogger.com/atom/ns#' term='vertex'/><title type='text'>Setting vertex attribute locations</title><content type='html'>While you can query the location of a generic vertex attribute in a GLSL shader by calling &lt;span style="font-family: courier new;"&gt;glGetAttribLocation(GLuint program, const GLchar *name)&lt;/span&gt;, you can also set the location of a generic vertex attribute manually using &lt;span style="font-family: courier new;"&gt;glBindAttribLocation(GLuint program, GLuint index, const GLchar *name)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;NOTES:  Manually set attribute locations do not take effect until &lt;span style="font-family: courier new;"&gt;glLinkProgram(GLuint program)&lt;/span&gt; is called.  &lt;br /&gt;&lt;br /&gt;You cannot manually assign a location to a built in vertex attribute (e.g. gl_Vertex).&lt;br /&gt;&lt;br /&gt;It is possible to assign the same location to multiple attributes.  This process is known as aliasing, and is only allowed if just one of the aliased attributes is active in the executable program.  HOWEVER the implementation is not required to check for aliasing and is free to employ optimizations that only work in the abscence of aliasing.&lt;br /&gt;&lt;br /&gt;Any vertex attribute which is not manually assigned a location will be assigned one by the linker, and this location can be queried with &lt;span style="font-family: courier new;"&gt;glGetAttribLocation(GLuint program, const GLchar *name)&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;a href="http://developer.3dlabs.com/documents/GLmanpages/glBindAttribLocation.htm"&gt;glBindAttribLocation man page&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7705158385874906782-7472085373511767506?l=ogltotd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ogltotd.blogspot.com/feeds/7472085373511767506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7705158385874906782&amp;postID=7472085373511767506' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/7472085373511767506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/7472085373511767506'/><link rel='alternate' type='text/html' href='http://ogltotd.blogspot.com/2006/12/setting-vertex-attribute-locations_09.html' title='Setting vertex attribute locations'/><author><name>Alex Scarborough</name><uri>http://www.blogger.com/profile/00587680319916164177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7705158385874906782.post-1499692470547567991</id><published>2006-12-07T16:09:00.000-08:00</published><updated>2006-12-08T14:37:10.216-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='render to texture'/><category scheme='http://www.blogger.com/atom/ns#' term='FBO'/><category scheme='http://www.blogger.com/atom/ns#' term='framebuffer object'/><title type='text'>Render to Texture</title><content type='html'>OpenGL supports fast crossplatform offscreen rendering through the GL_EXT_framebuffer_object extension.&lt;br /&gt;&lt;br /&gt;To render to a texture using the framebuffer object you must&lt;br /&gt;&lt;br /&gt;1) Create a framebuffer object    &lt;span style="font-size:100%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;glGenFramebuffersEXT(1, &amp;myFBO);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;2) Bind the framebuffer object    &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, myFBO);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;3) Attach a texture to the FBO     &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, myTexture, 0);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;4) If you need depth testing, create and attach a depth renderbuffer  &lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// Gen renderbuffer&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;glGenRenderbuffersEXT(1, &amp;myRB);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;// Bind renderbuffer&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, myRB);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;// Init as a depth buffer&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;// Attach to the FBO for depth&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, myRB); &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;5) Render just like you normally would.&lt;br /&gt;&lt;br /&gt;6) Unbind the FBO (and renderbuffer if necessary).  &lt;span style="font-family:courier new;"&gt;glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;7) Use the texture you rendered to!&lt;br /&gt;&lt;br /&gt;NOTES:&lt;br /&gt;&lt;br /&gt;All textures and renderbuffers attached to the framebuffer object must have the same dimensions.&lt;br /&gt;&lt;br /&gt;You must use the &lt;a href="http://www.opengl.org/registry/specs/EXT/packed_depth_stencil.txt"&gt;GL_EXT_packed_depth_stencil&lt;/a&gt; extension to use stencil testing with framebuffer objects.&lt;br /&gt;&lt;br /&gt;You can only render to RGB, RGBA, and depth textures using framebuffer objects.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt"&gt;Framebuffer object specification&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7705158385874906782-1499692470547567991?l=ogltotd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ogltotd.blogspot.com/feeds/1499692470547567991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7705158385874906782&amp;postID=1499692470547567991' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/1499692470547567991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/1499692470547567991'/><link rel='alternate' type='text/html' href='http://ogltotd.blogspot.com/2006/12/render-to-texture.html' title='Render to Texture'/><author><name>Alex Scarborough</name><uri>http://www.blogger.com/profile/00587680319916164177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7705158385874906782.post-6438970071466132695</id><published>2006-12-07T12:34:00.000-08:00</published><updated>2006-12-07T23:21:16.868-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='version'/><category scheme='http://www.blogger.com/atom/ns#' term='Shaders'/><category scheme='http://www.blogger.com/atom/ns#' term='fragment'/><category scheme='http://www.blogger.com/atom/ns#' term='vertex'/><title type='text'>Checking for a D3D shader version</title><content type='html'>Direct3D's shader version (1.1, 1.4, 2.0, 3.0, 4.0) is a very useful way to keep track of what shaders can execute on what hardware.  While OpenGL does not provide a direct way to acquire this number, it is still possible to determine a shader model based on certain OpenGL extensions.&lt;br /&gt;&lt;br /&gt;If a card supports GL_ARB_vertex_program and/or GL_ARB_vertex_shader, it supports vertex shader 1.1.&lt;br /&gt;&lt;br /&gt;If a card supports GL_NV_texture_shader and GL_NV_register_combiners, it supports pixel shader 1.1.&lt;br /&gt;&lt;br /&gt;If a card supports GL_ATI_fragment_shader or GL_ATI_text_fragment_shader it supports pixel shader 1.4.&lt;br /&gt;&lt;br /&gt;If a card supports GL_ARB_fragment_program and/or GL_ARB_fragment_shader it supports Shader Model 2.0.&lt;br /&gt;&lt;br /&gt;If a card supports GL_NV_vertex_program3 or GL_ATI_shader_texture_lod it it supports Shader Model 3.0.&lt;br /&gt;&lt;br /&gt;If a card supports GL_EXT_gpu_shader4 it is a Shader Model 4.0 card. (Geometry shaders are implemented in GL_EXT_geometry_shader4)&lt;br /&gt;&lt;br /&gt;NOTE: In Mac OS 10.4.3 and later, all GPUs report support for GL_ARB_fragment_shader and GL_ARB_vertex_shader even if they do not support this extension in hardware.  To determine if these extensions are hardware accelerated, call &lt;span style="font-family: courier new;"&gt;CGLGetParameter(kCGLCPGPUFragmentProcessing)&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;CGLGetParameter(kCGLCPGPUVertexProcessing)&lt;/span&gt;, repsectively.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lists.apple.com/archives/mac-opengl/2006/Aug/msg00133.html"&gt;Mac OpenGL mailing list&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7705158385874906782-6438970071466132695?l=ogltotd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ogltotd.blogspot.com/feeds/6438970071466132695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7705158385874906782&amp;postID=6438970071466132695' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/6438970071466132695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/6438970071466132695'/><link rel='alternate' type='text/html' href='http://ogltotd.blogspot.com/2006/12/checking-for-d3d-shader-version.html' title='Checking for a D3D shader version'/><author><name>Alex Scarborough</name><uri>http://www.blogger.com/profile/00587680319916164177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7705158385874906782.post-5630529292227342062</id><published>2006-12-06T22:15:00.000-08:00</published><updated>2006-12-07T16:50:09.542-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='antialiasing'/><title type='text'>Setting up Antialiasing</title><content type='html'>&lt;a href="http://oss.sgi.com/projects/ogl-sample/registry/ARB/multisample.txt"&gt;GL_ARB_multisample&lt;/a&gt; defines the mechanism for antialising in OpenGL.&lt;br /&gt;&lt;br /&gt;In order to use antialiasing of any kind, you must create a proper pixel format for your rendering context.  This is a platform specific process.  Furthermore, in order to check for multisampling support, you must have an active rendering context.  Thus it is advised that you first create a dummy context that every GPU should support.  Once this dummy context is initialized, you can check for antialiasing support and destroy the dummy context.  If antialiasing support is available, you may then create a pixel format that uses antialiasing.&lt;br /&gt;&lt;br /&gt;In Windows, the following attributes must be added to your pixel format attribute array in order to use antialiasing: &lt;span style="font-family: courier new;"&gt;WGL_SAMPLE_BUFFERS_ARB&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;WGL_SAMPLES_ARB&lt;/span&gt;.  &lt;span style="font-family: courier new;"&gt;WGL_SAMPLE_BUFFERS_ARB&lt;/span&gt; should be set to 1.  &lt;span style="font-family: courier new;"&gt;WGL_SAMPLES_ARB&lt;/span&gt; should be set to the number of samples you/the user request (2, 4, 6, 8, etc.)&lt;br /&gt;&lt;br /&gt;In MacOS X, you can request antialiasing through Cocoa, AGL, or CGL depending on what your application needs.&lt;br /&gt;&lt;br /&gt;The following attributes must be added to an NSOpenGLPixelFormatAttribute array : &lt;span style="font-family: courier new;"&gt;NSOpenGLPFASampleBuffers&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;NSOpenGLPFASamples&lt;/span&gt;.  These directly correspond to &lt;span style="font-family: courier new;"&gt;WGL_SAMPLE_BUFFERS_ARB&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;WGL_SAMPLES_ARB&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;If you are using AGL, the following attributes must be added to your attribute array: &lt;span style="font-family: courier new;"&gt;AGL_SAMPLE_BUFFERS_ARB&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;AGL_SAMPLES_ARB&lt;/span&gt;.  These directly correspond to &lt;span style="font-family: courier new;"&gt;WGL_SAMPLE_BUFFERS_ARB&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;WGL_SAMPLES_ARB&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;If you are using CGL, the following attributes must be added to your attribute array: &lt;span style="font-family: courier new;"&gt;kCGLPFASampleBuffers&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;kCGLPFASamples&lt;/span&gt;.  These directly correspond to &lt;span style="font-family: courier new;"&gt;WGL_SAMPLE_BUFFERS_ARB&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;WGL_SAMPLES_ARB&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Once a context with a sample buffer and a number of samples greater than 1 has been created, antialising can be activated with the following command&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;glEnable(GL_MULTISAMPLE_ARB);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;a href="http://oss.sgi.com/projects/ogl-sample/registry/ARB/multisample.txt"&gt;Multisampling specification&lt;/a&gt;&lt;br /&gt;&lt;a href="http://developer.nvidia.com/object/gdc_ogl_multisample.html"&gt;Multisampling in Windows&lt;/a&gt;&lt;br /&gt;&lt;a href="http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_fsaa/chapter_11_section_5.html#//apple_ref/doc/uid/TP40001987-CH405-SW2"&gt;FSAA in Mac OS X&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7705158385874906782-5630529292227342062?l=ogltotd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ogltotd.blogspot.com/feeds/5630529292227342062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7705158385874906782&amp;postID=5630529292227342062' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/5630529292227342062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/5630529292227342062'/><link rel='alternate' type='text/html' href='http://ogltotd.blogspot.com/2006/12/setting-up-antialiasing.html' title='Setting up Antialiasing'/><author><name>Alex Scarborough</name><uri>http://www.blogger.com/profile/00587680319916164177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7705158385874906782.post-4250407485985233829</id><published>2006-12-06T21:06:00.000-08:00</published><updated>2006-12-06T21:48:55.462-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><category scheme='http://www.blogger.com/atom/ns#' term='vertex'/><title type='text'>What is the fastest way to draw geometry?</title><content type='html'>Ideally, you should use a static vertex buffer object, with a stride of 32 bytes (or a multiple of 32).  The most optimal draw call is glDrawRangeElements.  Indices should be unsigned shorts.&lt;br /&gt;&lt;br /&gt;Vertex data should be stored as GLfloat, GLshort, or GLubyte, as these formats are supported by most GPUs.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ati.amd.com/developer/gdc/PerformanceTuning.pdf"&gt;ATI performance tuning&lt;/a&gt;(page 10)&lt;br /&gt;&lt;a href="http://developer.nvidia.com/object/using_VBOs.htm"&gt;Using VBOs&lt;/a&gt;(page 14)&lt;br /&gt;&lt;br /&gt;UNCONFIRMED: Internally on all GPUs, vertices contain four values: xyzw.  By default, if a w value is not provided, it is set to 1.  Theoretically, if you perform this padding in your application before sending the data to OpenGL, you can improve performance.&lt;br /&gt;&lt;br /&gt;Shaders expect all data to be float, thus it is expected that on programmable GPUs specifying all vertex data as float will improve performance by limiting data conversion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7705158385874906782-4250407485985233829?l=ogltotd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ogltotd.blogspot.com/feeds/4250407485985233829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7705158385874906782&amp;postID=4250407485985233829' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/4250407485985233829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/4250407485985233829'/><link rel='alternate' type='text/html' href='http://ogltotd.blogspot.com/2006/12/what-is-fastest-way-to-draw-geometry.html' title='What is the fastest way to draw geometry?'/><author><name>Alex Scarborough</name><uri>http://www.blogger.com/profile/00587680319916164177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7705158385874906782.post-4038758094957956628</id><published>2006-12-06T20:54:00.001-08:00</published><updated>2006-12-07T16:48:05.422-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='texture'/><category scheme='http://www.blogger.com/atom/ns#' term='format'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><title type='text'>What is the optimal 32 bit texture format?</title><content type='html'>The optimal texture format on all systems, regardless of endianness or operating system, is an internal format of GL_RGBA8, a type of GL_UNSIGNED_INT_8_8_8_8_REV, and a format of GL_BGRA.  An optimal call to glTexImage2D would thus be this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, border, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Remember that because this is a packed integer format, you are responsible for taking endianness into account when packing the pixels.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;a href="http://www.nvidia.com/dev_content/nvopenglspecs/GL_NV_pixel_data_range.txt"&gt;GL_NV_pixel_data_range&lt;/a&gt; (look at NVIDIA Implementation Details).&lt;br /&gt;&lt;a href="http://lists.apple.com/archives/mac-opengl/2006/Nov/msg00181.html"&gt;Mac OpenGL mailing list&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7705158385874906782-4038758094957956628?l=ogltotd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ogltotd.blogspot.com/feeds/4038758094957956628/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7705158385874906782&amp;postID=4038758094957956628' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/4038758094957956628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7705158385874906782/posts/default/4038758094957956628'/><link rel='alternate' type='text/html' href='http://ogltotd.blogspot.com/2006/12/what-is-optimal-32-bit-texture-format.html' title='What is the optimal 32 bit texture format?'/><author><name>Alex Scarborough</name><uri>http://www.blogger.com/profile/00587680319916164177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
