Paint program help - drawing rectangles, restoring
BlitzMax Forums/BlitzMax Beginners Area/Paint program help - drawing rectangles, restoring
| ||
I'm trying to write a simple drawing program like MS-Paint, just to learn Blitzmax. I'm a bit stuck though. Imagine the user has drawn a load of stuff on the screen. Now the user draws a rectangle by clicking and dragging the mouse button. As the user moves the mouse with the button down, the rectangle can grow or shrink until the button is released. I can draw the rectangle fine but how to I restore the stuff behind the rectangle if the user shrinks the size of the rectangle? I've tried copying the whole screen into a buffer and restoring that before redrawing the rectangle but it doesn't seem to work. Is this the best approach? (I'm using regular Max2D functions) Thanks |
| ||
I'm guessing you're not using cls. How about... 1) cls 2) Draw background 3) Draw rect 4) loop to 1) When the mouse is released for drawing the rectangle then make that part of the background. |
| ||
I wonder whether restoring a part of the screen (where you're editing) is more clever. I recently made some testprogram which had a 512x512 canvas, drawing an even larger image on it with some selector rect over it @ event x/y. The movement was quite slugish, caused by redrawing the whole image again and again.. (98se, amd 2ghz, geforce4mx) |
| ||
Thanks for the replies: tonyg That's neat and you're right I'm not using CLS. Practically I can't find a way of storing the background before the rect is being drawn, which is kind of my problem. Should I just store the whole canvas into a buffer and then re-store the canvas in the buffer after the mouse is released? so 1. CLS 2. Draw contents of buffer on canvas (DrawImage) 3. Draw rect 4. Flip 5. Loop to 1 When mouse is released store canvas using GrabImage. on a hires screen that can be a massive canvas to grab and draw each loop. Thanks |
| ||
There is no point considering only restoring the part of the screen which you are `uncovering` by shrinking the rectangle, because with every frame, the entire backbuffer is wiped or relocated and basically does not keep its contents. After every Flip you have to completely redraw the entire screen anyway, so trying to only restore the part that changed won't save you any time. That technique would have been useful if the backbuffer were being kept, or if you were rendering it in main memory with custom drawing routines, but with the way Max is set up using OpenGL there is no point. As was mentioned, you start off, draw stuff, grab it into an image, then use that same image for the duration of scaling the rectangle - each frame draw the whole screen image, draw the rectangle at the appropriate size, then flip. That's all. If you do away with the backbuffer, which may be a possibility, and render directly to the `front` buffer, it might possibly be useful to preserve some of the background and restore only the parts being seen. It's questionable whether you really need a double buffered system for a paint program. |
| ||
OK thanks everyone. I got it working - well under Windows anyway. It seems I had it working already, I just didn't know it as there seems to be a bug in the Blitzmax Linux version. The same code works under one OS and not the other. Thanks again for your help. I'll post the code here just incase anyone can spot the problem. It's the drawimage line with the *** comment ** that causes problems under Linux, an exception error occurs. -------- cut here ---------------------------- Strict ' ------------ vars -------------------- ' Screen res Local screenwidth=800 Local screenheight=600 ' Mouse coords Global ox,oy, mx, my ' shape Local width, height ' Colour Global red, green, blue ' types of tools Const PEN=1, RECTANGLE=2 ' current tool Local currenttool = PEN ' holds current keypress Local key 'set graphics mode 'Graphics screenwidth,screenheight,16 Graphics screenwidth,screenheight,0 ' set a buffer up big enough to hold the whole screen (so we can restore the image during drawing ops such as rectangle Local screenbuf:timage = CreateImage(screenwidth,screenheight) ' ------------ main loop -------------------- red = 255 green = 100 blue = 100 'set the default colour SetColor (red,green, blue) ' take an initial snapshot of the canvas GrabImage screenbuf,0,0 While Not KeyHit(KEY_ESCAPE) ' See if key has been pressed or a tool clicked on key = GetChar() Select key ' p or P pressed, PEN mode Case 80 currenttool = PEN Case 112 currenttool = PEN ' r or R pressed, RECTANGLE mode Case 82 currenttool = RECTANGLE Case 114 currenttool = RECTANGLE End Select 'update previous mouse coords ox = MouseX() oy = MouseY() ' Left mouse button pressed While MouseDown(1) ' Get mouse coords mx = MouseX() my = MouseY() Select currenttool Case PEN 'Plot a pixel Plot mx,my Case RECTANGLE ' draw a rect width = mx-ox If width < 0 Then width = 1 height = my-oy If height < 0 Then height = 1 Cls ' **** comment/uncomment this next line for a crash under linux ***** DrawImage screenbuf ,0,0,0 DrawRect(ox,oy,width,height) End Select ' Flip the buffers Flip EndWhile Select currenttool Case RECTANGLE ' take a snapshot of the screen proir to the next draw operation if drawing rects, ovals etc GrabImage screenbuf,0,0,0 End Select ' end of main loop Wend |