Why does the rectangle move so slowly and blink?

For movement,I use SDL_FillRect to fill the current rect in new color then
background color.Although the usleep function was commented,the rectangle
still moved very slowly and blinked greatly.What should I do to speed up it and eliminate the blinking?
gentoo linux,libsdl-1.2.7-r2,kernel 2.6.7.
here is test code:-----------------------------------------------------------------------------
#include <stdlib.h>
#include <unistd.h>
#include <SDL/SDL.h>

/*

  • Return the pixel value at (x, y)

  • NOTE: The surface must be locked before calling this!
    */
    Uint32 getpixel(SDL_Surface surface, int x, int y)
    {
    int bpp = surface->format->BytesPerPixel;
    /
    Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
    return *p;

    case 2:
    return *(Uint16 *)p;

    case 3:
    if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
    return p[0] << 16 | p[1] << 8 | p[2];
    else
    return p[0] | p[1] << 8 | p[2] << 16;

    case 4:
    return *(Uint32 *)p;

    default:
    return 0; /* shouldn’t happen, but avoids warnings */
    }
    }

main(int argc, char *argv[])
{

SDL_Surface *screen;
int W = 640,H = 480,bpp = 8;
int x,y;
SDL_Rect dstrect;
Uint32 color;

/* Initialize the SDL library */
if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    fprintf(stderr,
            "Couldn't initialize SDL: %s\n", SDL_GetError());
    exit(1);
}

/* Clean up on exit */
atexit(SDL_Quit);

/*
 * Initialize the display in a 640x480 bpp-bit palettized mode,
 * requesting a software surface
 */
/* Have a preference for bpp-bit, but accept any depth */
screen = SDL_SetVideoMode(W, H, bpp, 
        SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
if ( screen == NULL ) {
    fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
                    SDL_GetError());
    exit(1);
}

 
for(x = 0,y = 0;(x<W) && (y<H);x++){
    dstrect.x = x;
    dstrect.y = y;
    dstrect.w = 100;
    dstrect.h = 100;
    color=getpixel(screen,x,y);
    SDL_FillRect(screen,&dstrect,0xfa9d31);
    SDL_UpdateRect(screen,x,y,100,100);
    SDL_Flip(screen);
    //usleep(1e2);
    SDL_FillRect(screen,&dstrect,color);
    SDL_UpdateRect(screen,x,y,100,100);
    y ++;
}

}

Best Regards,

Well I don’t know anything about your hardware so I can’t really judge
what the performance SHOULD be like, however you might want to try
creating the rectangle on a separate surface and blitting it. I don’t
believe SDL_FillRect offers any sort of acceleration (someone please
correct me if I’m wrong.)

Also, you probably don’t want to update two rects separately, that is
the source of your blinking. Instead of using SDL_UpdateRect, use
SDL_UpdateRects. Or one better, actually use the backbuffer you
requested with SDL_DOUBLEBUF, and call SDL_Flip some time!On Aug 3, 2004, at 3:47 PM, newbie wrote:

For movement,I use SDL_FillRect to fill the current rect in new color
then
background color.Although the usleep function was commented,the
rectangle
still moved very slowly and blinked greatly.What should I do to speed
up it and eliminate the blinking?
gentoo linux,libsdl-1.2.7-r2,kernel 2.6.7.
here is test code:


#include <stdlib.h>
#include <unistd.h>
#include <SDL/SDL.h>

/*

  • Return the pixel value at (x, y)

  • NOTE: The surface must be locked before calling this!
    */
    Uint32 getpixel(SDL_Surface surface, int x, int y)
    {
    int bpp = surface->format->BytesPerPixel;
    /
    Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
    return *p;

    case 2:
    return *(Uint16 *)p;

    case 3:
    if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
    return p[0] << 16 | p[1] << 8 | p[2];
    else
    return p[0] | p[1] << 8 | p[2] << 16;

    case 4:
    return *(Uint32 *)p;

    default:
    return 0; /* shouldn’t happen, but avoids warnings */
    }
    }

main(int argc, char *argv[])
{

SDL_Surface *screen;
int W = 640,H = 480,bpp = 8;
int x,y;
SDL_Rect dstrect;
Uint32 color;

/* Initialize the SDL library */
if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    fprintf(stderr,
            "Couldn't initialize SDL: %s\n", SDL_GetError());
    exit(1);
}

/* Clean up on exit */
atexit(SDL_Quit);

/*
 * Initialize the display in a 640x480 bpp-bit palettized mode,
 * requesting a software surface
 */
/* Have a preference for bpp-bit, but accept any depth */
screen = SDL_SetVideoMode(W, H, bpp,
        SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
if ( screen == NULL ) {
    fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
                    SDL_GetError());
    exit(1);
}


