SDL digest, Vol 1 #233 - 30 msgs

Hi all,
I’m drawing directly to an offscreen buffer that is 32bits. The surface is
created and if my pointer isn’t NULL I go ahead and SDL_SetAlpha(buffer,
SDL_SRCALPHA, 255). But it only uses per-surface alpha blending when I blit
it to the screen.
simplified drawing code:

if(you have to lock the surface)
{
lock the surface
}

draw the pixels with colors selected from the color_buffer[]

if(you had to lock it)
{
unlock it
}

blit the surface to the screen.
update the screen.

Pretty basic and just about right out of a tutorial somewhere…but like I
said it doesn’t use the alpha values from the colors I generated.

For testing purposes I’m making an array of 256 colors (white to black /
opaque to transparent) and including alpha information.
So what I’m asking is basically: Is it possible to draw onto a surface and
use alpha information that will be taken care of when you blit to the screen?
Thanks,
Chip Collier

Chip Collier wrote:

I’m drawing directly to an offscreen buffer that is 32bits. The surface is
created and if my pointer isn’t NULL I go ahead and SDL_SetAlpha(buffer,
SDL_SRCALPHA, 255). But it only uses per-surface alpha blending when I blit
it to the screen.

please make a complete minimal testcase that we can look at

Here is a modified version of the program I’m working on.
Thanks,
Chip

#include <iostream.h>
#include <SDL.h>
#include <stdlib.h>

/////////////////////////////////////////////////////
// GLOBALS
/////////////////////////////////////////////////////

#define WIDTH 640
#define HEIGHT 480
#define BPP 32
#define P_SIZE 255
#define SCREEN_SIZE WIDTH*HEIGHT

typedef struct{
SDL_Surface *screen;
SDL_Surface *buffer;
SDL_Surface *bkgrnd;
Uint32 *pixel_buffer;
}GLOBALS;

GLOBALS g;

int init(Uint32 init_flags, Uint32 video_flags){
if(SDL_Init(init_flags) < 0){
cout<<SDL_GetError()<<endl;
return -1;
}
else{
atexit(SDL_Quit);
g.screen = SDL_SetVideoMode(WIDTH, HEIGHT, BPP, video_flags);
if(g.screen == NULL){
cout<<SDL_GetError()<<endl;
return -1;
}
else{
g.buffer = SDL_ConvertSurface(g.screen, g.screen->format, SDL_HWSURFACE);
if(g.buffer == NULL){
cout<<SDL_GetError()<<endl;
return -1;
}
else{
SDL_SetAlpha(g.buffer, SDL_SRCALPHA, 255);
// Am I using this right?
}

    g.bkgrnd = SDL_LoadBMP("background.bmp");
    if(g.bkgrnd == NULL){
	cout << SDL_GetError() << endl;
	return -1;
    }
}
}

return 0;

}

int draw(){
bool need_lock = false;
g.pixel_buffer = (Uint32 *)g.buffer->pixels;

if(SDL_MUSTLOCK(g.buffer)){
SDL_LockSurface(g.buffer);
need_lock = true;
}

for(int i=0; i < 20000; i++){
g.pixel_buffer[(rand()%WIDTH) + ((rand()%HEIGHT)*WIDTH)] = 
	SDL_MapRGBA(g.buffer->format, 255,255,255,56);
}

if(need_lock){
SDL_UnlockSurface(g.buffer);
}
    
SDL_BlitSurface(g.buffer, NULL, g.screen, NULL);
SDL_Flip(g.screen);
return 0;

}

int main(int argc, char * argv){
bool done = false;
SDL_Event event;

cout << "Initializing: ";
if(init(SDL_INIT_VIDEO, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN) < 0){
return -1;
}

cout << "Done :)\n";
SDL_ShowCursor(0);
SDL_BlitSurface(g.bkgrnd, NULL, g.screen, NULL);
SDL_UpdateRect(g.screen, 0,0,0,0);
SDL_Delay(4000);

cout << "Entering main loop.\n";
while(!done){
while(SDL_PollEvent(&event)){
    switch(event.type){
	case SDL_QUIT:
	    done = true;
	    break;
	case SDL_KEYDOWN:
	    done = true;
	    break;
	default:
	    break;
    }
}
draw();
}
SDL_FreeSurface(g.buffer);

cout << "All done\n";
SDL_Delay(300);
return 0;

}On Friday 25 January 2002 04:22, you wrote:

Chip Collier <@Chip_Collier> wrote:

I’m drawing directly to an offscreen buffer that is 32bits. The surface is
created and if my pointer isn’t NULL I go ahead and SDL_SetAlpha(buffer,
SDL_SRCALPHA, 255). But it only uses per-surface alpha blending when I
blit it to the screen.

please make a complete minimal testcase that we can look at

Chip Collier wrote:

Here is a modified version of the program I’m working on.

(Next time please make it shorter; 20-30 lines would do, not 135.)
Your surface “g.buffer” does not have an alpha channel, and therefore
per-pixel alpha cannot be used

[ CC:ed to sdl-list ]

Chip Collier wrote:

Should I be creating it with something else?

If you use ConvertSurface with screen->format, the created surface will
have exact the same format as the screen, which lacks an alpha channel.
I suggest you either use CreateRGBSurface with suitable masks or
DisplayFormatAlpha on an image you already have.

Suitable masks for CreateRGBSurface may be the same ones as the screen has
for the R, G, and B, and something that fits in for A. (Assuming the screen
is 32-bit of course — otherwise, just pick something like (0xff, 0xff00,
0xff0000, 0xff000000).)

[ CC:ed to the list — people, please don’t mail me privately about things
that may be of general interest without also sending a copy to the sdl-list.
People learn more from other’s problem than you might realise. ]

Chip Collier wrote:

Is there an SDL macro or function that can test for
bigendian or littleendian?

the macro SDL_BYTEORDER is set to either SDL_BIG_ENDIAN or SDL_LIL_ENDIAN,
so you can use either #if or plain if().