Drawing Lines on different backgrounds
fatboy2

I am making a line using the following algorithm
The line starts from the point where I click the mouse and draws to wherever I point to.

while(!key[KEY_ESC])
{
if (mouse_b&1) {
int x = mouse_x;
int y = mouse_y;


while (mouse_b&1)
{

line(bmp, x, y, mouse_x,mouse_y,makecol(255,255, 255));
rest (10);

draw_sprite(buffer, bmp, 0, 0);
blit(buffer, screen, 0,0,0,0,1400,1050);
clear_bitmap(buffer);
clear_bitmap(bmp);
}
}
}

destroy_bitmap(buffer);
return 0;
}

The problem I have is that all lines get erased every time I draw a new one. I also want to be able to draw this line on various backgrounds. Any help would be greatly appreciated.

Kris Asick

The simplest way to achieve the effect you're aiming for is to use two buffers:

1. A buffer which holds what you want to show on the screen.
2. A buffer which holds the line you are drawing.

You are effectively doing that now, but your method relies on erasing the screen every time you update the line, so naturally, when you start a new one the old one disappears because it's using the same buffer to update the new line, and erasing it on every update.

So what you could do is draw the line to one buffer, draw the background buffer to the screen, then masked-blit the line buffer overtop. When you release the mouse button, you then masked-blit the line buffer onto the background buffer to make the line permanent.

You can go one step further and use three buffers to eliminate any shearing which may occur as a result. Thus what you would have is:

1. A buffer which holds what you've drawn so far.
2. A buffer which holds what you are currently drawing.
3. A buffer which holds the combination of the other two buffers so that the screen draw can be done in one operation.

If you're attempting to make a drawing program as I currently am, you're going to quickly gain an appreciation for how difficult they really are...

--- Kris Asick (Gemini)
--- http://www.pixelships.com

fatboy2

I got rid of some of the things that were unnecessary

while(!key[KEY_ESC])
{
if (mouse_b&1) {
int x = mouse_x;
int y = mouse_y;

while (mouse_b&1)
{
line(bmp, x, y, mouse_x,mouse_y,makecol(255,255, 255));
rest (10);
blit(bmp,buffer,0,0,0,0,1400,1050);
masked_blit(bmp, screen, 0,0,0,0,1400,1050);
clear_bitmap(bmp);
}
}
blit(buffer,screen,0,0,0,0,1400,1050);
}
I do not really get how to copy the line from bmp to screen. I also tried to create an intermediate bitmap that holds all the lines that I draw. I think that the problem with my code is that it stops copying when I release the mouse button.]

EDIT
blit(buffer,screen,0,0,0,0,1400,1050); - I think that this is supposed to make the line permanent on the screen. But for some reason it does not work

Lucid Nightmare

use 2 buffers...
all the lines on one buffer and evrything including the line buffer on the main buffer.

bitmap to scrren-->

draw_sprite(screen,your buffername,0,0);

Indeterminatus

Please, use the code tags, they make your posts much easier to read. You can see how by clicking on "Help" where you write the post.

Neil Black
Thank goodness someone said something about the help tab, which I never noticed.
Now I can use code tags! Yay!

Kris Asick

Here's one method that might work. Haven't tested it, only spent five minutes writing it...

1BITMAP draw_buffer, screen_buffer;
2 
3while(!key[KEY_ESC])
4{
5 int initx = -999, inity = -999;
6 
7 blit(draw_buffer,screen_buffer,0,0,0,0,draw_buffer->w,draw_buffer->h);
8 
9 if (mouse_b & 1)
10 {
11 if (initx == -999)
12 {
13 initx = mouse_x;
14 inity = mouse_y;
15 }
16 
17 line(screen_buffer,initx,inity,mouse_x,mouse_y,makecol(255,255,255));
18 }
19 else if (initx != -999)
20 {
21 line(screen_buffer,initx,inity,mouse_x,mouse_y,makecol(255,255,255));
22 line(draw_buffer,initx,inity,mouse_x,mouse_y,makecol(255,255,255));
23 initx = -999;
24 }
25 
26 blit(screen_buffer,screen,0,0,0,0,draw_buffer->w,draw_buffer->h);
27 rest(1);
28}

I don't like that code, but it should do exactly what you want it to do. The reason I don't like it is because the method I use in my drawing program is a lot better, but about 20 times more complicated.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

fatboy2

Your code does not work the way I want it to because it does not have a while loop in it. With the if statement the line does not draw continuously, and as a result all i get are dots on the screen.

I have tried adding an extra if statement:

if(!mouse_b&1) {
blit(screen,screen_buffer,0,0,0,0,640,480);
blit(screen_buffer,screen,0,0,0,0,640,480);

}

This does not seem to work so please give some suggestions.
i really do not understand why the screen is cleared each time I start a new line

EDIT: I got it, the problem is with the way I copy things from one bitmap to the other. I did not really understand the stuff written in the manual about copying functions such as blit and masked_blit.
Please explain what blitting function I need to use to just copy pixels that are not black from one bitmap to the other.

Kris Asick

Black is subjective.

In 8-bit mode, palette entry #0 is almost always black, unless you change it. Thus if you change it, that becomes your new transparent colour.

In 15/16/24/32-bit mode, magic pink is the transparent colour. You can make this colour by calling makecol(255,0,255). If you want transparent areas on a bitmap in higher colour depths, it needs to be that colour.

To draw things onto the screen with transparent areas, you need to use masked_blit(), draw_sprite(), draw_character_ex(), or any of the other sprite-based drawing commands.

I checked the code I provided by the way. It's bugged, but very easy to fix. If you move the "int initx = -999, inity = -999;" line to just before the while loop begins, it works perfectly.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

fatboy2

I get it now, thanks a lot.
Is is possible to change the transparent color to something else instead of pink and how do I do it?

Kris Asick

Unfortunately, the mask colours are built from #define directives, which means the only way to make the transparency colour different is to create your own routine for blitting which accepts different transparency colours.

Though another method is to use 32-bit, alpha blended sprites, but Allegro's routines for doing that are not the fastest.

An old method for doing transparent blitting is to have two sprites, one which represents the sprite, another which represents the transparent areas called the mask. You then draw the mask to the screen using an AND binary operation and draw the sprite using an OR binary operation. Again though, Allegro doesn't have built-in features to accommodate this method of drawing.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Tobias Dammers
Quote:

Again though, Allegro doesn't have built-in features to accommodate this method of drawing.

It sort of does, using custom blenders, but I wouldn't recommend it.

Thread #590063. Printed from Allegro.cc