<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>[A5] Sending Two Allegro Bitmaps to a GLSL Fragment/Pixel Shader</title>
		<link>http://www.allegro.cc/forums/view/609539</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Tue, 14 Feb 2012 09:36:43 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>OK, so I&#39;ve run into a problem I <i>know</i> has a solution because I&#39;ve seen raw GLSL code that does this, but since I&#39;m using Allegro for everything except my fragment (pixel) shaders I&#39;m trying to figure out how to make this work.</p><p>Essentially, here&#39;s what I&#39;m trying to do:</p><p>1. Render the entire scene to a Bitmap (Bmp1).<br />2. Render Bmp1 to Bmp2 using a fragment shader.<br />3. Render both Bmp1 and Bmp2 to the screen, blended together.</p><p>Step 1 and 2 are both working, but I&#39;m having trouble with Step 3 because the two bitmaps need to be blended in a VERY specific way that cannot be done with Allegro&#39;s built-in blending functions.</p><p>Essentially, the fragment shader I&#39;m trying to write to blend the two bitmaps looks like this:
</p><div class="source-code snippet"><div class="inner"><pre>uniform sampler2D Bmp1<span class="k2">;</span>
uniform sampler2D Bmp2<span class="k2">;</span>
<span class="k1">void</span> main<span class="k2">(</span><span class="k1">void</span><span class="k2">)</span> <span class="k2">{</span>
    vec2 v <span class="k3">=</span> gl_TexCoord<span class="k2">[</span><span class="n">0</span><span class="k2">]</span>.st<span class="k2">;</span>
    vec4 c1 <span class="k3">=</span> texture2D<span class="k2">(</span>Bmp1,v<span class="k2">)</span><span class="k2">;</span>
    vec4 c2 <span class="k3">=</span> texture2D<span class="k2">(</span>Bmp2,v<span class="k2">)</span><span class="k2">;</span>
    vec4 final<span class="k2">;</span>
    <span class="k1">if</span> <span class="k2">(</span>c1.r <span class="k3">&gt;</span> c2.r<span class="k2">)</span> final.r <span class="k3">=</span> c1.r<span class="k2">;</span> <span class="k1">else</span> final.r <span class="k3">=</span> c2.r<span class="k2">;</span>
    <span class="k1">if</span> <span class="k2">(</span>c1.g <span class="k3">&gt;</span> c2.g<span class="k2">)</span> final.g <span class="k3">=</span> c1.g<span class="k2">;</span> <span class="k1">else</span> final.g <span class="k3">=</span> c2.g<span class="k2">;</span>
    <span class="k1">if</span> <span class="k2">(</span>c1.b <span class="k3">&gt;</span> c2.b<span class="k2">)</span> final.b <span class="k3">=</span> c1.b<span class="k2">;</span> <span class="k1">else</span> final.b <span class="k3">=</span> c2.b<span class="k2">;</span>
    <span class="k1">if</span> <span class="k2">(</span>c1.a <span class="k3">&gt;</span> c2.a<span class="k2">)</span> final.a <span class="k3">=</span> c1.a<span class="k2">;</span> <span class="k1">else</span> final.a <span class="k3">=</span> c2.a<span class="k2">;</span>
    gl_FragColor <span class="k3">=</span> final<span class="k2">;</span> <span class="k2">}</span>
</pre></div></div><p>

