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
SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl