<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Pixel by pixel operations (Allegro 5)</title>
		<link>http://www.allegro.cc/forums/view/612922</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Mon, 08 Jul 2013 03:26:34 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Hi all, I&#39;m having a problem: al_draw_pixel is too slow <img src="http://www.allegro.cc/forums/smileys/sad.gif" alt=":(" />. What I want to do is draw each pixel in the screen according to a number I decide. </p><p>For example, I fill a list of X elements (X is equal to the total amount of pixels in my screen) with some random numbers. Then, what I do is drawing each element on a pixel in a bitmap according to their number (for example, element 1 have a 144 number, so I&#39;ll put a pixel in position 1 with the color r,g,b = 144,144,144 ) and I will do that with all the elemts in my list. Finally, I draw that bitmap into my screen buffer.</p><p>The function I mentioned before is too slow to do it, it takes around 10 seconds in a 1920x1080 screen. I have tried to lock the bitmap for writeonly, but it&#39;s still incredible slow. I&#39;ve been browsing around the internet and saw that you can use &quot;direct adressing&quot; to write directly in the bitmap and it&#39;s a fast method to do pixel by pixel operations, but I haven&#39;t been able to implement it in my Allegro 5 program <img src="http://www.allegro.cc/forums/smileys/huh.gif" alt="???" />. Can anybody please help me with this? </p><p>Thanks.</p><p>(I&#39;m just an english student, so please forgive some grammar errors I could have <img src="http://www.allegro.cc/forums/smileys/undecided.gif" alt=":-/" /> )
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ediolot)</author>
		<pubDate>Wed, 03 Jul 2013 22:31:45 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Direct addressing is a thing of the distant past. Nowadays your GPU wil do the work for you. </p><p>In Allegro 5 you will probably need to use al_draw_prim with ALLEGRO_PRIM_POINT_LIST to draw many points more quickly. Look at examples/ex_prim.c to get more information about this.</p><p>Edit: And draw directly to the screen. Drawing to a bitmap is not accelerated.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (beoran)</author>
		<pubDate>Wed, 03 Jul 2013 22:37:20 +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/612922/986372#target">beoran</a> said:</div><div class="quote"><p>
Edit: And draw directly to the screen. Drawing to a bitmap is not accelerated.
</p></div></div><p>

It is on any GPU worth anything, which is 99%.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Trent Gamblin)</author>
		<pubDate>Wed, 03 Jul 2013 22:47:20 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Ah it is? I stand corrected then.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (beoran)</author>
		<pubDate>Wed, 03 Jul 2013 23:16:47 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The only machine I have ever seen that runs A5 but doesn&#39;t have accelerated render-to-texture is my old PowerPC Mac Mini. It&#39;s got some really old ATI GPU that doesn&#39;t support it. There are even older PPC Mac&#39;s (some old Powerbooks and iBooks) that do support RTT.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Trent Gamblin)</author>
		<pubDate>Wed, 03 Jul 2013 23:43:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You could create a bitmap, lock it via <span class="source-code"><a href="http://www.allegro.cc/manual/al_lock_bitmap"><span class="a">al_lock_bitmap</span></a></span> and do your pixel drawing and then unlock it and draw it to screen. This will be faster than your current method.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Thu, 04 Jul 2013 00:18:15 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The code for SiegeLord&#39;s suggestion would look something like this:</p><div class="source-code snippet"><div class="inner"><pre><a href="http://www.allegro.cc/manual/ALLEGRO_LOCKED_REGION"><span class="a">ALLEGRO_LOCKED_REGION</span></a> <span class="k3">*</span>lr <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_lock_bitmap"><span class="a">al_lock_bitmap</span></a><span class="k2">(</span>bitmap, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY<span class="k2">)</span><span class="k2">;</span>
<span class="k1">unsigned</span> <span class="k1">char</span> <span class="k3">*</span>ptr <span class="k3">=</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span><span class="k2">)</span>lr-&gt;data<span class="k2">;</span>
ptr<span class="k2">[</span><span class="n">0</span><span class="k2">]</span> <span class="k3">=</span> red<span class="k2">;</span>
ptr<span class="k2">[</span><span class="n">1</span><span class="k2">]</span> <span class="k3">=</span> green<span class="k2">;</span>
ptr<span class="k2">[</span><span class="n">2</span><span class="k2">]</span> <span class="k3">=</span> blue<span class="k2">;</span>
ptr<span class="k2">[</span><span class="n">3</span><span class="k2">]</span> <span class="k3">=</span> alpha<span class="k2">;</span>
</pre></div></div><p>