for(x = 0,y = 0;(x<W) && (y<H);x++){
    dstrect.x = x;
    dstrect.y = y;
    dstrect.w = 100;
    dstrect.h = 100;
    color=getpixel(screen,x,y);
    SDL_FillRect(screen,&dstrect,0xfa9d31);
    SDL_UpdateRect(screen,x,y,100,100);
    SDL_Flip(screen);
    //usleep(1e2);
    SDL_FillRect(screen,&dstrect,color);
    SDL_UpdateRect(screen,x,y,100,100);
    y ++;
}

}


Best Regards,


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

  • Donny Viszneki

Thank you very much,I have remove the blinking according to your advise:
for(x = 0,y = 0;(x<W) && (y<H);x++){
dstrect.x = x;
dstrect.y = y;
dstrect.w = 100;
dstrect.h = 100;
color=getpixel(screen,x,y);
SDL_FillRect(screen,&dstrect,0xfa9d31);
//SDL_UpdateRect(screen,x,y,100,100);
SDL_UpdateRects(screen,1,&dstrect);
SDL_Flip(screen);
//usleep(1e2);
SDL_FillRect(screen,&dstrect,color);
//SDL_UpdateRect(screen,x,y,100,100);
//SDL_Flip(screen);
y ++;
}

I am a newbie ( I have just begin to program with libsdl today.). I fail to
use SDL_BlitSurface though I know the speed of Blit is greater than Fill according to my test. To use Blit,I creat three surface: bg screen obj.At firt, I
fill obj with my color. Then,copy obj to screen’s dstrect. So, I got the loop:
1.copy bg to screen
2.copy obj to screen’s dstrect.
3.update screen.
But I found the result was not as my imagined:screen’s background color do
not update to bg,and obj fill all of the screen’s dstrect!

here is it:----------------------------------------------------------------------------
#include <stdlib.h>
#include <unistd.h>
#include <SDL/SDL.h>

/*

  • Return the pixel value at (x, y)

  • NOTE: The surface must be locked before calling this!
    */
    Uint32 getpixel(SDL_Surface surface, int x, int y)
    {
    int bpp = surface->format->BytesPerPixel;
    /
    Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
    return *p;

    case 2:
    return *(Uint16 *)p;

    case 3:
    if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
    return p[0] << 16 | p[1] << 8 | p[2];
    else
    return p[0] | p[1] << 8 | p[2] << 16;

    case 4:
    return *(Uint32 *)p;

    default:
    return 0; /* shouldn’t happen, but avoids warnings */
    }
    }

main(int argc, char *argv[])
{

SDL_Surface *bg,*obj,*screen;
int W = 640,H = 480,bpp = 8;
int x,y;
SDL_Rect srcrect,dstrect,all;
Uint32 color;

all.x = 0;
all.y = 0;
all.w = W;
all.h = H;

/* Initialize the SDL library */
if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    fprintf(stderr,
            "Couldn't initialize SDL: %s\n", SDL_GetError());
    exit(1);
}

/* Clean up on exit */
atexit(SDL_Quit);

/*
 * Initialize the display in a 640x480 bpp-bit palettized mode,
 * requesting a software surface
 */
/* Have a preference for bpp-bit, but accept any depth */
obj = SDL_SetVideoMode(W, H, bpp, 
        SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
if ( obj == NULL ) {
    fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
                    SDL_GetError());
    exit(1);
}

bg = SDL_SetVideoMode(W, H, bpp, 
        SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
if ( bg == NULL ) {
    fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
                    SDL_GetError());
    exit(1);
}

screen = SDL_SetVideoMode(W, H, bpp, 
        SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
if ( screen == NULL ) {
    fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
                    SDL_GetError());
    exit(1);
}

/* creat obj */
srcrect.x = 0;
srcrect.y = 0;
srcrect.w = 100;
srcrect.h = 100;

SDL_FillRect(obj,&srcrect,0xfa9d31);

for(x = 0,y = 0;(x<W) && (y<H);x++){
    dstrect.x = x;
    dstrect.y = y;
    dstrect.w = 100;
    dstrect.h = 100;
    SDL_BlitSurface(bg,NULL,screen,NULL);
    SDL_BlitSurface(obj,&srcrect,screen,&dstrect);
    SDL_UpdateRects(screen,1,&all);
    SDL_Flip(screen);
    y ++;
}

}

And would you like to tell me how to use backbuffer of SDL_DOUBLBUF?

here is my video card:
0000:01:00.0 VGA compatible controller: nVidia Corporation NV18 [GeForce4 MX 440 AGP 8x] (rev a2)

What should I do to the performance?

Best Regards,

On 16:02 Tue 03 Aug , Donny Viszneki wrote:

Well I don’t know anything about your hardware so I can’t really judge
what the performance SHOULD be like, however you might want to try
creating the rectangle on a separate surface and blitting it. I don’t
believe SDL_FillRect offers any sort of acceleration (someone please
correct me if I’m wrong.)

Also, you probably don’t want to update two rects separately, that is
the source of your blinking. Instead of using SDL_UpdateRect, use
SDL_UpdateRects. Or one better, actually use the backbuffer you
requested with SDL_DOUBLEBUF, and call SDL_Flip some time!

