draw to a BITMAP* argument - allegro and objects again [Archive] - C Board

PDA

View Full Version : draw to a BITMAP* argument - allegro and objects again


MadHatter
12-10-2002, 01:29 PM
was allegro just not meant to be used with classes, or what? :rolleyes:

okay.. so i've got a player class that has all the data for a player (x and y positions, bitmap to use, functions for walking, jumping, shooting, etc). i had it before so that the background (just a bitmap that has some backgroundish stuff on it) was loaded and displayed in the player class (that is, i would draw the player and background to the buffer, then blit the buffer to the screen). however, i decided if i was going to have enemy classes, and things like that, then i should make the redraw function just draw the character to a buffer (pass as an arguement), and then draw the background to the buffer and blit to the screen in the main program. but i can't get it to work... here's some code


//*******in the player.cpp*******
void player::redraw(BITMAP *Buffer)
{
draw_sprite(Buffer, character, xpos, ypos); //draw character
}
//that's really the only important part... character is a bitmap that has the character,
//and xpos and ypos are pretty self explainitory(sp?).

//*******in main.cpp*******
BITMAP
*Buffer,
*bckgrnd;
//these bitmaps get loaded in a setup function

int main()
{
setup(); //initializes everything
while(!key[KEY_ESC])
{
clear_bitmap(Buffer); //clear buffer
plr1.redraw(Buffer); //should draw the character to Buffer, but doesn't
draw_sprite(Buffer, bckgrnd, 0, 0); //draw bckgrnd to Buffer
blit(Buffer, screen, 0, 0, 0, 0, 640, 480); //blit to screen
}

return 0;
}


any ideas what's going wrong? i made a function in main.cpp where it was passed a BITMAP* and did the same thing as the redraw() in player, and it worked fine, so it should be possible to do this..

help is appreciated.

Travis Dane
12-11-2002, 04:38 PM
Have you tried making the bitmap BUFFER global?
(Allegro is written in c so don't expect classes)

MadHatter
12-11-2002, 04:51 PM
global.. where? i have two different files.. player.cpp and main.cpp, so which should i declare it in? (sorry if it's a newbish question.. this is my first time working with multiple files :p )

if i blit the Buffer to the screen in the player::redraw function, it shows the character, so i know it's changing Buffer... it just isn't sending the changes back to main, or something.

TechWins
12-11-2002, 05:41 PM
What is the error that you're getting? I'm pretty sure I know what's wrong, but I want to make sure.

Btw, I'm going to be leaving for right now, so I won't be able to help you right away. Don't know if that matters to you much or not.

MadHatter
12-11-2002, 06:07 PM
i don't get an error. the things (that should be) drawn to Buffer in player::redraw just don't show up on the screen.
no worries if replies take a while.. i'm glad to get them at all ;)

TechWins
12-12-2002, 12:39 AM
Yes, the character is being drawn to the Buffer but to the wrong one. Look at how you set it up...Your passing the Buffer in main.cpp to the function player::redraw(BITMAP *Buffer). The Buffer inside player::redraw(BITMAP *Buffer) now is the same as the Buffer in main.cpp, which is want you want. But inside player::redraw(BITMAP *Buffer) you're drawing the character to the Buffer of player::redraw(BITMAP *Buffer) and not to the Buffer in main.cpp. To solve this you need to make the Buffer global and get read of passing the Buffer value to player::redraw(BITMAP *Buffer). Here's how you should do it...


/*** bitmap_load.h ***/
#ifndef _BITMAP_LOAD_H_
#define _BITMAP_LOAD_H_

#include <allegro.h>

extern BITMAP *Buffer;

void bitmap_loading();

#endif
///////////////////////////////////

/*** bitmap_load.cpp ***/
#include <allegro.h>
#include "bitmap_load.h"

BITMAP *Buffer;

void bitmap_loading()
{
Buffer = create_bitmap(SCREEN_W, SCREEN_H);
}
////////////////////////////////////////

/*** player.cpp ***/
#include "bitmap_load.h"

void player::redraw()
{
draw_sprite(Buffer, character, xpos, ypos); //draw character
}
/////////////////////////////////////////

/*** main.cpp ***/
#include <allegro.h>
#include "bitmap_load.h"
#include "player.h"

BITMAP *bckgrnd;

int main()
{
setup(); //initializes everything
bitmap_loading();

while(!key[KEY_ESC])
{
clear_bitmap(Buffer); //clear buffer
draw_sprite(Buffer, bckgrnd, 0, 0); /*you're going to want
the background here and not below b/c you want the background
to not cover the character*/
plr1.redraw(); /*no longer have to waste valuable process
time by passing the buffer*/
blit(Buffer, screen, 0, 0, 0, 0, 640, 480); //blit to screen
}

return 0;
}
END_OF_MAIN();
///////////////////////////////////////////


There you go, that should solve everything. Just to let you know, I would declare all of your bitmaps in bitmap_load.h and load all of them in bitmap_loading.

fry
12-12-2002, 12:43 AM
Why are you drawing the background after the player? Are you sure the player isnt being drawn over? In every other game, the background is drawn BEFORE the objects on top. Of course, this may not be like every other game ;) But it seems wrong to me.

Also, it doesn't really matter too much, but why are you drawing the background as a sprite, rather than blitting it?

TechWins
12-12-2002, 12:46 AM
Why are you drawing the background after the player?

Yeah, that was one of the problems in the code, but it wasn't the main reason why the character wasn't showing up.

Also, yeah, blitting the bckgrnd might be better. Typically I only draw_sprite for small bitmaps (i.e. sprites).

MadHatter
12-12-2002, 02:18 AM
:eek: :eek: :eek: *smashes head through monitor*

the problem was that i was drawing the background over the character.. my god, i can't believe i did that. maybe i'll used TechWin's way, just because he took the time to write it ;)

terribly sorry for all this.. should have looked over my code better :rolleyes: thanks very much for the replies tho!

(i'll keep the blitting of background thing in mind, too)

fry
12-12-2002, 04:02 AM
Sorry Tech ;) i must have been replying when you were posting yours, so i didnt see your post :)

