Posts: 652
Threads: 96
Joined: Apr 2022
Reputation:
22
I have the few lines of code below, which draw a shape on the screen.
How do I implement a "Paint" (or P in a draw-string) to paint the inside of the shape, say red (_RGB(255,0,0) ?
Code: (Select All) Screen _NewImage(1200, 820, 32)
Dim colr As _Unsigned Long: colr = _RGB(255, 0, 0)
colr = _RGB(0, 255, 255)
PSet (500, 300): Draw "C" + Str$(colr) + "R100F100D100G100L100H100U100E100"
Posts: 1,586
Threads: 59
Joined: Jul 2022
Reputation:
52
06-27-2023, 10:54 AM
(This post was last modified: 06-27-2023, 10:59 AM by mnrvovrfc.)
Unfortunately, painting is a headache in this programming language, and especially if you want to use 32-bit color. :/
First you have to make absolutely sure the shape is closed. If not the painting would take over the whole screen or, less often, other screen elements that could ruin your landscape or portrait.
It's better to forget about "P" command for DRAW for 32-bit color because it's confusing, "C" already requires specific LONG integer values and otherwise this programming system is very good yelling "Illegal function call" back at you if it doesn't like a value. You have the border color already in a variable called "colr". Assuming the color you want to paint with is called "paintcolr" then the code could be added like this:
Code: (Select All) DIM paintcolr AS LONG
paintcolr = _RGB(255, 0, 0)
PAINT(501, 301), paintcolr, colr
The POINT TO SELECT TO PAINT is very important. I had to deduce it from your code which seems to draw an octagon and begins from the top-left corner. Figuring out the point inside the closed figure to paint is a science in itself in BASIC graphics programming.
I suppose you could use STR$() to force the _RGB() values that you want for "P" command for DRAW but using PAINT is more concise. Otherwise would have to use POINT(0) and POINT(1) to obtain the X,Y coordinates of the DRAW "pen" but it's not reliable. Irritatingly the Wiki page on POINT() says nothing about DRAW.
This is a quick silly program that I wrote demonstrating POINT(0) and POINT(1):
Code: (Select All)
SCREEN 12
LOCATE 1, 1
PRINT POINT(0), POINT(1)
DRAW "s16fbdbrdhdbehebddhfbdhrbebuh"
LOCATE 2, 1
PRINT POINT(0), POINT(1)
END
It is verified the first X,Y coordinates shown is the middle of the screen.
Posts: 276
Threads: 14
Joined: Apr 2022
Reputation:
27
Code: (Select All) SCREEN _NEWIMAGE(1200, 820, 32)
DIM colr AS _UNSIGNED LONG: colr = _RGB(255, 0, 0)
colr = _RGB(0, 255, 255)
PSET (500, 300): DRAW "C" + STR$(colr) + "R100F100D100G100L100H100U100E100"
PAINT STEP(10, 10), colr
As it happens, a straight paint after stepping into the shape works in this case, but mnrvovrfc is correct in that it requires a "manifold" (aka water tight) shape, or paint will over write the entire screen. It can be a difficult standard to hit sometimes.
Also, knowing which way to step the graphics cursor into a shape (as I did above) for paint insertion can be tricky if there are rotations or movements going on in a program. Paint is slow to implement, so if you need speed, it's probably better to define a painted shape as a discrete image at program startup and then _putimage it as needed.
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Posts: 1,272
Threads: 119
Joined: Apr 2022
Reputation:
100
06-27-2023, 11:56 AM
(This post was last modified: 06-27-2023, 11:58 AM by TerryRitchie.)
You can do the painting right on the default screen or on a work screen.
Try not to think in terms of needing to paint the object. Many times I'll simply paint an entire work screen, draw my object, then paint OUTSIDE the object to get the effect I need. Code below shows a few examples:
Code: (Select All)
SCREEN _NEWIMAGE(1200, 820, 32)
' Do the painting on the default screen (_DEST 0)
CLS , _RGB32(255, 0, 0) ' paint the entire screen first
DIM colr AS _UNSIGNED LONG: colr = _RGB(255, 0, 0)
colr = _RGB(0, 255, 255)
PSET (500, 300): DRAW "C" + STR$(colr) + "R100F100D100G100L100H100U100E100"
PAINT (0, 0), _RGB32(0, 0, 0), colr ' paint the screen black until cyan is met
SLEEP
' Do the painting on a work screen that gets copied to the default screen.
CLS
PRINT
PRINT " This is the default screen _DEST 0"
PRINT " The work screen will not wipe this text out"
WorkScreen& = _NEWIMAGE(1200, 820, 32)
_DEST WorkScreen& ' all graphics command sent to work screen
CLS , _RGB32(255, 0, 0) ' paint the entire work screen first
PSET (500, 300): DRAW "C" + STR$(colr) + "R100F100D100G100L100H100U100E100"
PAINT (0, 0), _RGB32(0, 0, 0), colr ' paint the work screen black until colr met
_CLEARCOLOR _RGB32(0, 0, 0) ' make black on the work screen transparent
_DEST 0 ' go back to default screen
_PUTIMAGE , WorkScreen&, 0 ' copy the work screen to the default screen
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Posts: 3,965
Threads: 176
Joined: Apr 2022
Reputation:
219
When object overlaps another you can paint to Border Color of object inside or out, as:
Code: (Select All) Paint (x, y), color~&, toBorderColor~&
as the toBorderColor option parameter has been fixed!, if I recall our updates to QB64 correctly.
As already mentioned, make sure the object is enclosed by border inside the screen, no gaps or holes.
b = b + ...
Posts: 246
Threads: 44
Joined: May 2022
Reputation:
28
If for drawing you need to coloring an object that does not have color borders in the same color, use my Paint2 here: https://qb64phoenix.com/forum/showthread.php?tid=1507
Posts: 246
Threads: 44
Joined: May 2022
Reputation:
28
@PhilofPerth
Do you need the exact same shape in red?
In this way you can save to memory more images - and then place it using _PutImage - it is fastest method.
Code: (Select All)
'how create more images from one in different colors
Dim Images(3) As Long
Screen _NewImage(1200, 820, 32)
Dim colr As _Unsigned Long: colr = _RGB(255, 0, 0)
For ImageCreate = 0 To 3
Select Case ImageCreate
Case 0: R = 0: G = 255: B = 255
Case 1: R = 255: G = 255: B = 255
Case 2: R = 255: G = 255: B = 0
Case 3: R = 0: G = 0: B = 255
End Select
Images(ImageCreate) = _NewImage(1200, 820, 32)
_Dest Images(ImageCreate)
colr = _RGB(R, G, B)
PSet (500, 300): Draw "C" + Str$(colr) + "R100F100D100G100L100H100U100E100"
Next
_Dest 0
For ImageView = 0 To 3
Cls
_PutImage , Images(ImageView), 0
Print "Press any key for next image..."
Sleep
Next
Posts: 246
Threads: 44
Joined: May 2022
Reputation:
28
06-27-2023, 02:39 PM
(This post was last modified: 06-27-2023, 02:40 PM by Petr.)
And in this way you fill your images with color:
Code: (Select All)
Dim Images(3) As Long
Screen _NewImage(1200, 820, 32)
Dim colr As _Unsigned Long: colr = _RGB(255, 0, 0)
For ImageCreate = 0 To 3
Select Case ImageCreate
Case 0: R = 0: G = 255: B = 255
Case 1: R = 255: G = 255: B = 255
Case 2: R = 255: G = 255: B = 0
Case 3: R = 0: G = 0: B = 255
End Select
C$ = Str$(_RGB(R, G, B))
Images(ImageCreate) = _NewImage(1200, 820, 32)
_Dest Images(ImageCreate)
colr = _RGB(R, G, B)
PSet (500, 300): Draw "C" + Str$(colr) + "R100 F100 D100 G100 L100 H100 U100 E100 BD50 P" + C$ + "," + C$
Next
_Dest 0
For ImageView = 0 To 3
Cls
_PutImage , Images(ImageView), 0
Print "Press any key for next image..."
Sleep
Next
You must not forget to move the graphic cursor back to the filled area (in this case I am moving 50 pixels down the BD50 part)
Posts: 345
Threads: 24
Joined: Jul 2022
Reputation:
20
Hi
all different and working ways
but P of draw is not so bad
Draw wiki page
and taking the example 4
Code: (Select All) SCREEN 12
DO
LOCATE 1, 1: INPUT "Enter a number 0 to 9: ", num
CLS
SELECT CASE num
CASE 0, 2, 3, 5 TO 9: PSET (20, 20), 12
DRAW "E2R30F2G2L30H2BR5P12,12" 'top horiz
END SELECT
SELECT CASE num
CASE 0, 4 TO 6, 8, 9: PSET (20, 20), 12
DRAW "F2D30G2H2U30E2BD5P12,12" 'left top vert
END SELECT
SELECT CASE num
CASE 0, 2, 6, 8: PSET (20, 54), 12
DRAW "F2D30G2H2U30E2BD5P12, 12" 'left bot vert
END SELECT
SELECT CASE num
CASE 2 TO 6, 8, 9: PSET (20, 54), 12
DRAW "E2R30F2G2L30H2BR5P12, 12" 'middle horiz
END SELECT
SELECT CASE num
CASE 0 TO 4, 7 TO 9: PSET (54, 20), 12
DRAW "F2D30G2H2U30E2BD5P12,12" 'top right vert
END SELECT
SELECT CASE num
CASE 0, 1, 3 TO 9: PSET (54, 54), 12
DRAW "F2D30G2H2U30E2BD5P12,12" 'bottom right vert
END SELECT
SELECT CASE num
CASE 0, 2, 3, 5, 6, 8: PSET (20, 88), 12
DRAW "E2R30F2G2L30H2BR5P12,12" 'bottom horiz
END SELECT
LOOP UNTIL num > 9
it is clear that all previous tips told in this thread have been used.
P of DRAW works fine also in 32 bit color
here the same example using a screen 32 and a col$ _RGBA32
Code: (Select All) Screen _NewImage(1000, 800, 32)
Col$ = Str$(_RGBA32(222, 116, 44, 255))
paint$ = "P" + Col$ + "," + Col$
Do
Locate 1, 1: Input "Enter a number 0 to 9: ", num
Cls
Select Case num
Case 0, 2, 3, 5 To 9: PSet (20, 20), Val(Col$)
Draw "E2R30F2G2L30H2BR5" + paint$ 'top horiz
End Select
Select Case num
Case 0, 4 To 6, 8, 9: PSet (20, 20), Val(Col$)
Draw "F2D30G2H2U30E2BD5" + paint$ 'left top vert
End Select
Select Case num
Case 0, 2, 6, 8: PSet (20, 54), Val(Col$)
Draw "F2D30G2H2U30E2BD5" + paint$ 'left bot vert
End Select
Select Case num
Case 2 To 6, 8, 9: PSet (20, 54), Val(Col$)
Draw "E2R30F2G2L30H2BR5" + paint$ 'middle horiz
End Select
Select Case num
Case 0 To 4, 7 To 9: PSet (54, 20), Val(Col$)
Draw "F2D30G2H2U30E2BD5" + paint$ 'top right vert
End Select
Select Case num
Case 0, 1, 3 To 9: PSet (54, 54), Val(Col$)
Draw "F2D30G2H2U30E2BD5" + paint$ 'bottom right vert
End Select
Select Case num
Case 0, 2, 3, 5, 6, 8: PSet (20, 88), Val(Col$)
Draw "E2R30F2G2L30H2BR5" + paint$ 'bottom horiz
End Select
Loop Until num > 9
I remember an exercise of the Terry's tutorial to build a landscape with DRAW, another to create Basic shapes to use for landscape.
In this last case you will find very useful the function S (scale) of DRAW to get different size of the same shape.
Posts: 3,965
Threads: 176
Joined: Apr 2022
Reputation:
219
Code: (Select All)
Screen _NewImage(1200, 820, 32)
Dim colr As _Unsigned Long: colr = _RGB32(255, 0, 0)
colr = _RGB32(0, 255, 255)
PSet (500, 300): Draw "C" + Str$(colr) + "R100F100D100G100L100H100U100E100"
Paint (600, 410), &HFFFF0000, colr
b = b + ...
|