On Aug 3, 2004, at 3:47 PM, newbie wrote:

For movement,I use SDL_FillRect to fill the current rect in new color
then
background color.Although the usleep function was commented,the
rectangle
still moved very slowly and blinked greatly.What should I do to speed
up it and eliminate the blinking?
gentoo linux,libsdl-1.2.7-r2,kernel 2.6.7.
here is test code:


#include <stdlib.h>
#include <unistd.h>
#include <SDL/SDL.h>

/*

  • Return the pixel value at (x, y)

  • NOTE: The surface must be locked before calling this!
    */
    Uint32 getpixel(SDL_Surface surface, int x, int y)
    {
    int bpp = surface->format->BytesPerPixel;
    /
    Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
    return *p;

    case 2:
    return *(Uint16 *)p;

    case 3:
    if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
    return p[0] << 16 | p[1] << 8 | p[2];
    else
    return p[0] | p[1] << 8 | p[2] << 16;

    case 4:
    return *(Uint32 *)p;

    default:
    return 0; /* shouldn’t happen, but avoids warnings */
    }
    }

main(int argc, char *argv[])
{

SDL_Surface *screen;
int W = 640,H = 480,bpp = 8;
int x,y;
SDL_Rect dstrect;
Uint32 color;

/* Initialize the SDL library */
if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr,
“Couldn’t initialize SDL: %s\n”, SDL_GetError());
exit(1);
}

/* Clean up on exit */
atexit(SDL_Quit);

/*
* Initialize the display in a 640x480 bpp-bit palettized mode,
* requesting a software surface
/
/
Have a preference for bpp-bit, but accept any depth */
screen = SDL_SetVideoMode(W, H, bpp,
SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
if ( screen == NULL ) {
fprintf(stderr, “Couldn’t set 640x480x8 video mode: %s\n”,
SDL_GetError());
exit(1);
}

for(x = 0,y = 0;(x<W) && (y<H);x++){
dstrect.x = x;
dstrect.y = y;
dstrect.w = 100;
dstrect.h = 100;
color=getpixel(screen,x,y);
SDL_FillRect(screen,&dstrect,0xfa9d31);
SDL_UpdateRect(screen,x,y,100,100);
SDL_Flip(screen);
//usleep(1e2);
SDL_FillRect(screen,&dstrect,color);
SDL_UpdateRect(screen,x,y,100,100);
y ++;
}

}


Best Regards,


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

  • Donny Viszneki

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

And when my test code was executed,most of mem(swap+physical mem) was used!
What should I do?On 16:02 Tue 03 Aug , Donny Viszneki wrote:

Well I don’t know anything about your hardware so I can’t really judge
what the performance SHOULD be like, however you might want to try
creating the rectangle on a separate surface and blitting it. I don’t
believe SDL_FillRect offers any sort of acceleration (someone please
correct me if I’m wrong.)

Also, you probably don’t want to update two rects separately, that is
the source of your blinking. Instead of using SDL_UpdateRect, use
SDL_UpdateRects. Or one better, actually use the backbuffer you
requested with SDL_DOUBLEBUF, and call SDL_Flip some time!

On Aug 3, 2004, at 3:47 PM, newbie wrote:

For movement,I use SDL_FillRect to fill the current rect in new color
then
background color.Although the usleep function was commented,the
rectangle
still moved very slowly and blinked greatly.What should I do to speed
up it and eliminate the blinking?
gentoo linux,libsdl-1.2.7-r2,kernel 2.6.7.
here is test code:


#include <stdlib.h>
#include <unistd.h>
#include <SDL/SDL.h>

/*

  • Return the pixel value at (x, y)

  • NOTE: The surface must be locked before calling this!
    */
    Uint32 getpixel(SDL_Surface surface, int x, int y)
    {
    int bpp = surface->format->BytesPerPixel;
    /
    Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
    return *p;

    case 2:
    return *(Uint16 *)p;

    case 3:
    if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
    return p[0] << 16 | p[1] << 8 | p[2];
    else
    return p[0] | p[1] << 8 | p[2] << 16;

    case 4:
    return *(Uint32 *)p;

    default:
    return 0; /* shouldn’t happen, but avoids warnings */
    }
    }

main(int argc, char *argv[])
{

SDL_Surface *screen;
int W = 640,H = 480,bpp = 8;
int x,y;
SDL_Rect dstrect;
Uint32 color;

/* Initialize the SDL library */
if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr,
“Couldn’t initialize SDL: %s\n”, SDL_GetError());
exit(1);
}

/* Clean up on exit */
atexit(SDL_Quit);

