Sign in to follow this  

Clearing previously drawn pixels

This topic is 4810 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys, I'm new to this place, so Hi. I'm learning SDL. The first thing I'm doing is making a blood eninge. I ran into a problem though, the pixels I'm drawing for the blood explosion aren't going away. I know there is no update function, and I use UpdateRect for the whole screen too. But lets say that I draw a pixel somewhere. Next frame, when it goes somewhere else, it is still drawn at the privious place as well. This makes the blood never go away. Is there anything in here that is making the previous blood pixels remain?
#include "sdl.h"
#include <stdlib.h>
#include <time.h>
#include <memory.h>
#include <cmath>
#include <vector>

using namespace std;

#define RED 1
#define GREEN 2
#define BLUE 3


class Blood {
public:
    float x, y;
    float xvel, yvel;
    int life, color;

    //Blood *next;
};

vector<Blood*>bloods;

void CreateBlood(int x, int y, int angle, int intensity, int color);
void cleanup();
void cleanup2();
void UpdateBlood();
void Event();
void Input();
bool KeyDown(bool KeyFlag);
bool KeyHit(bool &KeyFlag);

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

SDL_Surface *DisplaySurface;
Blood *first_blood = NULL;
SDL_Event g_Event;

char *pixel_data;
//int* pixel_data;
int pixel_color;

int relative_angle;
int test_intensity = 5;
int test_angle = 0;
int max_bloodlife = 30;
float gravity = .4;

bool f_Up;
bool f_Down;
bool f_Left;
bool f_Right;
bool f_Space;
bool f_Escape; 

int main(int argc, char* argv[]) {
	bloods.clear();
    srand(time(NULL));

	if(SDL_Init(SDL_INIT_VIDEO) == -1) {
	    fprintf(stderr,"Could not initialize SDL!\n");
		exit(1);
	}
	else {
		fprintf(stdout,"SDL initialized properly!\n");
		atexit(SDL_Quit);
	}
	DisplaySurface = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,0,SDL_ANYFORMAT);
	SDL_ShowCursor(SDL_DISABLE); 
	if(!DisplaySurface) {
		fprintf(stderr,"Could not set up display surface!\n");
		exit(1);
	}

	int debug = 0;
	while(1) {
        
        Event();
		if (f_Escape)
			break;
		
		//check if surface needs locking
		if(SDL_MUSTLOCK(DisplaySurface)) {
			if(SDL_LockSurface(DisplaySurface) == -1) {
				fprintf(stderr,"Could not lock display surface!\n");
				cleanup();
				exit(1);
			}
		}
     
        UpdateBlood();
	    //update the screen
		SDL_UpdateRect(DisplaySurface,0,0,0,0);

	    if(SDL_MUSTLOCK(DisplaySurface)) 
		    SDL_UnlockSurface(DisplaySurface);

		Input();
		if(test_angle > 360)
			test_angle -= 360;
		if(test_angle < 360)
			test_angle += 360; 
	}
	cleanup();
	fprintf(stdout,"Terminating normally.\n");
	return 0;
}

void Event() {
    //wait for an event
    if(SDL_PollEvent(&g_Event) == 0) {
	    //No event, so do stuff.
        if(g_Event.key.keysym.sym == SDLK_ESCAPE) {
            SDL_Event quit;
            quit.type = SDL_QUIT;
            SDL_PushEvent(&quit);
		}

        switch(g_Event.type) {
            case SDL_KEYDOWN:
                switch(g_Event.key.keysym.sym) {
                    case SDLK_UP:
                        f_Up = true;
                        break;
                    case SDLK_DOWN:
                        f_Down = true;
                        break;
                    case SDLK_LEFT:
                        f_Left = true;
                        break;
                    case SDLK_RIGHT:
                        f_Right = true;
                        break;
                    case SDLK_SPACE:
                        f_Space = true;
                        break;
                    case SDLK_ESCAPE:
                        f_Escape = true;
                        break;
                }
                break;

            case SDL_KEYUP:
                switch(g_Event.key.keysym.sym) {
                    case SDLK_UP:
                        f_Up = false;
                        break;
                    case SDLK_DOWN:
                        f_Down = false;
                        break;
                    case SDLK_LEFT:
                        f_Left = false;
                        break;
                    case SDLK_RIGHT:
                        f_Right = false;
                        break;
                    case SDLK_SPACE:
                        f_Space = false;
                        break;
                    case SDLK_ESCAPE:
                        f_Escape = false;
                        break;
                }
                break;

            default:
                break;
			    
		} 
	} 
	else {
	    //event occurred, check for quit
		if(g_Event.type == SDL_QUIT) {
			SDL_Event quit;
            quit.type = SDL_QUIT;
            SDL_PushEvent(&quit);
		}
	}
}

void Input() {
	if(KeyDown(f_Up))
        test_intensity++;
    if(KeyDown(f_Down))
        test_angle -= 4;
    if(KeyDown(f_Left))
        test_intensity--;
    if(KeyDown(f_Right))
        test_angle += 4;
	if(KeyDown(f_Space))
        CreateBlood(320,240,test_angle,test_intensity,3);
}

void CreateBlood(int x, int y, int angle, int intensity, int color) {

	Blood* blood;

    for(int i = 0; i<=intensity; i++) {

		blood = NULL;

		if (!(blood = new Blood)) {
			fprintf(stdout, "Out of memory :(\n");
			cleanup();
			exit(3);
		}

        blood->x = x + (rand()%(-600+300))/100.00;
        blood->y = y + (rand()%(-600+300))/100.00;
        blood->life = rand()%(-(intensity/12+1));
	    relative_angle = angle + rand()%110 - 55;
	    blood->xvel = cos(relative_angle) * (intensity/(rand()%14 + 10));
	    blood->yvel = sin(relative_angle) * (intensity/(rand()%14 + 10));
		blood->color = color;

		bloods.push_back(blood);

    }
}

void cleanup() {
	vector<Blood*>::iterator rmvme = bloods.begin();

	cleanup2();
	while (rmvme != bloods.end()) {
		delete *rmvme;
		rmvme++;
	}
	bloods.clear();
}

void cleanup2() {
	vector<Blood*>::iterator rmvme = bloods.begin();

	while (rmvme != bloods.end()) {
		if (*rmvme == NULL) {
			bloods.erase(rmvme);
			rmvme = bloods.begin();
			continue;
		}
		rmvme++;
	}
}
		

void UpdateBlood() {

	//Blood **blood_p = &first_blood;
	vector<Blood*>::iterator curBloodIt = bloods.begin();
	Blood* curBlood;
	unsigned int numBloods = 0;

	while(/*curBloodIt != bloods.end()*/numBloods < bloods.size()) {

		curBlood = bloods.at(numBloods);
		if (!curBlood) {
			cleanup2();
			numBloods = 0;
			continue;
		}

		if(curBlood->life == 0)
		{
			delete curBlood;
			bloods.at(numBloods) = NULL;
		}
		else
		{
			curBlood->x += curBlood->xvel;
			curBlood->y += curBlood->yvel;
			curBlood->yvel += gravity;

			if (curBlood->x >= SCREEN_WIDTH || curBlood->x <= 0)
				curBlood->life = 0;
			if (curBlood->y >= SCREEN_HEIGHT || curBlood->y <= 0)
				curBlood->life = 0;
			if (curBlood->life == 0) {
				delete curBlood;
				bloods.at(numBloods) = NULL;
				continue;
			}

			pixel_color = SDL_MapRGB(DisplaySurface->format, 255, 0, 0);
			
			/*if(curBlood->color == RED)
			    pixel_color = SDL_MapRGB(DisplaySurface->format, 255-(max_bloodlife - curBlood->life)*8, 0, 0);
			if(curBlood->color == GREEN)
			    pixel_color = SDL_MapRGB(DisplaySurface->format, 0, 255-(max_bloodlife - curBlood->life)*8, 0);
			if(curBlood->color == BLUE)
			    pixel_color = SDL_MapRGB(DisplaySurface->format, 0, 0, 255-(max_bloodlife - curBlood->life)*8);*/

			//grab pixel pointer
			pixel_data = (char*)DisplaySurface->pixels;
			
			//vertical offset
			pixel_data += ((unsigned int)curBlood->y * DisplaySurface->pitch);
			
			//horizontal offset
			pixel_data += ((unsigned int)curBlood->x * DisplaySurface->format->BytesPerPixel);

			//copy from color to frame buffer
			memcpy(pixel_data,&pixel_color,DisplaySurface->format->BytesPerPixel);
			//memcpy(pixel_data,&pixel_color,sizeof(int));

			curBloodIt++;
		}
		numBloods++;
	}
}

bool KeyDown(bool KeyFlag) {
    return KeyFlag;
}

bool KeyHit(bool &KeyFlag) {
    if(KeyFlag == true) {
        KeyFlag = false;
        return true;
    }
    return false;
}

