<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Stefan Lienhard &#187; OpenGL</title>
	<atom:link href="http://www.stefanlienhard.ch/category/opengl/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.stefanlienhard.ch</link>
	<description>I care because you do.</description>
	<lastBuildDate>Mon, 05 Apr 2010 11:24:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>GL_EXT_framebuffer_object with Multisampling</title>
		<link>http://www.stefanlienhard.ch/2008/08/27/gl_ext_framebuffer_object-with-multisampling/</link>
		<comments>http://www.stefanlienhard.ch/2008/08/27/gl_ext_framebuffer_object-with-multisampling/#comments</comments>
		<pubDate>Tue, 26 Aug 2008 22:45:22 +0000</pubDate>
		<dc:creator>Stefan</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[OpenGL]]></category>

		<guid isPermaLink="false">http://blog.dexta.ch/2008/08/27/gl_ext_framebuffer_object-with-multisampling/</guid>
		<description><![CDATA[I&#8217;ve been using OpenGL Framebuffer Objects (FBOs) a lot lately. One day I was trying to render smoother, anti-aliased edges by using multisampling in combination with a FBO. After iterating through all possible options of OpenGL and the window context &#8230; <a href="http://www.stefanlienhard.ch/2008/08/27/gl_ext_framebuffer_object-with-multisampling/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using OpenGL Framebuffer Objects (FBOs) a lot lately. One day I was trying to render smoother, anti-aliased edges by using multisampling in combination with a FBO. After iterating through all possible options of OpenGL and the window context I was only confused&#8230; my FBO refused to multisample.</p>
<p>My buddy Google who&#8217;s usually most helpful proved to be really bitchy in this matter. But after long arguments with Google I finally got some interesting sources.</p>
<p>This is nothing new, this is nothing revolutionary&#8230; this is meant for people with a similar problem as the one I had and help them to find their way to the solution a little quicker than I did.</p>
<p><span id="more-22"></span> The standard example for using a Framebuffer Object to render to a texture (for more details and explanations ckeck the <a title="Framebuffer Object 101" href="http://www.gamedev.net/reference/programming/features/fbo1/">FBO 101</a>):</p>
<pre>// depth buffer
glGenRenderbuffersEXT(1, &amp;depthBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);

// create fbo and attach depth buffer
glGenFramebuffersEXT(1, &amp;fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);

// create texture
glGenTextures(1, &amp;texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
// set your texture parameters here if required ...

// attach texture
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture, 0);

...

// rendering procedure
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, width, height);
// ... draw ...
glPopAttrib();
// you have to unbind all fbos before you can render to the main window
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);</pre>
<p>Now we extend the previous example a little bit by using <em>GL_EXT_framebuffer_multisample</em> and <em>GL_EXT_framebuffer_blit</em> in addition to the <em>GL_EXT_framebuffer_object</em> extension so that we can use multisampling for anti-aliasing. The only tricky part is that we now use two FBOs. One is a normal FBO which also the texture is attached to. Only the second FBO is multisampled. While rendering, the multisampled FBO&#8217;s content is blitted to the normal FBO.</p>
<pre>// multi sampled color buffer
glGenRenderbuffersEXT(1, &amp;colorBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorBuffer);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_RGBA8, width, height);

// multi sampled depth buffer
glGenRenderbuffersEXT(1, &amp;depthBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH_COMPONENT, width, height);

// create fbo for multi sampled content and attach depth and color buffers to it
glGenFramebuffersEXT(1, &amp;mfbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mfbo);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorBuffer);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);

// create texture
glGenTextures(1, &amp;texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
// set your texture parameters here if required ...

// create final fbo and attach texture to it
glGenFramebuffersEXT(1, &amp;fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture, 0);

...

// rendering procedure
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mfbo);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, width, height);
// ... draw ...
glPopAttrib();
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, mfbo);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fbo);
glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// you have to unbind all fbos before you can render to the main window
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
...

// cleaning up
glDeleteRenderbuffersEXT(1, &amp;depthBuffer);
glDeleteRenderbuffersEXT(1, &amp;colorBuffer);
glDeleteFramebuffersEXT(1, &amp;mfbo);
glDeleteFramebuffersEXT(1, &amp;fbo);</pre>
<p>Make sure that your graphics device supports the <em>GL_EXT_framebuffer_multisample</em> and <em>GL_EXT_framebuffer_blit </em>extensions because usually if an extension is not available the compiler won&#8217;t complain and no error message will be displayed. Instead your application will simply crash (at least this is what happens when you access the OpenGL extensions through glew). If you&#8217;re using glew you can simply do such a check by calling <em>glewIsSupported(&#8230;)</em>. It took me a while to figure out that it was my laptop&#8217;s ATI Mobility Radeon X1400 inability to anti-alias a FBO and not my inattention that caused the crash <img src='http://www.stefanlienhard.ch/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' />  .</p>
<p>One last hint: If you want to render your FBO onto a non-power-of-two sized texture you might be better off using the <em>GL_ARB_texture_rectangle</em> extension. Replace <em>GL_TEXTURE_2D</em> with <em>GL_TEXTURE_RECTANGLE_ARB</em>&#8230; that&#8217;s it.</p>
<p>Enough extensions, happy hacking!</p>
<p>Update:<br />
Also see <a href="http://www.opengl.org/wiki/GL_EXT_framebuffer_multisample">http://www.opengl.org/wiki/GL_EXT_framebuffer_multisample</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.stefanlienhard.ch/2008/08/27/gl_ext_framebuffer_object-with-multisampling/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>