/*
* Initialize the display in a 640x480 bpp-bit palettized mode,
* requesting a software surface
/
/
Have a preference for bpp-bit, but accept any depth */
screen = SDL_SetVideoMode(W, H, bpp,
SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
if ( screen == NULL ) {
fprintf(stderr, “Couldn’t set 640x480x8 video mode: %s\n”,
SDL_GetError());
exit(1);
}

for(x = 0,y = 0;(x<W) && (y<H);x++){
dstrect.x = x;
dstrect.y = y;
dstrect.w = 100;
dstrect.h = 100;
color=getpixel(screen,x,y);
SDL_FillRect(screen,&dstrect,0xfa9d31);
SDL_UpdateRect(screen,x,y,100,100);
SDL_Flip(screen);
//usleep(1e2);
SDL_FillRect(screen,&dstrect,color);
SDL_UpdateRect(screen,x,y,100,100);
y ++;
}

}


Best Regards,


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

  • Donny Viszneki

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

obj = SDL_SetVideoMode(W, H, bpp, 

SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);

bg = SDL_SetVideoMode(W, H, bpp,
SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);

screen = SDL_SetVideoMode(W, H, bpp,
SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);

SDL_SetVideoMode does indeed return an SDL_Surface, however it is not
the way to create a surface, except for when you are creating your
screen. Use SDL_CreateRGBSurface.

  • Donny VisznekiOn Aug 3, 2004, at 5:18 PM, newbie wrote:

NAME
SDL_CreateRGBSurface- Create an empty SDL_Surface

SYNOPSIS
#include “SDL.h”

   SDL_Surface  *SDL_CreateRGBSurface(Uint32 flags, int width, int height,
   int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);

DESCRIPTION
Allocate an empty surface (must be called after SDL_SetVideoMode)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Does this mean that I should create a main surface with SetVideoMode before I
creat any ?empty surface" with CreateRGBSurface?

And I failed again.The output of my code is only a empty surface in black:

#include <stdlib.h>
#include <unistd.h>
#include <SDL/SDL.h>

/*

  • Return the pixel value at (x, y)

  • NOTE: The surface must be locked before calling this!
    */
    Uint32 getpixel(SDL_Surface surface, int x, int y)
    {
    int bpp = surface->format->BytesPerPixel;
    /
    Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
    return *p;

    case 2:
    return *(Uint16 *)p;

    case 3:
    if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
    return p[0] << 16 | p[1] << 8 | p[2];
    else
    return p[0] | p[1] << 8 | p[2] << 16;

    case 4:
    return *(Uint32 *)p;

    default:
    return 0; /* shouldn’t happen, but avoids warnings */
    }
    }

main(int argc, char *argv[])
{

SDL_Surface *bg,*obj,*screen;
int W = 640,H = 480,bpp = 8;
int x,y;
SDL_Rect srcrect,dstrect,all;
Uint32 color,rmask,gmask,bmask,amask;

all.x = 0;
all.y = 0;
all.w = W;
all.h = H;

/* Initialize the SDL library */
if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    fprintf(stderr,
            "Couldn't initialize SDL: %s\n", SDL_GetError());
    exit(1);
}

/* Clean up on exit */
atexit(SDL_Quit);

/*
 * Initialize the display in a 640x480 bpp-bit palettized mode,
 * requesting a software surface
 */
/* Have a preference for bpp-bit, but accept any depth */

screen = SDL_SetVideoMode(W, H, bpp, 
        SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
if ( screen == NULL ) {
    fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
                    SDL_GetError());
    exit(1);
}

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif

bg = SDL_CreateRGBSurface( SDL_HWSURFACE|SDL_ANYFORMAT|
        SDL_DOUBLEBUF,W, H, bpp, rmask, gmask, bmask, amask);
if(bg == NULL) {
    fprintf(stderr, "CreateRGBSurface failed: %s\n", SDL_GetError());
    exit(1);
}

obj = SDL_CreateRGBSurface( SDL_HWSURFACE|SDL_ANYFORMAT|
        SDL_DOUBLEBUF,W, H, bpp, rmask, gmask, bmask, amask);
if(obj == NULL) {
    fprintf(stderr, "CreateRGBSurface failed: %s\n", SDL_GetError());
    exit(1);
}


//SDL_SetAlpha(bg,SDL_RLEACCEL|SDL_SRCALPHA,0);
/* creat obj */
srcrect.x = 0;
srcrect.y = 0;
srcrect.w = 100;
srcrect.h = 100;

SDL_FillRect(obj,&srcrect,0xfa9d31);
//SDL_FillRect(screen,&all,0x3c64a6);

for(x = 0,y = 0;(x<W) && (y<H);x++){
    dstrect.x = x;
    dstrect.y = y;
    dstrect.w = 100;
    dstrect.h = 100;
    SDL_BlitSurface(bg,NULL,screen,NULL);
    SDL_BlitSurface(obj,&srcrect,screen,&dstrect);
    SDL_UpdateRects(screen,1,&all);
    SDL_Flip(screen);
    y ++;
}

}

What’s wrong with me?Thank you for your help!

On 21:47 Tue 03 Aug , Donny Viszneki wrote:

On Aug 3, 2004, at 5:18 PM, newbie wrote:

obj = SDL_SetVideoMode(W, H, bpp,
SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);

bg = SDL_SetVideoMode(W, H, bpp,
SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);