Seriously, it isn't that complicated. You don't need to look through it all or anything. Just look at the updaterect and pixel drawing and lemme know if I've done something wrong. I've also had another terrible thing happen. I don't know when, because I've never gotten this error, but my .Exe randomly started requiring a WHOLE bunch of extra .DLL files besides SDL.dll. If I run it on a computer tha doesn't have Visual C++ installed, I get all sorts of errors becasue MSVCPD06.DLL wasn't found or something. Then, when I upload that, it needs another .DLL and I have no clue why that's happening. Do you think these random required .DLL additions are just screwed compiler settings? Any help would REALLY be appreciated!

Share this post


Link to post
Share on other sites
Please use the source tags, like this:


#include "sdl.h"
#include <stdlib.h>
#include <time.h>
#include <memory.h>
#include <cmath>
#include <vector>

using namespace std;

#define RED 1
#define GREEN 2
#define BLUE 3


class Blood {
public:
float x, y;
float xvel, yvel;
int life, color;

//Blood *next;
};

vector<Blood*>bloods;

void CreateBlood(int x, int y, int angle, int intensity, int color);
void cleanup();
void cleanup2();
void UpdateBlood();
void Event();
void Input();
bool KeyDown(bool KeyFlag);
bool KeyHit(bool &KeyFlag);

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

SDL_Surface *DisplaySurface;
Blood *first_blood = NULL;
SDL_Event g_Event;

char *pixel_data;
//int* pixel_data;
int pixel_color;

int relative_angle;
int test_intensity = 5;
int test_angle = 0;
int max_bloodlife = 30;
float gravity = .4;

bool f_Up;
bool f_Down;
bool f_Left;
bool f_Right;
bool f_Space;
bool f_Escape;

int main(int argc, char* argv[]) {
bloods.clear();
srand(time(NULL));

if(SDL_Init(SDL_INIT_VIDEO) == -1) {
fprintf(stderr,"Could not initialize SDL!\n");
exit(1);
}
else {
fprintf(stdout,"SDL initialized properly!\n");
atexit(SDL_Quit);
}
DisplaySurface = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,0,SDL_ANYFORMAT);
SDL_ShowCursor(SDL_DISABLE);
if(!DisplaySurface) {
fprintf(stderr,"Could not set up display surface!\n");
exit(1);
}

int debug = 0;
while(1) {

Event();
if (f_Escape)
break;

//check if surface needs locking
if(SDL_MUSTLOCK(DisplaySurface)) {
if(SDL_LockSurface(DisplaySurface) == -1) {
fprintf(stderr,"Could not lock display surface!\n");
cleanup();
exit(1);
}
}

UpdateBlood();
//update the screen
SDL_UpdateRect(DisplaySurface,0,0,0,0);

if(SDL_MUSTLOCK(DisplaySurface))
SDL_UnlockSurface(DisplaySurface);

Input();
if(test_angle > 360)
test_angle -= 360;
if(test_angle < 360)
test_angle += 360;
}
cleanup();
fprintf(stdout,"Terminating normally.\n");
return 0;
}

void Event() {
//wait for an event
if(SDL_PollEvent(&g_Event) == 0) {
//No event, so do stuff.
if(g_Event.key.keysym.sym == SDLK_ESCAPE) {
SDL_Event quit;
quit.type = SDL_QUIT;
SDL_PushEvent(&quit);
}

switch(g_Event.type) {
case SDL_KEYDOWN:
switch(g_Event.key.keysym.sym) {
case SDLK_UP:
f_Up = true;
break;
case SDLK_DOWN:
f_Down = true;
break;
case SDLK_LEFT:
f_Left = true;
break;
case SDLK_RIGHT:
f_Right = true;
break;
case SDLK_SPACE:
f_Space = true;
break;
case SDLK_ESCAPE:
f_Escape = true;
break;
}
break;

case SDL_KEYUP:
switch(g_Event.key.keysym.sym) {
case SDLK_UP:
f_Up = false;
break;
case SDLK_DOWN:
f_Down = false;
break;
case SDLK_LEFT:
f_Left = false;
break;
case SDLK_RIGHT:
f_Right = false;
break;
case SDLK_SPACE:
f_Space = false;
break;
case SDLK_ESCAPE:
f_Escape = false;
break;
}
break;

default:
break;

}
}
else {
//event occurred, check for quit
if(g_Event.type == SDL_QUIT) {
SDL_Event quit;
quit.type = SDL_QUIT;
SDL_PushEvent(&quit);
}
}
}

