A5 Palette question

Hello everyone. I'm having some problems using allegro5.
I'm used to use allegro4, and I really love the palette manipulation.
Nowadays I'm making a game with 2d graphics that matches the graphics of BlazBlue(the size and 256 colors).

In Allegro4, I can load all the sprites, the main character has more than 80 MB (256 colors) sprites.. And I load the palettes too, 4 palettes for the main character, for multiplayer purposes.
With this I can reuse the main character sprites and just change the palettes for drawing the other players for example.

In Allegro5 I couldn't find a way to do so. Because there aren't palettes...
So I thought of loading the sprites, setting the palette in one of my functions, and that way I would end up with 4 times more sprites in memory and 4 times more ram wasted... And With more enemies in the stage this gets HUGE. Cause I used the palettes for making new enemies, just changing their colors too.

Is There a way to do this in allegro5? What would you recomend me to do?
Thanks in advance.

For example, What I'm trying to do is this:


I find the 256-color support of SDL 1.2 excellent, since it can perform conversion to a 24bit screen mode "behind-the-scene", at a speed that I found incredible. But SDL 1.2 is in end-of-life, so it's probably not a good idea to start moving to it.

Several people have had the idea of using shaders to "simulate" 8bit palette tricks, but after a bit of search I cannot find anything directly usable by somebody who can't program OpenGL (like me)
Seems our Trent himself experimented with it: http://www.nooskewl.com/blogs/trent/?p=180


If you don't want a palette shader, you could instead separate the picture into multiple white layers and tint them.

Like, say the legs use colors 1, 2 and 3 - then just create two pictures, one which gets all pixels 1, 2 and 3 converted to white and another which has all the rest converted to white. Then when you draw the character draw both images and tint them to the colors. You will probably need 5 separate images in your case.

A shader could be more simple, but you need to use Allegro 5.1 for it (or otherwise use OpenGL, as Audric said). With the shader you can just define a palette lookup function in a shading language and directly use your 8-bit textures. Googling for "8-bit palette shader" should find plenty of shaders to use. It would be an ideal example program for Allegro 5.1 btw. - so if someone wants to add a new fragment shader example to 5.1 which does this that would be nice :)

Elias said:

It would be an ideal example program for Allegro 5.1 btw. - so if someone wants to add a new fragment shader example to 5.1 which does this that would be nice

better yet - someone should do a "palette-addon" based on this idea. ;)


I have no idea how to program for shaders... I do find a pallette-add-on interesting.
So I did some searching.
This seems[1] relevant for shading.
Would require a separate bitmap loading routine à la Allegro 4. (Also to ensure bitmap gets loaded to memory, if shader is unsupported.)


  1. I can't read it :-X

Oh God this is so complicated. kkk
Anyway thanks for the feedback. So I will try the shaders, first of all I will pick the example Audric posted.
I will code some thing using allegro5, and I will post here what I could get. :D

Just one more thing, using shaders will breack the multiplataform of my program?
Thanks in advance.


So I have done the palette swapping. But I found some problems. To swap the colors I have the image and some palettes. So What I do is:
Load the palettes;
Load the Image;

reindex theimage colors: This step is costy. What I do is, searching the image for the colors in palette - 1 (the original palette), then When I found the color in the image I put another color, this time I put like
al_put_pixel(x,y, al_map_rgb_f((float)pal/255.f,0.0f,0.0f));
Where pal is the position of the color in the palette...

Where I'm running my program, I pass the color palette for the shader, in the shader I pick the red component and use it as an index for acessing the palette color, get the right color than coloring it right.

The fact is: I have to do the remapping of the colors because allegro5 dont load the image in 8 bits, if it was like allegro4, I could just pick the colors indexes of the palette with get_pixel and use the correct index normally.

By the way there is another problem, I dont know if it is just in my PC or what, but when running my shader I get this error:
i915_program_error: bad opcode: ARL
I have searched in google and found almost nothing, just in some places say that this opcode ARL isn't suported and thats that. But how can I dont use it? XD

The code and the resources used in the experiment are attached .

Dalmo KB

Dude I love palette manipulation as you, and It would be really great to have a palette addon. I downloaded your code, and compiled it. For me it worked, the shaders changed the sprite palette.


There's another reason you want a custom loading routine: to use the indexed colours directly instead of searching them afterwards.
Kudo's on getting this working! ("Fragment shaders not supported" :-X )


Weapoin_S: thanks for trying this, but sad that this isn't suported in your pc. :(
About the loading routine.. I have implemented BMP and PCX load by me own, but the problem is that allegro dont suport 8bit images at all, so thats not possible to take the value of the index in the shader, I will have to modify my loading rotines to put the index of the 8 bit images into one of the pixel components for further access.

I read somewhere that there's an opengl extension that works with palettes, and it receives 8 bit textures..
so is there a way of load a image, put it in a texture(openGl one), and after put it into an allegro_bitmap? Without converting the pixel values of them?

I compiled the same code I posted here in a friend PC, and in his PC, this runned smooth, ilke consuming 4% of the CPU. But like I said the gap is the conversion to be done in loading...

There's to be a better way...
When running the EXAMPLE I posted you can get this output:


Edgar Reynaldo

That's cool stuff. Keep working on it!



To speed up the remapping, you could lock to ALLEGRO_PIXEL_FORMAT_ABGR_8888 and directly modify the pixels instead of calling getpixel for each. We could also have a bitmap flag which makes al_load_bitmap directly put palette indices into r/g/b fields - should be easiy adjusting the bitmap loaders to use such a flag when they encounter paletted files.

And additionally, we should add an 8-bit pixel format to Allegro... I was meaning to add that for some time - maybe I can do it on the weekend. In combination with the above flag, it would then be easy to load a paletted bitmap into a GL_LUMINANCE texture and save some texture space. The shader would be unaffected as far as I understand (GL_LUMINANCE should just make color.r/g/b all have the same texture value).


Hey Elias. thanks. :D
About the remapping, with locking or without locking it will be slow, In a big game you will have to load more than 1000 images. If you hava to remap all the images your loading time will be HUGE.

If we have this Palette flag, it would be really great! And using a GL_LUMINANCE texture will save memory too! It just have 1 internal component. :D

If you could do this Its gonna be awesome. :D

I tried a lot of things to speedup the conversion of images but nothing as good.
Today I tried to get the FBO of the image and get and set the data with:

glReadPixels ( x, y, 1, 1, GL_RGB, GL_FLOAT, pixel);
glDrawPixels(1, 1,GL_RGB, GL_FLOAT, pixel);

But this was wayyyyy slower than allegro. This new Allegro is fantastic but the get and set pixels functions of it is way slower than the previous version.


To speed it up, you could pre-convert the images. Basically load your bitmaps, do the (slow) conversion, then save them again (with the red channel as palette index). The next time you can load them without conversion.

Anyway, I made a patch against 5.1 SVN which allows loading the 8-bit palette index directly. With the patch you can do this:


And it will then load a paletted bitmap by simply reading all the 8-bit indices.

I also attached an example I wrote based on your shader, mainly as excuse to try the programmable pipeline version of A5 :)


Elias THANK YOU man!
That worked perfectly. :D
Just made the diff, compiled the lib, and used your new flags. DONE.
Btw I couldnt compile your ex because it complains about:

ex_palette.c:(.text+0x589): undefined reference to `al_create_shader'
ex_palette.c:(.text+0x5a7): undefined reference to `al_attach_shader_source'
ex_palette.c:(.text+0x5c2): undefined reference to `al_attach_shader_source'
ex_palette.c:(.text+0x5cd): undefined reference to `al_link_shader'
ex_palette.c:(.text+0x5d8): undefined reference to `al_get_opengl_program_object'
ex_palette.c:(.text+0xb60): undefined reference to `al_set_shader_sampler'
ex_palette.c:(.text+0xb8d): undefined reference to `al_set_shader_float_vector'
ex_palette.c:(.text+0xba0): undefined reference to `al_use_shader'
ex_palette.c:(.text+0xc8c): undefined reference to `al_set_shader_sampler'
ex_palette.c:(.text+0xcb9): undefined reference to `al_set_shader_float_vector'
ex_palette.c:(.text+0xccc): undefined reference to `al_use_shader'
ex_palette.c:(.text+0xd42): undefined reference to `al_destroy_shader'

And I coudn't find the allegro_shader that is in the manual...
So I used my own example, and it worked pretty well. :D

And i'm flattered that you used my example as a base. *-*
BTW, whats up with the programmable pipeline version of A5?
When I'm using the programable pipeline.. m screen is totally black, I cant see nothing.. Why? O.o
thanks in advance.


Yes, the shader functions are not documented yet, and I'm not sure all of Allegro works with the programmable pipeline already. It's still work in progress. If you use the debug version allegro.log should contain all the OpenGL errors that were encountered - maybe reveals something.

Also, only Trent knows the programmable pipeline version well for now, I'm not sure what it does exactly. But I think you have to define vertex and fragment shaders for anything with it or you just get black - could be wrong though.

Here's how the example looks... except I don't know how to tell youtube not to re-encode it with 1bit/second :P



Thanks for feedback Elias. Btw cool example thats why I love color palettes. kkkk
Anyways, about the pipeline version, I ook your example, remove all the shaders stuff, and usaed opengl GLSL stuff directly, and nothing of it shows something...
So I think, maybe my graphic card isn't suported (I program in a netbook with a bad intel graphic card.. XD).. I dunno, I think I will get with the normal version for a while. :D
Thanks again. ;)


I think something is wrong in Allegro still, my allegro.log shows several OpenGL errors (even though the example is working). So yeah, right now, just stick with the normal version and use OpenGL directly.

Eventually, the shader addon in A5 should allow having your code work with both OpenGL and DirectX, which seems to still be an advantage in Windows. The shaders themselves would have to come in two versions then, one for GLSL and one for HLSL, or alternatively just a single Cg version, if I understand right. But the rest is taken care of by the addon functions.

Thread #607425. Printed from Allegro.cc