I have problems getting al_put_pixel to work as intended. It seems that, whenever I use it, it either does nothing or only writes black pixels into my texture (that is, sampling the texture always returns 0.0 for the red channel and looking at texture in gDEBugger always shows it as either completely black or transparent with one vertical line of black, depending on the bitmap format) . I'm trying to pass a run-time generated texture to my shader to use as some kind of array. It doesn't matter whether I lock my texture or not, the outcome is always the same. Here is some example code:
1// Texture generation code (called once at program start):
ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8); // Also tried ALLEGRO_PIXEL_FORMAT_ARGB_8888 here, no difference - still just black
numAnimations = 1;
maxNumTiles() > 1)
m_pAnimationData = al_create_bitmap(1
15// Filling texture data (called once per frame):
pLockedRegion = al_lock_bitmap(
22for (unsigned int
i = 0;
24 if (
, i, al_map_rgba(
someNumber /* The number I want to read in the shader */
26// I can put a breakpoint here and actually step into al_put_pixel, which means it actually gets called, implying that locking the texture worked as intended. Stepping further into the function, I see that _AL_INLINE_GET_PIXEL gets called, so it should definitely write SOMETHING to the texture.
And the outcome is always something like this (for ALLEGRO_PIXEL_FORMAT_ARGB_8888):
For ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8, it always shows the whole textures as black. Note that the width of the texture is actually expanded to 16 in the GPU, but that shouldn't matter, it should still have at least a few pixels other than black in the texture. To be more precise, it should have a gradient from black to white (from black to red for single channel) in there with only a few pixels inbetween with different values (for most pixels in the loop, someNumber equals i). I also tried writing to pLockedRegion->data directly, still no difference, only black.
Anyone has an idea what I'm doing wrong? (Allegro version is 5.1.10, btw.)
Alright, by now I have made some progress on this, but I still need some help. I think I've actually experienced one or multiple bugs in Allegro related to al_put_pixel, but it might just be me making a few mistakes. Some input on this would be nice.
First of all, I rewrote my locking code like this:
So now I only lock the region I'm actually writing to (in case the texture turns out bigger than I requested), I pick ALLEGRO_PIXEL_FORMAT_ANY as the pixel format and I set the target bitmap after locking the image (to prevent FBO creation in Open GL).
Anyways, here are the observations I made.
First of all, the minimum texture size on my GPU seems to be 16x16. This shouldn't be important, but as it turns out it actually is. If I set the texture format to ALLEGRO_PIXEL_FORMAT_ARGB_8888, the line of pixels I want to modify usually turns out grey (R205/G205/B205/A205). However, when I modify the width and height of my bitmap to be at least 16 pixels each, then al_put_pixel actually works as inteded. It creates a nice gradient from turquoise (R0/G255/B255/A255) to white (RY/G255/B255/A255) on the texture. So here is my first observation: al_put_pixel doesn't seem to work on bitmaps that are smaller than the minimum texture size supported by the GPU. Or maybe it doesn't work on any bitmaps where the texture had to be resized because of GPU restrictions (like, I can imagine it also not working correctly on systems where the GPU only supports power of two textures and you create a NPOT-texture). My guess is that this is a bug in Allegro that was overlooked because this is kind of a rare scenario (especially on more modern GPUs).
My second observation: when using ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8, I never can get it to write the pixels I want into the texture. It seems that it always either puts full black (R0) or almost red (R205) into column of the texture I want to fill. My guess is that this is another bug in Allegro, probably because, once again, this is a rare scenario. While modifying pixels in RGBA textures isn't too uncommon, modifying (or even just using) an R8 texture in Allegro is quite rare.
I'm not entirely sure how locking and al_put_pixel in Allegro work, but from what I understand, the bitmaps use an internal buffer that is returned when the bitmap is locked, and whenever the bitmap is unlocked, the data in the buffer is copied to the locked region of the texture. If that is true, then my guess is that either the pixels are copied from the wrong section of the internal buffer into the texture or the locking call returns a pointer to the wrong place in the buffer. In any case, it looks like some uninitialized memory ends up in the texture. If I'm not wrong, 205 (or 0xCD in hex) is what Visual Studio uses to makr uninitialized memory in RAM.
So can anyone look into this and confirm whether these are actually bugs in Allegro?