However, when I tried to pass two bitmaps down the graphics pipeline through this fragment shader, BOTH ended up pointing to the one being drawn by the al_draw_bitmap() command! I did some further testing and noticed my calls to glUniform1iARB() weren&#39;t being honoured and that even if I changed them to completely bogus values in the fragment shaders I already had working, they continued working.</p><p>Here&#39;s how I&#39;m preapring the fragment shaders for use:
</p><div class="source-code snippet"><div class="inner"><pre>sceneblend_shader <span class="k3">=</span> glCreateShaderObjectARB<span class="k2">(</span>GL_FRAGMENT_SHADER_ARB<span class="k2">)</span><span class="k2">;</span>
glShaderSourceARB<span class="k2">(</span>sceneblend_shader,sceneblend_code_len,sceneblend_code,NULL<span class="k2">)</span><span class="k2">;</span>
glCompileShaderARB<span class="k2">(</span>sceneblend_shader<span class="k2">)</span><span class="k2">;</span>
sceneblend <span class="k3">=</span> glCreateProgramObjectARB<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
glAttachObjectARB<span class="k2">(</span>sceneblend,sceneblend_shader<span class="k2">)</span><span class="k2">;</span>
glLinkProgramARB<span class="k2">(</span>sceneblend<span class="k2">)</span><span class="k2">;</span>
loc <span class="k3">=</span> glGetUniformLocationARB<span class="k2">(</span>sceneblend,<span class="s">"Bmp1"</span><span class="k2">)</span><span class="k2">;</span>
glUniform1iARB<span class="k2">(</span>loc,<a href="http://www.allegro.cc/manual/al_get_opengl_texture"><span class="a">al_get_opengl_texture</span></a><span class="k2">(</span>_bitmap_1<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
loc <span class="k3">=</span> glGetUniformLocationARB<span class="k2">(</span>sceneblend,<span class="s">"Bmp2"</span><span class="k2">)</span><span class="k2">;</span>
glUniform1iARB<span class="k2">(</span>loc,<a href="http://www.allegro.cc/manual/al_get_opengl_texture"><span class="a">al_get_opengl_texture</span></a><span class="k2">(</span>_bitmap_2<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>

Note, everything so far has been pseudocode because I&#39;ve been re-writing the heck out of it all trying to make it work, but this is what I originally tried.</p><p>Any ideas?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Tue, 14 Feb 2012 04:08:17 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Yes, you&#39;re doing it wrong. You don&#39;t pass OpenGL textures for sampler2Ds, you&#39;re supposed to pass <i>texture units</i>. So your code should look a little like this:</p><div class="source-code snippet"><div class="inner"><pre>glActiveTexture<span class="k2">(</span><span class="n">0</span><span class="k2">)</span><span class="k2">;</span>
glBindTexture<span class="k2">(</span>bmp1<span class="k2">)</span><span class="k2">;</span>
glActiveTexture<span class="k2">(</span><span class="n">1</span><span class="k2">)</span><span class="k2">;</span>
glBindTexture<span class="k2">(</span>bmp2<span class="k2">)</span><span class="k2">;</span>
glUniform1i<span class="k2">(</span>blah, <span class="n">0</span><span class="k2">)</span><span class="k2">;</span>
glUniform1i<span class="k2">(</span>blah2, <span class="n">1</span><span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>

If you had used the shader addon, this would be done for you <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" />.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Trent Gamblin)</author>
		<pubDate>Tue, 14 Feb 2012 04:54:05 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p><a href="http://www.allegro.cc/forums/thread/606245">Don&#39;t worry, been in a similar situation once.</a> <img src="http://www.allegro.cc/forums/smileys/grin.gif" alt=";D" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Dario ff)</author>
		<pubDate>Tue, 14 Feb 2012 06:53:39 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Someone might wanna tell that to whoever wrote ex_opengl_pixel_shader.c to go with the A5 examples. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /></p><p>However, even after making this change it still isn&#39;t working. It appears as though texture 0 is <i>always</i> the bitmap Allegro is drawing from and anything beyond that is cleared away. If I try assigning a texture to ID 1, nothing goes through, yet even if I assign it to ID 1 then pass ID 0 to glUniform1iARB(), it goes through fine, but then I&#39;m still left only able to get one texture through the pipeline and not two.</p><p>I&#39;m using 5.0.5 until 5.1 is considered a stable release with pre-compiled MSVC10 binaries and such, so I don&#39;t have access to the shader addon.</p><p><b>EDIT:</b> *looks through Dario&#39;s situation* So... waitaminute... is the solution nothing more than just manually drawing the texture and skipping on Allegro&#39;s drawing functions?</p><p>*tries this, will be back momentarily*
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Tue, 14 Feb 2012 06:54:40 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/609539/947299#target">Kris Asick</a> said:</div><div class="quote"><p>So... waitaminute... is the solution nothing more than just manually drawing the texture and skipping on Allegro&#39;s drawing functions?</p></div></div><p>
I didn&#39;t actually mean that, but then again that solution was for code I was trying to get to work ONE year ago. I&#39;m not sure how much has A5 changed from then in regards to it.</p><p>Still, if you&#39;re using GLSL I&#39;m gonna guess you&#39;re staying OpenGL only, so I don&#39;t see any reasons to not use specific code like that. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Dario ff)</author>
		<pubDate>Tue, 14 Feb 2012 07:08:54 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>After much tweaking, I finally have it working, WITH the built-in Allegro functions! <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /></p><p>Basically, once I enable the fragment shader, I have to do this:
</p><div class="source-code snippet"><div class="inner"><pre>  glActiveTexture<span class="k2">(</span>GL_TEXTURE0<span class="k2">)</span><span class="k2">;</span>
  glBindTexture<span class="k2">(</span>GL_TEXTURE_2D,<a href="http://www.allegro.cc/manual/al_get_opengl_texture"><span class="a">al_get_opengl_texture</span></a><span class="k2">(</span>_bitmap_1<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
  loc <span class="k3">=</span> glGetUniformLocationARB<span class="k2">(</span>sceneblend,<span class="s">"Bmp1"</span><span class="k2">)</span><span class="k2">;</span>
  glUniform1iARB<span class="k2">(</span>loc,<span class="n">0</span><span class="k2">)</span><span class="k2">;</span>
  glActiveTexture<span class="k2">(</span>GL_TEXTURE1<span class="k2">)</span><span class="k2">;</span>
  glBindTexture<span class="k2">(</span>GL_TEXTURE_2D,<a href="http://www.allegro.cc/manual/al_get_opengl_texture"><span class="a">al_get_opengl_texture</span></a><span class="k2">(</span>_bitmap_2<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
  loc <span class="k3">=</span> glGetUniformLocationARB<span class="k2">(</span>sceneblend,<span class="s">"Bmp2"</span><span class="k2">)</span><span class="k2">;</span>
  glUniform1iARB<span class="k2">(</span>loc,<span class="n">1</span><span class="k2">)</span><span class="k2">;</span>
  glActiveTexture<span class="k2">(</span>GL_TEXTURE0<span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>

Then I can call the Allegro function to draw the bitmap to the screen and it will process both textures through the pipeline. <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /></p><p>After a whole bunch of tweaking, the real trick to this entire mess was, <i>no matter what texture IDs you use</i>, to specifically call glActiveTexture(GL_TEXTURE0) after setting up both textures. Failing to do this throws the entire thing out of whack, even when trying to handle everything manually through OpenGL calls.</p><p>At first it didn&#39;t work and I was spending nearly half an hour trying everything until I realized I forgot to turn the fragment shader off afterwards, thus it was getting used to render the scene elements themselves, which obviously wasn&#39;t going to work properly. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /></p><p>And of course, my sceneblend shader isn&#39;t perfect and needs tweaking. Ah well, the fact that it&#39;s working means tweaking it will be simple enough. <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" /></p><p>Thanks, guys! <img src="http://www.allegro.cc/forums/smileys/grin.gif" alt=";D" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Tue, 14 Feb 2012 08:37:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/609539/947315#target">Kris Asick</a> said:</div><div class="quote"><p>
After a whole bunch of tweaking, the real trick to this entire mess was, no matter what texture IDs you use, to specifically call glActiveTexture(GL_TEXTURE0) after setting up both textures. Failing to do this throws the entire thing out of whack, even when trying to handle everything manually through OpenGL calls.
</p></div></div><p>

Makes sense. The Allegro draw functions bind the texture, so without that final call, it would bind the texture on unit 1, and they would then both be pointing at the same bitmap <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Trent Gamblin)</author>
		<pubDate>Tue, 14 Feb 2012 09:36:43 +0000</pubDate>
	</item>
</rss>