screen = SDL_SetVideoMode(W, H, bpp,
SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);

SDL_SetVideoMode does indeed return an SDL_Surface, however it is not
the way to create a surface, except for when you are creating your
screen. Use SDL_CreateRGBSurface.

  • Donny Viszneki

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

I’m not quite sure about what you’ve said, perhaps you could rephrase
it? I’ll try to answer what I can, and make some remarks about your
code.

First, why do you still include getpixel()? You don’t seem to use it
anywhere.

Second, you don’t call SDL_UpdateRects() and THEN SDL_Flip(). You use
SDL_UpdateRects() in an environment that doesn’t support double
buffering. AFAIK, this is sort of a throw back to Microsoft Windows
style window composition, where your application typically tells the
operating system what part of the screen exactly it wants to update, to
avoid copying unnecessarily large chunks of data.

On modern games, it’s not unusual to change the entire contents of the
screen, hence double buffering. So telling the OS exactly which
rectangles to update is kind of silly at that point. For more clarity,
the man page for SDL_Flip() says “On hardware that doesn’t support
double-buffering, this is equivalent to calling SDL_UpdateRect(screen,
0, 0, 0, 0)”

Now onto your question, I don’t quite understand what you’re trying to
say, but I’ll give it a try.

What you should do is create your screen using SDL_DOUBLEBUF. This
means that SDL will create a surface of what is actually on the screen,
and what will be on the screen next. Calling SDL_Flip automatically
swaps them for you, so blitting to the SDL_Surface that is returned
from SDL_SetVideoMode() is fine no matter what “page” you’re flipped to
(by page, I mean screen buffer, remember, there are two when you use
SDL_DOUBLEBUF.)

So if you want two rectangles to move around the screen, and just want
a blank black background to reappear in an area the rectangles vacate,
then do something like this:

SDL_Surface * screen = SDL_SetVideoMode (blah, blah, blah);
SDL_Surface * rectangle_1 = SDL_CreateRGBSurface (blah, blah, blah);
SDL_Surface * rectangle_2 = SDL_CreateRGBSurface (blah, blah, blah);
SDL_Surface * eraser_1 = SDL_CreateRGBSurface (blah, blah, blah);
Eraser 1 and 2 should be black and have
SDL_Surface * eraser_2 = SDL_CreateRGBSurface (blah, blah, blah);
the same dimensions as rectangle 1 and 2
FillRectanglesWithSomething();
some_kind(of | loop)
{
MoveRectangles(rectangle_1, rectangle_2);
SDL_Blit(screen, rectangle_1);
SDL_Blit(screen, rectangle_2);
SDL_Flip(screen);
SDL_Blit(screen, eraser_1);
SDL_Blit(screen, eraser_2);
}

The idea here is to perform the action, then draw the screen, then show
the screen, then erase what you’ve done so you’ll have a clean slate.
In a game where you perhaps have a tile based background, you won’t
need to erase anything because you’ll just be repainting the whole
background every frame. As a matter of fact you should probably just
get used to the idea of repainting the whole screen from scratch anyhow
IMHO. But that really depends on your system, and of course, your
application.On Aug 4, 2004, at 11:22 AM, newbie wrote:

NAME
SDL_CreateRGBSurface- Create an empty SDL_Surface

SYNOPSIS
#include “SDL.h”

   SDL_Surface  *SDL_CreateRGBSurface(Uint32 flags, int width, int 

height,
int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32
Amask);

DESCRIPTION
Allocate an empty surface (must be called after
SDL_SetVideoMode)

Does this mean that I should create a main surface with SetVideoMode 
before I
creat any ?empty surface" with CreateRGBSurface?

And I failed again.The output of my code is only a empty surface in 
black:
-------------------------------------------------------------------
#include <stdlib.h>
#include <unistd.h>
#include <SDL/SDL.h>

/*
 * Return the pixel value at (x, y)
 * NOTE: The surface must be locked before calling this!
 */
Uint32 getpixel(SDL_Surface *surface, int x, int y)
{
    int bpp = surface->format->BytesPerPixel;
    /* Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
        return *p;

    case 2:
        return *(Uint16 *)p;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
            return p[0] << 16 | p[1] << 8 | p[2];
        else
            return p[0] | p[1] << 8 | p[2] << 16;

    case 4:
        return *(Uint32 *)p;

    default:
        return 0;       /* shouldn't happen, but avoids warnings */
    }
}

main(int argc, char *argv[])
{

   SDL_Surface *bg,*obj,*screen;
   int W = 640,H = 480,bpp = 8;
   int x,y;
   SDL_Rect srcrect,dstrect,all;
   Uint32 color,rmask,gmask,bmask,amask;

   all.x = 0;
   all.y = 0;
   all.w = W;
   all.h = H;

    /* Initialize the SDL library */
    if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
        fprintf(stderr,
                "Couldn't initialize SDL: %s\n", SDL_GetError());
        exit(1);
    }

    /* Clean up on exit */
    atexit(SDL_Quit);

    /*
     * Initialize the display in a 640x480 bpp-bit palettized mode,
     * requesting a software surface
     */
    /* Have a preference for bpp-bit, but accept any depth */

    screen = SDL_SetVideoMode(W, H, bpp,
            SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
    if ( screen == NULL ) {
        fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
                        SDL_GetError());
        exit(1);
    }

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    rmask = 0xff000000;
    gmask = 0x00ff0000;
    bmask = 0x0000ff00;
    amask = 0x000000ff;
