Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Blitting TGA with ALPHA channel (OGL)

Credits go to BAF, Bob, Fladimir da Gorf, Kitty Cat, and Pavel Hilser for helping out!
This thread is locked; no one can reply to it. rss feed Print
Blitting TGA with ALPHA channel (OGL)
GullRaDriel
Member #3,861
September 2003
avatar

I ) Introduction:

I'm working on some functions to handle alpha channel and blit an animation of them.
I was using Allegro functions before and it was working fine.
Now i wanna use allegroGL to improve speed, but i'm sure i'm mistaking with "how to use allegroGL & mix it with (opengl & allegro)" .

II ) What is my problem:

I got a SPRITE structure where i keep information for my anims.
Before trying to switch to AGL, i was saving each one pixel per pixel in a file , and reading them from this file.
It was keeping Alpha channel and working fine when set_alpha_blender & draw_trans_sprite.

Since i try to use AllegroGL instead of directX, i got the following problems:
1: never see the right color, always got various red colors.
2: a very bad FPS ( 6-9 )
3: not sure the result is using alpha

<b>III ) What i want to do :</b>

1: Make an initialize function to handle allegroGL for 2d iso using
2: Make a 'blit' function who use allegroGL instead of directX
3: Make a 'close' function to shutdown allegroGL

<b>IV ) so, WTF ?</b>

I'm for sure don't understanding how do GL work. I'm ok to draw lines, point , shapes. But with alpha i got a real problem.

Are function for direct use of BITMAP struct with allegroGL available ?
I was thinking to a allegro_gl_draw_trans_sprite(...) or something else.

If some can post code , i'll be very happy.

<b>V ) Function & structs used</b>

struct SPRITE:

#SelectExpand
1/*! 2 * type of a normal blitted sprite 3 */ 4 5#define NORMAL_SPRITE 0 6 7 8 9/*! 10 * type of a masked sprite 11 */ 12 13#define MASKED_SPRITE 1 14 15 16 17 18/*! 19 * type of a Transp sprite 20 */ 21 22#define TRANS_SPRITE 2 23 24 25 26/*! Struct of a cell of an animation */ 27typedef struct SPRITE { 28 29 /*! sprite */ 30 BITMAP **spr; 31 32 int /*! w size */ 33 w, 34 /*! h size */ 35 h, 36 /*! x center of sprite */ 37 x, 38 /*! y center of sprite */ 39 y, 40 /*! id of the sprite -1 for unavailable */ 41 id, 42 /* type of data ( with blending or just masking ) */ 43 type, 44 /*! is animated ? true or false */ 45 animated, 46 /*! delays between image -1 if no*/ 47 delay, 48 /*! number of pictures in **spr */ 49 current, 50 /*! max picture in **spr */ 51 max, 52 /*! namelenght */ 53 namelenght; 54 55 /*! handles to opengl textures if enable (not saved or loaded) */ 56 GLuint *handles; 57 58 59 /*! name of sprite */ 60 char *name; 61 62} SPRITE;

sprite saver:

