<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>[A5] Bitmaps to OpenGL textures</title>
		<link>http://www.allegro.cc/forums/view/611449</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Thu, 22 Nov 2012 21:19:33 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;ve ran into some problems when creating OGL textures from Allegro bitmaps. For the classic 2D texture I&#39;m currently using this code which runs fine:
</p><div class="source-code snippet"><div class="inner"><pre><a href="http://www.allegro.cc/manual/ALLEGRO_BITMAP"><span class="a">ALLEGRO_BITMAP</span></a> <span class="k3">*</span>bitmap <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_load_bitmap"><span class="a">al_load_bitmap</span></a><span class="k2">(</span>path<span class="k2">)</span><span class="k2">;</span>
GLuint texName <span class="k3">=</span> <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<span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>
After that I can just use texName everywhere I want to use GL_TEXTURE2D. But, I also want to use cubemap textures, which are essentially 6 2D textures. Therefore to load it I have a function that loads single bitmap containing all six cube faces and creates a GL_TEXTURE_CUBE_MAP from it:
</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="c">// Omitted sanity checks etc. the textures are +x, -x, +y, -y, +z, -z in one column</span>
<span class="number">  2</span><span class="c">// of size w * w, mBitmap is the bitmap containing them (either loaded from disk</span>
<span class="number">  3</span><span class="c">// or procedurally generated</span>
<span class="number">  4</span><span class="k1">unsigned</span> <span class="k1">int</span> w <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_get_bitmap_width"><span class="a">al_get_bitmap_width</span></a><span class="k2">(</span>mBitmap<span class="k2">)</span><span class="k2">;</span>
<span class="number">  5</span><span class="k1">unsigned</span> <span class="k1">int</span> h <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_get_bitmap_height"><span class="a">al_get_bitmap_height</span></a><span class="k2">(</span>mBitmap<span class="k2">)</span><span class="k2">;</span>
<span class="number">  6</span>
<span class="number">  7</span>glGenTextures<span class="k2">(</span><span class="n">1</span>, <span class="k3">&amp;</span>mName<span class="k2">)</span><span class="k2">;</span>
<span class="number">  8</span>glBindTexture<span class="k2">(</span>GL_TEXTURE_CUBE_MAP, mName<span class="k2">)</span><span class="k2">;</span>
<span class="number">  9</span>glActiveTexture<span class="k2">(</span>GL_TEXTURE0<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 10</span>
<span class="number"> 11</span>glTexParameteri<span class="k2">(</span>GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 12</span>glTexParameteri<span class="k2">(</span>GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 13</span>glTexParameteri<span class="k2">(</span>GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 14</span>glTexParameteri<span class="k2">(</span>GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 15</span>glTexParameteri<span class="k2">(</span>GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 16</span>
<span class="number"> 17</span>glPixelStorei<span class="k2">(</span>GL_UNPACK_ALIGNMENT, <a href="http://www.allegro.cc/manual/al_get_pixel_size"><span class="a">al_get_pixel_size</span></a><span class="k2">(</span>mBitmap-&gt;format<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 18</span>
<span class="number"> 19</span>GLenum target <span class="k3">=</span> GL_TEXTURE_CUBE_MAP_POSITIVE_X<span class="k2">;</span> <span class="c">// Followed by -x, y, -y, z, -z</span>
<span class="number"> 20</span><span class="k1">for</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">int</span> i <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> i <span class="k3">&lt;</span> TextureCubemap::FACE_COUNT<span class="k2">;</span> <span class="k3">+</span><span class="k3">+</span>i<span class="k2">)</span>
<span class="number"> 21</span><span class="k2">{</span>
<span class="number"> 22</span>  <a href="http://www.allegro.cc/manual/al_set_new_bitmap_format"><span class="a">al_set_new_bitmap_format</span></a><span class="k2">(</span>ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 23</span>  <a href="http://www.allegro.cc/manual/ALLEGRO_BITMAP"><span class="a">ALLEGRO_BITMAP</span></a> <span class="k3">*</span>face <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_create_sub_bitmap"><span class="a">al_create_sub_bitmap</span></a><span class="k2">(</span>mBitmap, <span class="n">0</span>, i <span class="k3">*</span> w, w, w<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 24</span>
<span class="number"> 25</span>  glTexImage2D<span class="k2">(</span>target, <span class="n">0</span>, GL_RGBA, w, w, <span class="n">0</span>, GL_RGBA, GL_UNSIGNED_BYTE, face-&gt;memory<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 26</span>
<span class="number"> 27</span>  <a href="http://www.allegro.cc/manual/al_destroy_bitmap"><span class="a">al_destroy_bitmap</span></a><span class="k2">(</span>face<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 28</span>  target<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span>
<span class="number"> 29</span><span class="k2">}</span>
</div></div><p>
This code works, but produces garbage. My guess is wrong data formats. I&#39;ve been also taking a look at ogl_bitmap.c in allegro sources. So, essentially two questions are at hand:</p><p>1. What am I doing wrong.<br />2. Is there a better way of doing this, i.e., creating a cubemap texture from bitmap/bitmaps?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (OICW)</author>
		<pubDate>Fri, 16 Nov 2012 20:24:47 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>There is no -&gt;format or -&gt;memory. You need to lock the bitmap with al_lock_bitmap to the format you want.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Elias)</author>
		<pubDate>Fri, 16 Nov 2012 20:40:59 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Allright, seems I haven&#39;t understood bitmap locking. This time I think I have everything correct, but it still produces garbage:
</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="k1">unsigned</span> <span class="k1">int</span> w <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_get_bitmap_width"><span class="a">al_get_bitmap_width</span></a><span class="k2">(</span>mBitmap<span class="k2">)</span><span class="k2">;</span>
<span class="number">  2</span><span class="k1">unsigned</span> <span class="k1">int</span> h <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_get_bitmap_height"><span class="a">al_get_bitmap_height</span></a><span class="k2">(</span>mBitmap<span class="k2">)</span><span class="k2">;</span>
<span class="number">  3</span>
<span class="number">  4</span>glGenTextures<span class="k2">(</span><span class="n">1</span>, <span class="k3">&amp;</span>mName<span class="k2">)</span><span class="k2">;</span>
<span class="number">  5</span>glBindTexture<span class="k2">(</span>GL_TEXTURE_CUBE_MAP, mName<span class="k2">)</span><span class="k2">;</span>
<span class="number">  6</span>glActiveTexture<span class="k2">(</span>GL_TEXTURE0<span class="k2">)</span><span class="k2">;</span>
<span class="number">  7</span>
<span class="number">  8</span>glTexParameteri<span class="k2">(</span>GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE<span class="k2">)</span><span class="k2">;</span>
<span class="number">  9</span>glTexParameteri<span class="k2">(</span>GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 10</span>glTexParameteri<span class="k2">(</span>GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 11</span>glTexParameteri<span class="k2">(</span>GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 12</span>glTexParameteri<span class="k2">(</span>GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 13</span>
<span class="number"> 14</span>GLenum target <span class="k3">=</span> GL_TEXTURE_CUBE_MAP_POSITIVE_X<span class="k2">;</span> <span class="c">// Followed by -x, y, -y, z, -z</span>
<span class="number"> 15</span><span class="k1">for</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">int</span> i <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> i <span class="k3">&lt;</span> TextureCubemap::FACE_COUNT<span class="k2">;</span> <span class="k3">+</span><span class="k3">+</span>i<span class="k2">)</span>
<span class="number"> 16</span><span class="k2">{</span>
<span class="number"> 17</span>  <a href="http://www.allegro.cc/manual/ALLEGRO_LOCKED_REGION"><span class="a">ALLEGRO_LOCKED_REGION</span></a> <span class="k3">*</span>face <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_lock_bitmap_region"><span class="a">al_lock_bitmap_region</span></a><span class="k2">(</span>mBitmap, <span class="n">0</span>, i <span class="k3">*</span> w, w, w, ALLEGRO_PIXEL_FORMAT_ABGR_8888, ALLEGRO_LOCK_READONLY<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 18</span>
<span class="number"> 19</span>  glPixelStorei<span class="k2">(</span>GL_UNPACK_ALIGNMENT, face-&gt;pixel_size<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 20</span>  glTexImage2D<span class="k2">(</span>target, <span class="n">0</span>, GL_RGBA, w, w, <span class="n">0</span>, GL_RGBA, GL_UNSIGNED_BYTE, face-&gt;data<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 21</span>
<span class="number"> 22</span>  <a href="http://www.allegro.cc/manual/al_unlock_bitmap"><span class="a">al_unlock_bitmap</span></a><span class="k2">(</span>mBitmap<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 23</span>
<span class="number"> 24</span>  target<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span>
<span class="number"> 25</span><span class="k2">}</span>
</div></div><p>
The first cubemap face (positive x) is full of garbage (see attached image below). Inspecting <tt>mBitmap</tt> and <tt>face</tt> in debugger provides following interesting bits for the first iteration:
</p><div class="source-code snippet"><div class="inner"><pre>mBitmap:
 format: <span class="n">9</span>
 pitch: <span class="n">512</span>
 locked: <span class="k1">true</span>
 lock_x: <span class="n">0</span>
 lock_y: <span class="n">0</span>
 lock_w: <span class="n">128</span>
 lock_h: <span class="n">128</span>
 lock_flags: <span class="n">1</span>

face:
 format: <span class="n">17</span>
 pitch: <span class="k3">-</span><span class="n">512</span>
 pixel_size: <span class="n">4</span>
</pre></div></div><p>

<span class="remote-thumbnail"><span class="json">{"name":"606868","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/1\/91c186a55a15f92dcbb50e7dd80df6c4.png","w":646,"h":507,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/1\/91c186a55a15f92dcbb50e7dd80df6c4"}</span><img src="http://www.allegro.cc//djungxnpq2nug.cloudfront.net/image/cache/9/1/91c186a55a15f92dcbb50e7dd80df6c4-240.jpg" alt="606868" width="240" height="188" /></span>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (OICW)</author>
		<pubDate>Thu, 22 Nov 2012 16:19:51 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Try face&gt;data + face-&gt;pitch * w.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Elias)</author>
		<pubDate>Thu, 22 Nov 2012 16:25:42 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>This did the trick:
</p><div class="source-code snippet"><div class="inner"><pre><span class="k2">(</span>face-&gt;data <span class="k3">+</span> <span class="k2">(</span><span class="k1">int</span><span class="k2">)</span>w <span class="k3">*</span> face-&gt;pitch<span class="k2">)</span>
</pre></div></div><p>
Thanks for help. One more question though, should I understand it that the actual pixel data are prepended by pitch * height of something else?</p><p>The only thing I need to solve now, is that apparently each face gets one line from the previous one accidentally. Anyway cookies <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (OICW)</author>
		<pubDate>Thu, 22 Nov 2012 20:20:22 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>No, face-&gt;data simply points to the beginning of the last row (because in Allegro bitmaps row 0 is the top-most row while in OpenGL textures row 0 is the bottom-most row).</p><p>The correct and only documented way of accessing the data is row-by-row, so <span class="source-code">face-&gt;data <span class="k3">+</span> row <span class="k3">*</span> face-&gt;pitch</span> where row can go from 0 to (h-1). Since in your case you know that the data is an OpenGL texture it&#39;s not a horrible hack to just access the whole memory I&#39;d say.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Elias)</author>
		<pubDate>Thu, 22 Nov 2012 20:34:33 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Well, yeah. That also explains the pitch being negative.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (OICW)</author>
		<pubDate>Thu, 22 Nov 2012 21:19:33 +0000</pubDate>
	</item>
</rss>
