[SDL] weird drawing issue

Chris Thielen chris at luethy.net
Sun Jan 26 22:35:01 PST 2003


Oops, I found out what it was. It wasn't SDL related, but it brings up
an SDL related question.

To anybody who blits, remembers the rects, and then calls
SDL_UpdateRects() to do their drawing (I've seen it in some examples but
I don't know how many people use it), how do you handle the number of
rects needed? I have:

SDL_Rect blitted_rects[]

but the array size is too great, especially considering I need 200 or so
1x1 rectangles to remember as stars. Anybody have a good way to get
around it or does everybody just use a large array?

On Sun, 2003-01-26 at 22:06, Chris Thielen wrote:
> I've run into quite an odd issue with it comes to drawing ovals. I had
> originally a function to draw circles, but when it did, things wouldn't
> work correctly in my app after it did the drawing. Moving sprites would
> stay on screen, the stars would dim and come back up, and I suspected
> some really weird memory corruption at first. But I wrote a simple macro
> ENSURE_ON_SCREEN(x, y) to make sure the drawing function didnt write
> outside the surface ... and yet the problem remains.
> 
> I guess I have two questions. First, does this sound like a good way to
> do locking/unlocking? (maybe that's my problem? i don't know, this weird
> graphics corruption occurs under x11, probably windows too, i dont
> know):
> 
> if (SDL_MUSTLOCK(screen)) {
> 	unsigned char unlocked = 1;
> 	while (unlocked)
> 		unlocked = SDL_LockSurface(screen);
> }
> 
> ... code touching surface ...
> 
> if (SDL_MUSTLOCK(screen))
> 	SDL_UnlockSurface(screen);
> 
> and ... if that checks out ... is there anything wrong with the included
> draw_oval function? I don't know what's wrong, but only calling this
> function causes that weird sort of video corruption. (where "screen" is
> the main video surface and ensure_blitted() is a function to keep track
> of rects needing flipping)
> 
> #define ENSURE_ON_SCREEN(x, y) if (((x) >= 0) && ((y) >= 0) && ((x) <
> 800) && ((y) < 600))
> 
> /* bresenham's oval algorithm, converted from a dos graphics book */
> void draw_oval(int x, int y, int radius, float aspect, Uint32 color) {
> 	int pitch_adjust;
> 	int pixels[4][2];
> 	int col, i, row;
> 	float aspect_square;
> 	long a_square, b_square, two_a_square, two_b_square, four_a_square,
> four_b_square, d;
> 
> 	if (screen_bpp == 32)
> 		pitch_adjust = screen->pitch / sizeof(Uint32);
> 	else if (screen_bpp == 16)
> 		pitch_adjust = screen->pitch / sizeof(Uint16);
> 
> 	if (SDL_MUSTLOCK(screen)) {
> 		unsigned char unlocked = 1;
> 		while (unlocked)
> 			unlocked = SDL_LockSurface(screen);
> 	}
> 
> 	/* draw an oval */
> 	aspect_square = aspect * aspect;
> 	radius -= LINE_WIDTH / 2;
> 	for (i = 1; i < LINE_WIDTH; i++) {
> 		b_square = radius * radius;
> 		a_square = b_square / aspect_square;
> 		row = radius;
> 		col = 0;
> 		two_a_square = a_square << 1;
> 		four_a_square = a_square << 2;
> 		four_b_square = b_square << 2;
> 		two_b_square = b_square << 1;
> 		d = two_a_square * ((row - 1) * (row)) + a_square + two_b_square * (1
> - a_square);
> 		while(a_square * (row) > b_square * (col)) {
> 			/* plot the pixels */
> 			pixels[0][0] = col+x;
> 			pixels[0][1] = row+y;
> 			pixels[1][0] = col+x;
> 			pixels[1][1] = y-row;
> 			pixels[2][0] = x-col;
> 			pixels[2][1] = row+y;
> 			pixels[3][0] = x-col;
> 			pixels[3][1] = y-row;
> 			if (screen_bpp == 32) {
> 				ENSURE_ON_SCREEN(pixels[0][0], pixels[0][1]) {
> 					((Uint32 *) screen->pixels)[pixels[0][0] + (pixels[0][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[0][0], pixels[0][1], 1, 1);
> 				}
> 				ENSURE_ON_SCREEN(pixels[1][0], pixels[1][1]) {
> 					((Uint32 *) screen->pixels)[pixels[1][0] + (pixels[1][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[1][0], pixels[1][1], 1, 1);
> 				}
> 				ENSURE_ON_SCREEN(pixels[2][0], pixels[2][1]) {
> 					((Uint32 *) screen->pixels)[pixels[2][0] + (pixels[2][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[2][0], pixels[2][1], 1, 1);
> 				}
> 				ENSURE_ON_SCREEN(pixels[3][0], pixels[3][1]) {
> 					((Uint32 *) screen->pixels)[pixels[3][0] + (pixels[3][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[3][0], pixels[3][1], 1, 1);
> 				}
> 			} else if (screen_bpp == 16) {
> 				ENSURE_ON_SCREEN(pixels[0][0], pixels[0][1]) {
> 					((Uint16 *) screen->pixels)[pixels[0][0] + (pixels[0][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[0][0], pixels[0][1], 1, 1);
> 				}
> 				ENSURE_ON_SCREEN(pixels[1][0], pixels[1][1]) {
> 					((Uint16 *) screen->pixels)[pixels[1][0] + (pixels[1][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[1][0], pixels[1][1], 1, 1);
> 				}
> 				ENSURE_ON_SCREEN(pixels[2][0], pixels[2][1]) {
> 					((Uint16 *) screen->pixels)[pixels[2][0] + (pixels[2][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[2][0], pixels[2][1], 1, 1);
> 				}
> 				ENSURE_ON_SCREEN(pixels[3][0], pixels[3][1]) {
> 					((Uint16 *) screen->pixels)[pixels[3][0] + (pixels[3][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[3][0], pixels[3][1], 1, 1);
> 				}
> 			}
> 			if (d >= 0) {
> 				row--;
> 				d -= four_a_square * (row);
> 			}
> 			d += two_b_square * (3 + (col << 1));
> 			col++;
> 		}
> 		d = two_b_square * (col + 1) * col + two_a_square * (row * (row - 2) +
> 1) + (1 - two_a_square) * b_square;
> 		while((row) + 1) {
> 			/* plot the pixels */
> 			pixels[0][0] = col+x;
> 			pixels[0][1] = row+y;
> 			pixels[1][0] = col+x;
> 			pixels[1][1] = y-row;
> 			pixels[2][0] = x-col;
> 			pixels[2][1] = row+y;
> 			pixels[3][0] = x-col;
> 			pixels[3][1] = y-row;
> 			if (screen_bpp == 32) {
> 				ENSURE_ON_SCREEN(pixels[0][0], pixels[0][1]) {
> 					((Uint32 *) screen->pixels)[pixels[0][0] + (pixels[0][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[0][0], pixels[0][1], 1, 1);
> 				}
> 				ENSURE_ON_SCREEN(pixels[1][0], pixels[1][1]) {
> 					((Uint32 *) screen->pixels)[pixels[1][0] + (pixels[1][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[1][0], pixels[1][1], 1, 1);
> 				}
> 				ENSURE_ON_SCREEN(pixels[2][0], pixels[2][1]) {
> 					((Uint32 *) screen->pixels)[pixels[2][0] + (pixels[2][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[2][0], pixels[2][1], 1, 1);
> 				}
> 				ENSURE_ON_SCREEN(pixels[3][0], pixels[3][1]) {
> 					((Uint32 *) screen->pixels)[pixels[3][0] + (pixels[3][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[3][0], pixels[3][1], 1, 1);
> 				}
> 			} else if (screen_bpp == 16) {
> 				ENSURE_ON_SCREEN(pixels[0][0], pixels[0][1]) {
> 					((Uint16 *) screen->pixels)[pixels[0][0] + (pixels[0][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[0][0], pixels[0][1], 1, 1);
> 				}
> 				ENSURE_ON_SCREEN(pixels[1][0], pixels[1][1]) {
> 					((Uint16 *) screen->pixels)[pixels[1][0] + (pixels[1][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[1][0], pixels[1][1], 1, 1);
> 				}
> 				ENSURE_ON_SCREEN(pixels[2][0], pixels[2][1]) {
> 					((Uint16 *) screen->pixels)[pixels[2][0] + (pixels[2][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[2][0], pixels[2][1], 1, 1);
> 				}
> 				ENSURE_ON_SCREEN(pixels[3][0], pixels[3][1]) {
> 					((Uint16 *) screen->pixels)[pixels[3][0] + (pixels[3][1] *
> pitch_adjust)] = color;
> 					ensure_blitted(pixels[3][0], pixels[3][1], 1, 1);
> 				}
> 			}
> 			/* correct above code for book */
> 			if (d <= 0) {
> 				col++;
> 				d += four_b_square * col;
> 			}
> 			row--;
> 			d += two_a_square * (3 - (row << 1));
> 		}
> 		radius++;
> 	}
> 
> 	if (SDL_MUSTLOCK(screen))
> 		SDL_UnlockSurface(screen);
> }
-- 
Chris Thielen <chris at luethy.net>





More information about the SDL mailing list