#SelectExpand
1/*!\fn write_sprite_in_file( FILE *file , SPRITE *spr ) 2 * 3 *\brief write a sprite in an opened file 4 * 5 *\param file an opening FILE *file to write in 6 *\param spr a SPRITE pointer to know the data 7 * 8 *\return FALSE if not valid file or writing error or memory error TRUE else 9 */ 10 11int write_sprite_in_file( FILE *file , SPRITE *spr ) { 12 13 int it,it1,it2, 14 color; 15 16 17 /* error checking*/ 18 19 if( !file ) return FALSE; 20 21 if( !spr ) return FALSE; 22 23 fwrite( &spr -> w , sizeof(int) , 1 , file ); 24 fwrite( &spr -> h , sizeof(int) , 1 , file ); 25 fwrite( &spr -> x , sizeof(int) , 1 , file ); 26 fwrite( &spr -> y , sizeof(int) , 1 , file ); 27 fwrite( &spr -> id , sizeof(int) , 1 , file ); 28 fwrite( &spr -> type , sizeof(int) , 1 , file ); 29 fwrite( &spr -> animated , sizeof(int) , 1 , file ); 30 fwrite( &spr -> delay , sizeof(int) , 1 , file ); 31 fwrite( &spr -> current , sizeof(int) , 1 , file ); 32 fwrite( &spr -> max , sizeof(int) , 1 , file ); 33 fwrite( &spr -> namelenght , sizeof(int) , 1 , file ); 34 35 36 for( it = 0 ; it < spr -> namelenght ; it ++) 37 fwrite( &spr -> name[ it ] , sizeof(char) , 1 , file ); 38 39 40 for( it = 0 ; it < spr -> current ; it ++ ) { 41 42 for( it1 = 0 ; it1 < spr -> w ; it1 ++ ) { 43 44 for( it2 = 0 ; it2 < spr -> h ; it2 ++ ) { 45 46 color = getpixel( spr -> spr[it] , it1 , it2 ); 47 48 fwrite( &color , sizeof(int) , 1 , file ); 49 50 } 51 } 52 } 53 54 return TRUE; 55 56 57}/* write_sprite_in_file( ... ) */

sprite loader:

#SelectExpand
1/*!\fn read_sprite_in_file( FILE *file , SPRITE **spr ) 2 * 3 *\brief read a sprite in an opened file 4 * 5 *\param file an opening FILE *file to read in 6 *\param spr a SPRITE pointer to point the sprite in memory 7 * 8 *\return FALSE if not valid file or writing error or memory error TRUE else 9 */ 10 11int read_sprite_in_file( FILE *file , SPRITE **spr ) { 12 13 14 15 int it, 16 it1, 17 it2, 18 color; 19 20 21 22 /* error checking*/ 23 24 if( !file ) return FALSE; 25 26 init_sprite( spr , "name" ,-1,-1,-1,-1,-1,-1,-1,-1,-1); 27 28 29 if( !spr ) return FALSE; 30 31 32 fread( &(*spr) -> w , sizeof(int) , 1 , file ); 33 fread( &(*spr) -> h , sizeof(int) , 1 , file ); 34 fread( &(*spr) -> x , sizeof(int) , 1 , file ); 35 fread( &(*spr) -> y , sizeof(int) , 1 , file ); 36 fread( &(*spr) -> id , sizeof(int) , 1 , file ); 37 fread( &(*spr) -> type , sizeof(int) , 1 , file ); 38 fread( &(*spr) -> animated , sizeof(int) , 1 , file ); 39 fread( &(*spr) -> delay , sizeof(int) , 1 , file ); 40 fread( &(*spr) -> current , sizeof(int) , 1 , file ); 41 fread( &(*spr) -> max , sizeof(int) , 1 , file ); 42 fread( &(*spr) -> namelenght , sizeof(int) , 1 , file ); 43 44 Malloc( (*spr) -> name , char , (*spr) -> namelenght + 1 ); 45 46 fill_str( (*spr) -> name , 0 , (*spr) -> namelenght +1 ); 47 48 49 for( it = 0 ; it < (*spr) -> namelenght ; it ++) 50 fread( &(*spr) -> name[ it ] , sizeof(char) , 1 , file ); 51 52 53 Malloc( (*spr) -> spr , BITMAP * , (*spr) -> max ); 54 Malloc( (*spr) -> handles , GLuint , (*spr) -> max ); 55 56 57 for( it = 0 ; it < (*spr) -> current ; it ++ ) { 58 59 (*spr) -> spr[ it ] = create_bitmap( (*spr) -> w , (*spr) -> h ); 60 61 clear_to_color( (*spr) -> spr[ it ] , makeacol( 0 , 0 , 0 , 0 ) ); 62 63 64 for( it1 = 0 ; it1 < (*spr) -> w ; it1 ++ ) { 65 66 67 for( it2 = 0 ; it2 < (*spr) -> h ; it2 ++ ) { 68 69 fread( &color , sizeof(int) , 1 , file ); 70 71 putpixel( (*spr) -> spr[ it ] , it1 , it2 , color ); 72 73 } 74 75 } 76 (*spr) -> handles[ it ] = allegro_gl_make_texture( (*spr) -> spr[ it] ); 77 78 } 79 return TRUE; 80 81 82 }/* read_sprite_in_file(...) */