#else
    rmask = 0x000000ff;
    gmask = 0x0000ff00;
    bmask = 0x00ff0000;
    amask = 0xff000000;
#endif

    bg = SDL_CreateRGBSurface( SDL_HWSURFACE|SDL_ANYFORMAT|
            SDL_DOUBLEBUF,W, H, bpp, rmask, gmask, bmask, amask);
    if(bg == NULL) {
        fprintf(stderr, "CreateRGBSurface failed: %s\n", 
SDL_GetError());
        exit(1);
    }

    obj = SDL_CreateRGBSurface( SDL_HWSURFACE|SDL_ANYFORMAT|
            SDL_DOUBLEBUF,W, H, bpp, rmask, gmask, bmask, amask);
    if(obj == NULL) {
        fprintf(stderr, "CreateRGBSurface failed: %s\n", 
SDL_GetError());
        exit(1);
    }


    //SDL_SetAlpha(bg,SDL_RLEACCEL|SDL_SRCALPHA,0);
    /* creat obj */
    srcrect.x = 0;
    srcrect.y = 0;
    srcrect.w = 100;
    srcrect.h = 100;

    SDL_FillRect(obj,&srcrect,0xfa9d31);
    //SDL_FillRect(screen,&all,0x3c64a6);

    for(x = 0,y = 0;(x<W) && (y<H);x++){
        dstrect.x = x;
        dstrect.y = y;
        dstrect.w = 100;
        dstrect.h = 100;
        SDL_BlitSurface(bg,NULL,screen,NULL);
        SDL_BlitSurface(obj,&srcrect,screen,&dstrect);
        SDL_UpdateRects(screen,1,&all);
        SDL_Flip(screen);
        y ++;
    }

}
------------------------------------------------------------------

What's wrong with me?Thank you for your help!