obviously <span class="source-code">bitmap, red, green, blue,</span> and <span class="source-code">alpha</span> are your own values. This starts at the first (top left) pixel. You can put it in a loop and iterate the pointer by 4 to get the next pixel. If you want a specific pixel, you can do this:</p><p><span class="source-code"><span class="k1">unsigned</span> <span class="k1">char</span> <span class="k3">*</span>ptr <span class="k3">=</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span><span class="k2">)</span>lr-&gt;data <span class="k3">+</span> y <span class="k3">*</span> lr-&gt;pitch <span class="k3">+</span> <span class="k2">(</span>x<span class="k3">&lt;</span><span class="k3">&lt;</span><span class="n">2</span><span class="k2">)</span><span class="k2">;</span></span></p><p>Don&#39;t forget to unlock before drawing
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ph03nix)</author>
		<pubDate>Thu, 04 Jul 2013 07:05:28 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Eh... not quite. Firstly, if you are going for direct bitmap access, you&#39;re not going to want to leave the pixel format up to Allegro. Secondly, just doing this will work fine:</p><div class="source-code snippet"><div class="inner"><pre><a href="http://www.allegro.cc/manual/al_lock_bitmap"><span class="a">al_lock_bitmap</span></a><span class="k2">(</span>bitmap, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY<span class="k2">)</span><span class="k2">;</span>
<a href="http://www.allegro.cc/manual/al_put_pixel"><span class="a">al_put_pixel</span></a><span class="k2">(</span>x, y, color<span class="k2">)</span><span class="k2">;</span> <span class="c">// if you don't need blending</span>
<a href="http://www.allegro.cc/manual/al_put_blended_pixel"><span class="a">al_put_blended_pixel</span></a><span class="k2">(</span>x, y, color<span class="k2">)</span><span class="k2">;</span> <span class="c">// if you need blending</span>
<a href="http://www.allegro.cc/manual/al_unlock_bitmap"><span class="a">al_unlock_bitmap</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Thu, 04 Jul 2013 07:19:25 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Drawing a single pixel with hardware acceleration when controlled by the CPU is practically as slow as drawing a single full-screen bitmap. This is the kind of thing you&#39;re much better off using fragment shaders for.</p><p>&quot;Fragment Shaders&quot; are basically programs that run on your GPU exclusively and don&#39;t need to communicate (at least not much) with the CPU. They&#39;re countless times faster than trying to draw pixels one at a time from the CPU, so when you need to do per-pixel access, this is the only way you&#39;re gonna get any sort of real speed out of it.</p><p>Especially considering you&#39;re trying to do an entire 1920x1080 screen worth of pixels. That&#39;s slightly over 2,000,000 pixels. Even without hardware acceleration this would go VERY slow at the CPU level. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Thu, 04 Jul 2013 07:49:32 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Don&#39;t forget with ALLEGRO_LOCK_WRITE_ONLY that you have to write to every single pixel or else you may have garbage when you unlock and transfer the new contents.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Thu, 04 Jul 2013 07:54:07 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Put the bitmap in memory if you&#39;re going to use the CPU to draw pixels?</p><p>Depending on what you&#39;re doing though, the shader method may be the way to go.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (MiquelFire)</author>
		<pubDate>Thu, 04 Jul 2013 19:30:00 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thanks for the answers.</p><p>I&#39;ve tried both, SiegeLord and ph03nix method. With the first one my &quot;game&quot; goes around 7-8 FPS and with the second it reaches 21 FPS (Fast enough for what I need), I guess that al_put_pixel is still too slow. But there is still something strange with it. This is part of my code:</p><p>ALLEGRO_LOCKED_REGION *lr = al_lock_bitmap(earth, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY);<br />unsigned char *ptr = (unsigned char *)lr-&gt;data;</p><p>  for (y=0; y&lt;screen.h; y++) {<br />    for (x=0 ; x&lt;screen.w; x++) {</p><p>      pixel = x+y*screen.w;<br />      ptr[pixel*4] = 150;</p><p>    }<br />  }</p><p>al_unlock_bitmap(earth);</p><p>This is supposed to set all pixels to red, but they are drawn in blue <img src="http://www.allegro.cc/forums/smileys/shocked.gif" alt=":o" /><br />If I put ptr[pixel*4+2] = 150 they are drawn in red instead.<br />However, ptr[pixel*4+1] = 150 works fine as they appear in green. It seems that blue and red swapped together.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ediolot)</author>
		<pubDate>Sun, 07 Jul 2013 22:13:13 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I was mistaken when I suggested ALLEGRO_PIXEL_FORMAT_ANY. Use ALLEGRO_PIXEL_FORMAT_ABGR_8888 if you are using a little endian system or ALLEGRO_PIXEL_FORMAT_RGBA_8888 otherwise and the components should be in the right order.</p><p>Also here&#39;s a minor optimization for your code. If you iterate through it 2 million times you should make sure it&#39;s as efficient as possible</p><div class="source-code snippet"><div class="inner"><pre><a href="http://www.allegro.cc/manual/ALLEGRO_LOCKED_REGION"><span class="a">ALLEGRO_LOCKED_REGION</span></a> <span class="k3">*</span>lr <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_lock_bitmap"><span class="a">al_lock_bitmap</span></a><span class="k2">(</span>earth, ALLEGRO_PIXEL_FORMAT_ABGR_8888, ALLEGRO_LOCK_WRITEONLY<span class="k2">)</span><span class="k2">;</span>
<span class="k1">unsigned</span> <span class="k1">char</span> <span class="k3">*</span>ptr <span class="k3">=</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span> <span class="k3">*</span><span class="k2">)</span>lr-&gt;data<span class="k2">;</span> <span class="c">//points to first pixel</span>
<span class="k1">const</span> <span class="k1">int</span> screen_pixels <span class="k3">=</span> screen.w<span class="k3">*</span>screen.h<span class="k2">;</span>
<span class="k1">for</span> <span class="k2">(</span><span class="k1">int</span> i<span class="k3">=</span><span class="n">0</span><span class="k2">;</span> i<span class="k3">!</span><span class="k3">=</span>screen_pixels<span class="k2">;</span> <span class="k3">+</span><span class="k3">+</span>i<span class="k2">)</span><span class="k2">{</span>
      <span class="k3">*</span>ptr<span class="k3">+</span><span class="k3">+</span> <span class="k3">=</span> <span class="n">255</span><span class="k2">;</span> <span class="c">//red</span>
      <span class="k3">*</span>ptr<span class="k3">+</span><span class="k3">+</span> <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span>   <span class="c">//green</span>
      <span class="k3">*</span>ptr<span class="k3">+</span><span class="k3">+</span> <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span>   <span class="c">//blue</span>
      <span class="k3">*</span>ptr<span class="k3">+</span><span class="k3">+</span> <span class="k3">=</span> <span class="n">255</span><span class="k2">;</span> <span class="c">//alpha</span>
<span class="k2">}</span>
<a href="http://www.allegro.cc/manual/al_unlock_bitmap"><span class="a">al_unlock_bitmap</span></a><span class="k2">(</span>earth<span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>

I think you have to set each value, not sure though.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ph03nix)</author>
		<pubDate>Sun, 07 Jul 2013 23:26:32 +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/612922/986432#target">SiegeLord</a> said:</div><div class="quote"><p>
Eh... not quite. Firstly, if you are going for direct bitmap access, you&#39;re not going to want to leave the pixel format up to Allegro.
</p></div></div><p>

If you&#39;re doing this frequently, you actually do want to use ALLEGRO_PIXEL_FORMAT_ANY. It doesn&#39;t have to do any conversion so it&#39;s a lot faster. When you create your bitmaps create them in the desired format then lock with ANY for best performance.</p><p>Note: Of course you can create and lock in the same format, but using ANY means one less hardcoded spot.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Trent Gamblin)</author>
		<pubDate>Sun, 07 Jul 2013 23:28:22 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p><u>Semantically</u> it doesn&#39;t make sense to use ALLEGRO_PIXEL_FORMAT_ANY unless you are going to have a separate case for each possible format it might be in, which may be hard to keep track of.</p><p>Aren&#39;t you guys supposed to be using lr-&gt;pitch in there somewhere? Can&#39;t pitch vary and is not guaranteed to be equal to the width?</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> pixel <span class="k3">=</span> lr-&gt;data <span class="k3">+</span> lr-&gt;pitch<span class="k3">*</span>y <span class="k3">+</span> x<span class="k3">*</span><span class="n">4</span><span class="k2">;</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Mon, 08 Jul 2013 02:54:18 +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/612922/986775#target">Edgar Reynaldo</a> said:</div><div class="quote"><p>
Semantically it doesn&#39;t make sense to use ALLEGRO_PIXEL_FORMAT_ANY unless you are going to have a separate case for each possible format it might be in, which may be hard to keep track of.
</p></div></div><p>

Not really. It locks in the actual format of the bitmap, which you should know. Otherwise your code is going to be slow.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Can&#39;t pitch vary and is not guaranteed to be equal to the width?
</p></div></div><p>

Yes, and it can even be negative (in fact it&#39;s always negative with OpenGL.)
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Trent Gamblin)</author>
		<pubDate>Mon, 08 Jul 2013 03:17:26 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Perhaps it should have been named ALLEGRO_PIXEL_FORMAT_ACTUAL or NO_CONVERSION. :/ Because ANY suggests it is up to allegro and may vary.</p><p>Okay, thanks Trent.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Mon, 08 Jul 2013 03:26:34 +0000</pubDate>
	</item>
</rss>