Edit: Actually, i went through your logic that it was the wrong "Buffer" that he was drawing to, but i don't think that is correct. It seemed to me that he was passing the Buffer correctly, and so it should have drawn to the correct bitmap. Thats how i draw in my programs.

Also, i was sure that "extern" was buried by most people ;)

And how much time is actually saved by declaring 'Buffer' globally? I guess it would add up with many calls, but is it sufficient enough to worry about?

TechWins
12-12-2002, 04:20 PM
Actually, i went through your logic that it was the wrong "Buffer" that he was drawing to, but i don't think that is correct

His method couldn't possibly correct.:confused:

it's just like saying this is right for getting a new value on x...


/***function.cpp***/

void pass_val(int x)
{
x++;
cout << x << endl;
}
//////////////////////

/*** main.cpp **/
#include "function.h"

int x=3

int main()
{
pass_val(x);
cout << x << endl;

return 0;
}
///////////////////////////


If MadHatter's method were correct, then the output would be

4
4

But of course that's not right. The output is...

4
3

The x in main.cpp is never changed, only the x in pass_val(int x) is changed. This is the same case in MadHatter's code wtih Buffer. The Buffer in main.cpp is not being changed in player.cpp, it's only having it's data being passed to the function in player.cpp. If it actually is working for some reason then all of my logic is completely failed, and I'm going to go kill myself (well not really but yeah...).

And yes passing the Buffer is going to give a significant decrease on the FPS. I highly suggest using my way for two reasons 1) your way shouldn't work and 2) passing the Buffer is too time costly.

MadHatter
12-12-2002, 06:23 PM
actually, my way is more like this


/***function.cpp***/
void pass_val(int *x) //pass a pointer to x (as i passed a pointer to Buffer)
{
*x++;
cout << x << endl;
}
//////////////////////
/*** main.cpp **/
#include "function.h"
int x=3
int main()
{
pass_val(&x);
cout << x << endl;
return 0;
}
///////////////////////////


in redraw, the argument is 'BITMAP *Buffer'. Buffer is a pointer, so i'm only passing an address. no need to kill yerself ;) in fact, please don't.. you come in handy sometimes :p

TechWins
12-12-2002, 11:40 PM
no need to kill yerself in fact, please don't.. you come in handy sometimes

Ah, geeze I don't know what I was thinking.:confused:

fry
12-13-2002, 06:51 AM
Ah, geeze I don't know what I was thinking.
As long as we are all sorted out, and i know that my way works how it should :)