On 21:47 Tue 03 Aug     , Donny Viszneki wrote:
>
> On Aug 3, 2004, at 5:18 PM, newbie wrote:
>>    obj = SDL_SetVideoMode(W, H, bpp,
>> SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
>> ...
>>    bg = SDL_SetVideoMode(W, H, bpp,
>> SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
>> ...
>>    screen = SDL_SetVideoMode(W, H, bpp,
>> SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
>
> SDL_SetVideoMode does indeed return an SDL_Surface, however it is not
> the way to create a surface, except for when you are creating your
> screen. Use SDL_CreateRGBSurface.
>
>  - Donny Viszneki
>
>
> _______________________________________________
> SDL mailing list
> SDL at libsdl.org
> http://www.libsdl.org/mailman/listinfo/sdl


_______________________________________________
SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


  • Donny Viszneki

yeah,getpixel was no use,and I should remove it from my code.Thank you,
now I know that SDL_UpdateRects was not necessary for DOUBLEBUF.

Thank you for your detail comment. But I am not sure if I have understood.
Here is my thinking:
MoveRectangles(rectangle_1, rectangle_2);
Q:How to move ?Using which function?Move in surface screen or rectangle inside?
SDL_Blit(screen, rectangle_1);
SDL_Blit(screen, rectangle_2);
Q:using SDL_BlitSurface(rectangle,NULL,screen,NULL) to copy
the whole surface?
SDL_Flip(screen);
SDL_Blit(screen, eraser_1);
SDL_Blit(screen, eraser_2);

I know little about these function except for man.So I do not know how to set
SDL_CreateRGBSurface’s rgbamask ,even what is DOUBLEBUF(system mem + vide mem?)
…In my code,I failed to fill the rectangle of surface created by
SDL_CreatRGBSurface in some color.That is to say ,surface bg and obj are all
in black!Here is the whole code:
#include <stdlib.h>
#include <unistd.h>
#include <SDL/SDL.h>
main(int argc, char *argv[])
{

SDL_Surface *bg,*obj,*screen;
int W = 640,H = 480,bpp = 8;
int x,y;
SDL_Rect srcrect,dstrect,all;
Uint32 color,rmask,gmask,bmask,amask;

all.x = 0;
all.y = 0;
all.w = W;
all.h = H;

/* Initialize the SDL library */
if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    fprintf(stderr,
            "Couldn't initialize SDL: %s\n", SDL_GetError());
    exit(1);
}

/* Clean up on exit */
atexit(SDL_Quit);


screen = SDL_SetVideoMode(W, H, bpp, 
        SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
if ( screen == NULL ) {
    fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
                    SDL_GetError());
    exit(1);
}

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif
// I do not know how does these mask work.
bg = SDL_CreateRGBSurface( SDL_HWSURFACE|SDL_ANYFORMAT|
SDL_DOUBLEBUF,W, H, bpp, rmask, gmask, bmask, amask);
if(bg == NULL) {
fprintf(stderr, “CreateRGBSurface failed: %s\n”, SDL_GetError());
exit(1);
}

obj = SDL_CreateRGBSurface( SDL_HWSURFACE|SDL_ANYFORMAT|
        SDL_DOUBLEBUF,W, H, bpp, rmask, gmask, bmask, amask);
if(obj == NULL) {
    fprintf(stderr, "CreateRGBSurface failed: %s\n", SDL_GetError());
    exit(1);
}


SDL_SetAlpha(obj,SDL_RLEACCEL|SDL_SRCALPHA,1);
/* creat obj */
srcrect.x = 0;
srcrect.y = 0;
srcrect.w = 100;
srcrect.h = 100;

SDL_FillRect(obj,&srcrect,0xfa9d31);
//this do not work!

SDL_FillRect(screen,&all,0x3c64a6);
//But the work!I can see the background color.

SDL_FillRect(bg,&all,0x3c64a6);

for(x = 0,y = 0;(x<W) && (y<H);x++){
    dstrect.x = x;
    dstrect.y = y;
    dstrect.w = 100;
    dstrect.h = 100;
    SDL_BlitSurface(obj,&srcrect,screen,&dstrect);
    SDL_Flip(screen);
    SDL_BlitSurface(bg,&srcrect,screen,&dstrect);
    y ++;
}

}

And would you like give me a simple example code (moving a single
rectangle with speed optimizations ) or online documention? I found
that I know little about SDL.What I do is only to follow the example in
the doc page of www.libsdl.org and guess to fit my need.And the help from man
is very necessary too,such as for the introduction of DOUBLBUF and rgbmask.On 00:58 Thu 05 Aug , Donny Viszneki wrote:

I’m not quite sure about what you’ve said, perhaps you could rephrase
it? I’ll try to answer what I can, and make some remarks about your
code.

First, why do you still include getpixel()? You don’t seem to use it
anywhere.

Second, you don’t call SDL_UpdateRects() and THEN SDL_Flip(). You use
SDL_UpdateRects() in an environment that doesn’t support double
buffering. AFAIK, this is sort of a throw back to Microsoft Windows
style window composition, where your application typically tells the
operating system what part of the screen exactly it wants to update, to
avoid copying unnecessarily large chunks of data.

On modern games, it’s not unusual to change the entire contents of the
screen, hence double buffering. So telling the OS exactly which
rectangles to update is kind of silly at that point. For more clarity,
the man page for SDL_Flip() says “On hardware that doesn’t support
double-buffering, this is equivalent to calling SDL_UpdateRect(screen,
0, 0, 0, 0)”

Now onto your question, I don’t quite understand what you’re trying to
say, but I’ll give it a try.

What you should do is create your screen using SDL_DOUBLEBUF. This
means that SDL will create a surface of what is actually on the screen,
and what will be on the screen next. Calling SDL_Flip automatically
swaps them for you, so blitting to the SDL_Surface that is returned
from SDL_SetVideoMode() is fine no matter what “page” you’re flipped to
(by page, I mean screen buffer, remember, there are two when you use
SDL_DOUBLEBUF.)

So if you want two rectangles to move around the screen, and just want
a blank black background to reappear in an area the rectangles vacate,
then do something like this:

SDL_Surface * screen = SDL_SetVideoMode (blah, blah, blah);
SDL_Surface * rectangle_1 = SDL_CreateRGBSurface (blah, blah, blah);
SDL_Surface * rectangle_2 = SDL_CreateRGBSurface (blah, blah, blah);
SDL_Surface * eraser_1 = SDL_CreateRGBSurface (blah, blah, blah);
Eraser 1 and 2 should be black and have
SDL_Surface * eraser_2 = SDL_CreateRGBSurface (blah, blah, blah);
the same dimensions as rectangle 1 and 2
FillRectanglesWithSomething();
some_kind(of | loop)
{
MoveRectangles(rectangle_1, rectangle_2);
SDL_Blit(screen, rectangle_1);
SDL_Blit(screen, rectangle_2);
SDL_Flip(screen);
SDL_Blit(screen, eraser_1);
SDL_Blit(screen, eraser_2);
}

The idea here is to perform the action, then draw the screen, then show
the screen, then erase what you’ve done so you’ll have a clean slate.
In a game where you perhaps have a tile based background, you won’t
need to erase anything because you’ll just be repainting the whole
background every frame. As a matter of fact you should probably just
get used to the idea of repainting the whole screen from scratch anyhow
IMHO. But that really depends on your system, and of course, your
application.

On Aug 4, 2004, at 11:22 AM, newbie wrote:

NAME
SDL_CreateRGBSurface- Create an empty SDL_Surface

SYNOPSIS
#include “SDL.h”

  SDL_Surface  *SDL_CreateRGBSurface(Uint32 flags, int width, int 

height,
int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32
Amask);

DESCRIPTION
Allocate an empty surface (must be called after
SDL_SetVideoMode)

Does this mean that I should create a main surface with SetVideoMode 
before I
creat any ?mpty surface" with CreateRGBSurface?

And I failed again.The output of my code is only a empty surface in 
black:
-------------------------------------------------------------------
#include <stdlib.h>
#include <unistd.h>
#include <SDL/SDL.h>

/*
* Return the pixel value at (x, y)
* NOTE: The surface must be locked before calling this!
*/
Uint32 getpixel(SDL_Surface *surface, int x, int y)
{
   int bpp = surface->format->BytesPerPixel;
   /* Here p is the address to the pixel we want to retrieve */
   Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

   switch(bpp) {
   case 1:
       return *p;

   case 2:
       return *(Uint16 *)p;

   case 3:
       if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
           return p[0] << 16 | p[1] << 8 | p[2];
       else
           return p[0] | p[1] << 8 | p[2] << 16;

   case 4:
       return *(Uint32 *)p;

   default:
       return 0;       /* shouldn't happen, but avoids warnings */
   }
}

main(int argc, char *argv[])
{

  SDL_Surface *bg,*obj,*screen;
  int W = 640,H = 480,bpp = 8;
  int x,y;
  SDL_Rect srcrect,dstrect,all;
  Uint32 color,rmask,gmask,bmask,amask;

  all.x = 0;
  all.y = 0;
  all.w = W;
  all.h = H;

   /* Initialize the SDL library */
   if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
       fprintf(stderr,
               "Couldn't initialize SDL: %s\n", SDL_GetError());
       exit(1);
   }

   /* Clean up on exit */
   atexit(SDL_Quit);

   /*
    * Initialize the display in a 640x480 bpp-bit palettized mode,
    * requesting a software surface
    */
   /* Have a preference for bpp-bit, but accept any depth */

   screen = SDL_SetVideoMode(W, H, bpp,
           SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
   if ( screen == NULL ) {
       fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
                       SDL_GetError());
       exit(1);
   }

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
   rmask = 0xff000000;
   gmask = 0x00ff0000;
   bmask = 0x0000ff00;
   amask = 0x000000ff;
#else
   rmask = 0x000000ff;
   gmask = 0x0000ff00;
   bmask = 0x00ff0000;
   amask = 0xff000000;
#endif

   bg = SDL_CreateRGBSurface( SDL_HWSURFACE|SDL_ANYFORMAT|
           SDL_DOUBLEBUF,W, H, bpp, rmask, gmask, bmask, amask);
   if(bg == NULL) {
       fprintf(stderr, "CreateRGBSurface failed: %s\n", 
SDL_GetError());
       exit(1);
   }

   obj = SDL_CreateRGBSurface( SDL_HWSURFACE|SDL_ANYFORMAT|
           SDL_DOUBLEBUF,W, H, bpp, rmask, gmask, bmask, amask);
   if(obj == NULL) {
       fprintf(stderr, "CreateRGBSurface failed: %s\n", 
SDL_GetError());
       exit(1);
   }


   //SDL_SetAlpha(bg,SDL_RLEACCEL|SDL_SRCALPHA,0);
   /* creat obj */
   srcrect.x = 0;
   srcrect.y = 0;
   srcrect.w = 100;
   srcrect.h = 100;

   SDL_FillRect(obj,&srcrect,0xfa9d31);
   //SDL_FillRect(screen,&all,0x3c64a6);

   for(x = 0,y = 0;(x<W) && (y<H);x++){
       dstrect.x = x;
       dstrect.y = y;
       dstrect.w = 100;
       dstrect.h = 100;
       SDL_BlitSurface(bg,NULL,screen,NULL);
       SDL_BlitSurface(obj,&srcrect,screen,&dstrect);
       SDL_UpdateRects(screen,1,&all);
       SDL_Flip(screen);
       y ++;
   }

}
------------------------------------------------------------------

What's wrong with me?Thank you for your help!

On 21:47 Tue 03 Aug     , Donny Viszneki wrote:
>
>On Aug 3, 2004, at 5:18 PM, newbie wrote:
>>   obj = SDL_SetVideoMode(W, H, bpp,
>>SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
>>...
>>   bg = SDL_SetVideoMode(W, H, bpp,
>>SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
>>...
>>   screen = SDL_SetVideoMode(W, H, bpp,
>>SDL_HWSURFACE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
>
>SDL_SetVideoMode does indeed return an SDL_Surface, however it is not
>the way to create a surface, except for when you are creating your
>screen. Use SDL_CreateRGBSurface.
>
> - Donny Viszneki
>
>
>_______________________________________________
>SDL mailing list
>SDL at libsdl.org
>http://www.libsdl.org/mailman/listinfo/sdl


_______________________________________________
SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


  • Donny Viszneki

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl