Colour blocks

Firstly, I am very new to graphics programming.

I am trying to get my program to display a block of colour on the screen.
The block of colour must be able to change to an arbitrary colour in about
1/40 s without any flicker and it must be able to do it repetitively (ie 40
times a second - at least). The colours are provided by other processing.

I have been playing with LibSDL to display a block that cycles through the
spectrum. Unfortunately, at resolutions above 320x240, it takes a painfully
long time to get anywhere (although it does do it very smoothly).

My next thought was to use the SDL_DBLBUFFER flag to speed up the displays
(if this is wrong - please tell me. As I said, I am new to graphics programming).
The call SDL_VideoModeOK returns 32 with SDL_DBLBUFFER flag, so I assume my
hardware is supporting everything ok (it is the NVidia Geforece 2 Go).

I then used that flag to define my video mode and replaced all the
SDL_UpdateRect(screen, 0, 0, 0, 0) with SDL_Flip(screen) and the program ran,
but no faster.

To test the SDL_Flip function, I inserted an error check after the call and lo,
there seems to be a problem!

I think I must be missing something really obvious. If so, could someone
please point it out. I’m also not sure I fully understand how SDL handles
screens etc.

Any help at all and suggestions on a better way to solve my problem would be
much appreciated.

I have attached the source I’ve been working on ‘test.c’

I have read the examples and the API reference in the DOCS.

Thanks

Henry Gomersall

/* test.c */

#include “SDL.h”
#include <stdio.h>

#define DISPLAY_RES_X 640
#define DISPLAY_RES_Y 480

int main() {
/* set various SDL variables */
SDL_Surface *screen;
SDL_Rect image;
Uint8 r, g, b;

/* Initilise SDL */
 
printf("Initializing SDL.\n");

/* Initialize Video */
if((SDL_Init(SDL_INIT_VIDEO)==-1)) { 
    fprintf(stderr, "Could not initialize SDL: %s.\n", SDL_GetError());
    exit(-1);
}

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

if(SDL_VideoModeOK(DISPLAY_RES_X, DISPLAY_RES_Y, 32, SDL_HWSURFACE | SDL_DOUBLEBUF) != 32)
	fprintf(stderr, "video mode not possible on this hardware\n");

 /* Initialize the display in 32-bit palettized mode,
 * requesting a hardware surface with double buffering */

screen = SDL_SetVideoMode(DISPLAY_RES_X, DISPLAY_RES_Y, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
if ( screen == NULL ) {
    fprintf(stderr, "Couldn't set %ix%ix8 video mode: %s\n", DISPLAY_RES_X, DISPLAY_RES_Y, SDL_GetError());
    exit(1);
}

for(;;){
	for(g = 0;g<255;g++) {
		SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, g, 0));
		if(!(SDL_Flip(screen))){
			fprintf(stderr, "error flipping screen buffers\n");
		}
	}
	for(r = 255;r>0;r--) {
		SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, 255, 0));
		SDL_Flip(screen);
	}
	for(b = 0;b<255;b++) {
		SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 255, b));
		SDL_Flip(screen);
	}
	for(g = 255;g>0;g--) {
		SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, g, 255));
		SDL_Flip(screen);
	}
	for(r = 0;r<255;r++) {
		SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, 0, 255));
		SDL_Flip(screen);
	}
	for(b = 255;b>0;b--) {
		SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 0, b));
		SDL_Flip(screen);
	}
}	
	
printf("SDL initialized.\n");

printf("Quiting SDL.\n");

/* Shutdown all subsystems */
SDL_Quit();

printf("Quiting....\n");

exit(0);

}

I am trying to get my program to display a block of colour on the screen.
The block of colour must be able to change to an arbitrary colour in about
1/40 […]

If all you need is to change the color of the full screen at once, you may
look at palette functions. That is, you set up a paletized mode (8 bit color
depth, i.e.). Then you fill a rect covering all the screen with color 0
(i.e.)
Then, instead of redrawing the full rect, you only redefine the RGB values
for the color 0. Do you get it ?

I am trying to get a coloured block on my screen that changes about 40
times a second. It only changes its colour. The problem I am
encountering is the splits in the screen when program updates the colour
information faster than the screen is drawn.

The advice I was given previously was to use a palette and just to
change the palette colour information. This is how I am doing the
drawing, but it does not seem to help with the issue of splits.

Here is the previous reply I received (it was some time ago).
http://www.libsdl.org/pipermail/sdl/2002-May/045498.html

Does anybody have any advice on how to avoid the problem I am
experiencing. I have looked at double buffering but without much joy.
The problem is primarily due (I think) to a callback function that
interrupts my program when data is ready (which is then processed). I
cannot do without this.

Thanks

Henry Gomersall
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20021120/740bcdea/attachment.pgp

double buffering is only half the answer, the other havl is doing the
"buffer flop" on the verticle retrace. Not sure how to check for this in
SDL however ):> ----- Original Message -----

From: whg21@cam.ac.uk (Henry Gomersall)
To:
Sent: Wednesday, November 20, 2002 2:42 PM
Subject: [SDL] colour blocks

Unless I am being totally silly here I would assume that SDL_flip waits
for the next vertical retrace to flip the buffer. It does however imply
that the vertical retrace fix only works with Hardware surfaces, which
you may or may not have access to.

If you are using software, you will have to find a method to sync with
the vertical retrace. I am not sure how this is done through SDL
either, since the vertical retrace isn’t published through the SDL API.
Does anyone know if the Vertical line count is on a standard register?
I’ve seen the Vertical retrace line count register on at least two
different video cards. If it does exist on a standard register you
could use this value to sync.

One cheap hack you could use, and yes I’ve used this before, is get a
task that wakes about every 16.6 mil and tells the main task to blit the
double buffer to the screen. You will have to play with the timing of
this to make it look correct, and if you are planning on putting this
out on more then one system this work around may very well not work.

RobertOn Wed, 2002-11-20 at 17:08, Atrix Wolfe wrote:

double buffering is only half the answer, the other havl is doing the
"buffer flop" on the verticle retrace. Not sure how to check for this in
SDL however ):

----- Original Message -----
From: “Henry Gomersall”
To:
Sent: Wednesday, November 20, 2002 2:42 PM
Subject: [SDL] colour blocks


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

I do (as far as I know) have access to hardware surfaces. I am
explicitly requesting a hardware surface and returning an error if it
can’t be found (at least I think I am, I’m not sure if SDL defaults to a
basic minimum if it can’t be found).

I experimented with HW surfaces, however, I could not get them to work
properly. I kept getting errors when I tried flipping. Perhaps I should
try again and get back.

thanks

Henry Gomersall
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20021120/26f21d77/attachment.pgpOn Thu, 2002-11-21 at 01:13, Robert Diel wrote:

Unless I am being totally silly here I would assume that SDL_flip waits
for the next vertical retrace to flip the buffer. It does however imply
that the vertical retrace fix only works with Hardware surfaces, which
you may or may not have access to.