void Input() {
if(KeyDown(f_Up))
test_intensity++;
if(KeyDown(f_Down))
test_angle -= 4;
if(KeyDown(f_Left))
test_intensity--;
if(KeyDown(f_Right))
test_angle += 4;
if(KeyDown(f_Space))
CreateBlood(320,240,test_angle,test_intensity,3);
}

void CreateBlood(int x, int y, int angle, int intensity, int color) {

Blood* blood;

for(int i = 0; i<=intensity; i++) {

blood = NULL;

if (!(blood = new Blood)) {
fprintf(stdout, "Out of memory :(\n");
cleanup();
exit(3);
}

blood->x = x + (rand()%(-600+300))/100.00;
blood->y = y + (rand()%(-600+300))/100.00;
blood->life = rand()%(-(intensity/12+1));
relative_angle = angle + rand()%110 - 55;
blood->xvel = cos(relative_angle) * (intensity/(rand()%14 + 10));
blood->yvel = sin(relative_angle) * (intensity/(rand()%14 + 10));
blood->color = color;

bloods.push_back(blood);

}
}

void cleanup() {
vector<Blood*>::iterator rmvme = bloods.begin();

cleanup2();
while (rmvme != bloods.end()) {
delete *rmvme;
rmvme++;
}
bloods.clear();
}

void cleanup2() {
vector<Blood*>::iterator rmvme = bloods.begin();

while (rmvme != bloods.end()) {
if (*rmvme == NULL) {
bloods.erase(rmvme);
rmvme = bloods.begin();
continue;
}
rmvme++;
}
}


void UpdateBlood() {

//Blood **blood_p = &first_blood;
vector<Blood*>::iterator curBloodIt = bloods.begin();
Blood* curBlood;
unsigned int numBloods = 0;

while(/*curBloodIt != bloods.end()*/numBloods < bloods.size()) {

curBlood = bloods.at(numBloods);
if (!curBlood) {
cleanup2();
numBloods = 0;
continue;
}

if(curBlood->life == 0)
{
delete curBlood;
bloods.at(numBloods) = NULL;
}
else
{
curBlood->x += curBlood->xvel;
curBlood->y += curBlood->yvel;
curBlood->yvel += gravity;

if (curBlood->x >= SCREEN_WIDTH || curBlood->x <= 0)
curBlood->life = 0;
if (curBlood->y >= SCREEN_HEIGHT || curBlood->y <= 0)
curBlood->life = 0;
if (curBlood->life == 0) {
delete curBlood;
bloods.at(numBloods) = NULL;
continue;
}

pixel_color = SDL_MapRGB(DisplaySurface->format, 255, 0, 0);

/*if(curBlood->color == RED)
pixel_color = SDL_MapRGB(DisplaySurface->format, 255-(max_bloodlife - curBlood->life)*8, 0, 0);
if(curBlood->color == GREEN)
pixel_color = SDL_MapRGB(DisplaySurface->format, 0, 255-(max_bloodlife - curBlood->life)*8, 0);
if(curBlood->color == BLUE)
pixel_color = SDL_MapRGB(DisplaySurface->format, 0, 0, 255-(max_bloodlife - curBlood->life)*8);*/


//grab pixel pointer
pixel_data = (char*)DisplaySurface->pixels;

//vertical offset
pixel_data += ((unsigned int)curBlood->y * DisplaySurface->pitch);

//horizontal offset
pixel_data += ((unsigned int)curBlood->x * DisplaySurface->format->BytesPerPixel);

//copy from color to frame buffer
memcpy(pixel_data,&pixel_color,DisplaySurface->format->BytesPerPixel);
//memcpy(pixel_data,&pixel_color,sizeof(int));

curBloodIt++;
}
numBloods++;
}
}

bool KeyDown(bool KeyFlag) {
return KeyFlag;
}

bool KeyHit(bool &KeyFlag) {
if(KeyFlag == true) {
KeyFlag = false;
return true;
}
return false;
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I was having a similiar issue
I remember that in D3D and OGL before rendering I would clear the screen to all black
so I did the same in SDL and it worked

SDL_FillRect(SDL_GetVideoSurface(), NULL, SDL_MapRGB(SDL_GetVideoSurface()->format, 0,0,0));

Share this post


Link to post
Share on other sites
efoday has the right idea.

thankgoodness you haven't been tainted by qbasic, otherwise you might be tempted to ask for the CLS equivilant.

when you have enough objects, clearing the screen isn't an issue. ususaly you will overwrite all of the previous garbage with new data.

essentially using a filled rect...

Share this post


Link to post
Share on other sites

This topic is 4810 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this