sprite blitter:

#SelectExpand
1/*!\fn blit_sprite( SPRITE *sprite , int x , int y , int frame , BITMAP *bmp ) 2 * 3 *\brief draw a sprite at the right position 4 * 5 *\param sprite a pointer where the data are 6 *\param x where to put sprite on BITMAP , X 7 *\param y where to put sprite on BITMAP , Y 8 *\param frame frame of sprite to blit 9 *\param bmp BITMAP object where blit sprite 10 * 11 *\return TRUE or FALSE (if not valid frame ie) 12 */ 13 14int blit_sprite( SPRITE *sprite , int x , int y , int frame , BITMAP *bmp ) { 15 16 17 if( !sprite || frame < 0 || frame >= sprite -> current )return FALSE; 18 19 switch( sprite -> type ) { 20 21 /* normal blit */ 22 case NORMAL_SPRITE : 23 24 if( bmp) stretch_blit( sprite -> spr[ frame ] , bmp , 25 0 , 0 , 26 sprite -> spr[ frame ] -> w , 27 sprite -> spr[ frame ] -> h , 28 x - sprite -> x , 29 y - sprite -> y , 30 sprite -> w, 31 sprite -> h 32 } 33 else { 34 /* 35 * TO DO: add Ogl blitter 36 */ 37 } 38 ); 39 40 41 return TRUE; 42 43 break; 44 45 46 /* masked blit */ 47 case MASKED_SPRITE: 48 if( bmp ) masked_stretch_blit( sprite -> spr[ frame ] , bmp , 49 0 , 0 , 50 sprite -> spr[ frame ] -> w , 51 sprite -> spr[ frame ] -> h , 52 x - sprite -> x , 53 y - sprite -> y , 54 sprite -> w, 55 sprite -> h 56 ); 57 else { 58 /* 59 * TO DO: add Ogl blitter 60 */ 61 } 62 63 return TRUE; 64 65 break; 66 67 68 /* translucent blit */ 69 case TRANS_SPRITE: 70 71 if( bmp ){ 72 set_alpha_blender(); 73 draw_trans_sprite( bmp , sprite -> spr[ frame ] , x - sprite -> x , y - sprite -> y ); 74 } 75 else { 76 /* 77 * TO DO: add Ogl blitter 78 */ 79 } 80 81 82 return TRUE; 83 84 break; 85 86 87 /* Sprite has no type ! */ 88 default: 89 90 return FALSE; 91 92 break; 93 94 }/*switch(...)*/ 95 96 return TRUE; 97 98 } /* blit_sprite(...) */

allegroGL initialiser:

/*
 * TO DO : add initialize function
 */

allegroGL exit:

/*
 * TO DO : add allegroGL exit function
 */

<b>Conclusion:</b>

OpenGl make me crazy, i have not sleeped the last 3 night, i'm tired to search and obtain the same result . I need help. Thanks

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Fladimir da Gorf
Member #1,565
October 2001
avatar

Quote:

OpenGl make me crazy, i have not sleeped the last 3 night, i'm tired to search and obtain the same result . I need help. Thanks

What about OpenLayer? It's made for this kind of a thing - to render bitmaps with an alpha channel using OpenGL.

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

GullRaDriel
Member #3,861
September 2003
avatar

Perhaps because i wanna know how to do this using only allegro & allegrogl

EDIT: But i'm also looking at openlayer. I'm not sure it has all the requirement i need , but i'll see. And if you know how to solve the topic with only allegro&allegrogl, don't wait and post your answer ! ;)

EDIT2: i'm looking at lots of code using allegroGL. The problem is that in fact , no one use the same organisation as the other. Some are calling allegro_gl_begin() ...end() where some others don't, to do the same thing.

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Fladimir da Gorf
Member #1,565
October 2001
avatar

Quote:

Perhaps because i wanna know how to do this using only allegro & allegrogl

Why? OpenLayer isn't a wrapper for AllegroGL. It maps the functions to direct OpenGL calls, not to AllegroGL code. Thus it enables a lot of effects and blending modes which aren't possible with AllegroGL's interface.

Sorry, but I don't really know how to solve your problem. But in many cases if you wish to use pure OpenGL you could take a peek at OpenLayer's code.

Also you wouldn't need any wrapper sprite class because OpenLayer automates all the code you posted.

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

GullRaDriel
Member #3,861
September 2003
avatar

is openlayer compatible with C code ? and ansi ? and finally does it run under linux ?

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Fladimir da Gorf
Member #1,565
October 2001
avatar

OpenLayer is in ansi C++ and platform independant. But in most cases you should be able to write C code but compile it in C++.

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

1: never see the right color, always got various red colors.
2: a very bad FPS ( 6-9 )

This leads me to believe you got software rendering. After you set the mode, try printing out these strings:

printf("Graphics Driver: OpenGL %s (%s)\n"
       "  %s detected\n"
       "  Set %dx%d %dbpp %s mode\n",
       glGetString(GL_VERSION), glGetString(GL_VENDOR),
       glGetString(GL_RENDERER),
       SCREEN_W, SCREEN_H, bitmap_color_depth(screen),
       (gfx_driver->windowed ? "windowed" : "fullscreen"));

If you are getting software rendering make sure you set and request GL_RENDERMETHOD 1.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

GullRaDriel
Member #3,861
September 2003
avatar

Graphics Driver: OpenGL 2.0.0 (NVIDIA Corporation)
GeForce FX Go5700/AGP/SSE2/3DNOW! detected
Set 800x600 32bpp fullscreen mode.

GL_RENDERMETHOD is already requested.

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Pavel Hilser
Member #5,788
April 2005
avatar

About the wrong colors - i did the same thing, loading PCX, saving them back into my file format and then in my game - load my format back to bitmaps (and then converting into AllegoGL textures).
But my textures were not RED, they were BLUE. I found that there are problem using RGB, BRG, ... formats. So check if you use the same colors when saving, or change it as you load it back..

BTW: how do you draw the textures ? I thing, if you do it the OpenGl way, you should have a lot of more FPS..
(wrote this in private message)
Try AllegroGL examples, what fps you'll get. (or your video card is capable off)

This is my basic drawing function (I'm really a beginner in openGl, but this will do all you need - rotation, alpha, rgb changes).

1void mydraw_sp(GLuint mytexture, int x,int y,int r,int g,int b,int alpha,int angle,int w,int h)
2{
3//Enable texturing on all models for now on.
4glLoadIdentity();//reset matrix
5glBindTexture(GL_TEXTURE_2D, mytexture);
6//Define how alpha blending will work and enable alpha blending.
7glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
8glEnable(GL_BLEND);
9glTranslatef(x, y, 0.0);
10glRotatef(angle, 0, 0, 1.0);
11glBegin(GL_QUADS);
12 //If we set the color to white here, then the textured quad won't be
13 //tinted red or half-see-through or something when we draw it based on
14 //the last call to glColor*().
15 glColor4ub(r, g, b, alpha);
16 
17 //Draw our four points, clockwise.
18 glTexCoord2f(0, 0); glVertex3f(0,0, 0);
19 glTexCoord2f(1, 0); glVertex3f(w, 0, 0);
20 glTexCoord2f(1, 1); glVertex3f(w, h, 0);
21 glTexCoord2f(0, 1); glVertex3f(0, h , 0);
22glEnd();
23glLoadIdentity();
24}

_____________________________________
Mein Cannon - see my new 2d game

GullRaDriel
Member #3,861
September 2003
avatar

I test with your drawing function.
I already got thosesilly colors.

What i do for saving and loading colors is:

for each x pixel:
for each y pixel:
   color=getpixel(bmp , x , y)
   fwrite( &color , sizeof(int) , 1 , file );

and for reading:
reading number of pixel in x , y
creating bitmap
clearing to zero
for each x pixel:
for each y pixel:
   fread( &color , sizeof(int) , 1 , file );
   putpixel(bmp, x , y , color );

WTF with this ? i can't see where it swap rgb to rbg or other.
When i use set_trans_blender & draw_trans_sprite, it works fine.

EDIT: i found this in the doc of allegroGL.

Quote:

Important note: on 32 bit bitmap in RGBA mode, the alpha channel created by Allegro is set to all 0 by default. This will cause the texture to not show up in 32bpp modes if alpha is set. You will need to fill in the alpha channel manually if you need an alpha channel.

Help !

Ohé ! Bob Bombadil, Bob Bombadillon !
By the pixel, the bitmap, the screen and the layer,
By the great spirit of OpenGL , listen now and hear me
COme on, Bob Bombadil, my need is near me..

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Pavel Hilser
Member #5,788
April 2005
avatar

what bpp you're using when saving ? and when using OGL ? is it the same ?

_____________________________________
Mein Cannon - see my new 2d game

GullRaDriel
Member #3,861
September 2003
avatar

bpp is the same at loading & saving. it's 32 bpp.

If someone have time to help, i have attached some tga that i can be able to quickly blit using allegro&agl.

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Bob
Free Market Evangelist
September 2000
avatar

Would be nice if you posted some code, on occasion.

--
- Bob
[ -- All my signature links are 404 -- ]

GullRaDriel
Member #3,861
September 2003
avatar

Here i made an example, who works very slow.

you can download it
HERE (with source code & tga for test only 900 ko)

the source code is posted here too

agl.c:

1#include <stdlib.h>
2#include <alleggl.h>
3 
4 
5int it,
6 nbimg,
7 w,h;
8 
9 
10char name[64];
11 
12 
13int main(int argc , char *argv[])
14{
15 
16 
17 BITMAP **tmp; /* for read the tga's */
18 GLuint *tex; /* for store the index returned by allegr_gl_make_texture */
19
20 
21 allegro_init();
22 install_mouse();
23
24 
25 set_color_depth(32);
26
27 install_allegro_gl();
28
29 allegro_gl_clear_settings();
30 allegro_gl_set (AGL_COLOR_DEPTH , 32);
31 allegro_gl_set (AGL_DOUBLEBUFFER , 1 );
32 allegro_gl_set (AGL_RENDERMETHOD , 1 );
33 allegro_gl_set (AGL_FULLSCREEN , 1 );
34 allegro_gl_set (AGL_REQUIRE, AGL_RENDERMETHOD |AGL_COLOR_DEPTH | AGL_DOUBLEBUFFER | AGL_FULLSCREEN);
35 
36
37 if (set_gfx_mode(GFX_OPENGL_FULLSCREEN, 800, 600, 0, 0) < 0)
38 {
39 allegro_message("DUCK AND COVER!\n");
40 exit(EXIT_FAILURE);
41 }
42 
43 
44 allegro_gl_use_alpha_channel(TRUE);
45
46
47 nbimg = atoi( argv[1] );
48 tmp = malloc( nbimg * sizeof( BITMAP *));
49 tex = malloc( nbimg * sizeof( GLuint ));
50 
51
52 for( it = 0 ; it < nbimg ; it ++) {
53
54 sprintf( name , "DATA/a+%04d.tga" , it + 1 );
55 
56 printf("name: %s\n",name);
57
58 tmp[it] = load_bitmap(name, NULL);
59
60 w=tmp[it]->w;
61 h=tmp[it]->h;
62
63 if (tmp[it] == NULL)
64 {
65 allegro_message("Error: couldn't find %s",name);
66 exit(EXIT_FAILURE);
67 }
68 
69 tex[it] = allegro_gl_make_texture(tmp[it]);
70 
71 destroy_bitmap(tmp[it]);
72 
73 }
74 
75 install_keyboard();
76 
77 glClearColor(0, 0, 0, 0);
78
79 glDisable(GL_DEPTH_TEST);
80 glDisable(GL_LIGHTING);
81
82 glMatrixMode(GL_PROJECTION);
83 glLoadIdentity();
84
85 glOrtho( 0, SCREEN_W, SCREEN_H, 0, -1, 1 );
86
87 glMatrixMode(GL_MODELVIEW);
88 glLoadIdentity();
89 
90 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
91 
92 it=-1;
93
94 glEnable(GL_TEXTURE_2D);
95
96
97 w = w /2;
98 h = h /2;
99
100 printf("Graphics Driver: OpenGL %s (%s)\n"
101 " %s detected\n"
102 " Set %dx%d %dbpp %s mode\n",
103 glGetString(GL_VERSION), glGetString(GL_VENDOR),
104 glGetString(GL_RENDERER),
105 SCREEN_W, SCREEN_H, bitmap_color_depth(screen),
106 (gfx_driver->windowed ? "windowed" : "fullscreen"));
107
108 do{
109
110 it++;
111 if(it>=nbimg)it=0;
112
113 glBindTexture(GL_TEXTURE_2D, tex[it]);
114
115 glClear(GL_COLOR_BUFFER_BIT);
116
117 glEnable(GL_BLEND);
118
119 glBegin(GL_QUADS);
120 glColor3f(1.0f, 1.0f, 1.0f);
121 glTexCoord2f(0.0f, 0.0f);
122 glVertex3f(mouse_x - w , mouse_y - h , 0.0f);
123 glTexCoord2f(1.0f, 0.0f);
124 glVertex3f(mouse_x + w , mouse_y - h , 0.0f);
125 glTexCoord2f(1.0f, 1.0f);
126 glVertex3f(mouse_x + w , mouse_y + h , 0.0f);
127 glTexCoord2f(0.0f, 1.0f);
128 glVertex3f(mouse_x - w , mouse_y + h , 0.0f);
129 glEnd();
130
131 glDisable(GL_BLEND);
132
133 allegro_gl_flip();
134
135}while(!key[KEY_ESC]);
136
137 for(it = 0 ; it < nbimg ; it ++ )
138 glDeleteTextures(1, &tex[it]);
139
140 remove_allegro_gl();
141
142 allegro_exit();
143
144 return 0;
145}
146END_OF_MAIN()

It's working, good colors, but it is sloooow and the drivers is good.

EDIT: i'm allowed myself to cut&paste your 5 lines of code, kittycat, and the return is always :
Graphics Driver: OpenGL 2.0.0 (NVIDIA Corporation)
GeForce FX Go5700/AGP/SSE2/3DNOW! detected
Set 800x600 32bpp fullscreen mode

EDIT2: to test it, launch a command, and go to the atb directory, launch atb 35 (there are 35 tga in /DATA)

EDIT3: can't be able to speed this up... can it be a size issue? lemme check.

EDIT4: I test all examples in AllegroGL examples directory. Results are: exmasked is as slow as the pasted code. WTF !!²²!!

EDIT5: What can be the raison for exmasked to be so slow ? it is right for colors, but it is already so slow...

!!! IT WAS A DRIVER ISSUE !!! Nvidia's Update for GeforceFX Go 5700 are bad ... everything is better now :( i loose more than a week for a driver issue...

Sorry to have make you loose times ... can someone post for me to give cookies ?

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

BAF
Member #2,981
December 2002
avatar

GullRaDriel
Member #3,861
September 2003
avatar

And no thanks to all for helping out (BAF is coockied because i bore him a lot on msn all along the day ;) and he bumps :p )

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Go to: