Help on a simple paint tool

Previous topic - Next topic

erico

Hello chaps, I was thinking about coding a very simple pixel paint tool.
Problem here is that I don´t want to draw colors but want to draw from a fixed pattern.

I will try to explain:

-The canvas is always 256x192.
-The "colors" are actually 256x192 fixed images.
-When I draw with these colors, I want to "reveal" them over my buffer.

In my mind, I´d have to GRABSPRITE the size/form of my brush from the "color" image and paste on the buffer.
...and that is what I´m failing to grasp. I also would like to avoid GRABSPRITE, for compatibility reasons and also that my brush may not actually be square.

Does anyone know a way to do this without having to create a havoc with sprite to mem?

In a general way, when I click mouse to draw, I should get my brush positon and check against a "color" image, grab that exact portion with alpha, and paste over my canvas.

UBERmonkeybot

#1
Mem2sprite and sprittomem? Perhaps utilising the alpha channel.

erico

That is what I wanted to avoid and was looking for a more simple solution.

UBERmonkeybot

Oh yeah sorry,I quickly scanned your message.

you could print your image then plot an array of black squares over it then delete them at cursor point  revealing the image underneath...
Unless i have totally misunderstood your request. :S

Slydog

#4
This might not be very fast, but you could draw your colored sprite first, then overlay it with another fully dark sprite. Wherever you click that sprite, on the dark sprite, use a SETPIXEL command at that pixel position with the color RGB(255,0,128) [which should make it transparent] to be able to view the underlaying colored pixel.

Does RGB() have an alpha channel parameter? I didn't see one in the manual.
It's been too long since I coded in GLBasic - I forget most of this!
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

dreamerman

canvas% sprite is your output
colors% sprite is base for brush
I will add 'brush% sprite' to this, that will be used for drawing on canvas

pseudo code:
Code (glbasic) Select

USESCREEN brush% //first draw on brush
ALPHAMODE 0.0 //disable alpha
draw_part_of_sprite from colors% with proper source position to brush% as simple rectangle
ALPHAMODE -1.0
draw_inverse_mask for brush shape on brush% with 0x008000FF color //32bit image with transparent brush shape and GLB pink as rest of image
USESCREEN canvas% //finally draw on canvas
ALPHAMODE -1.0
drawsprite brush% on proper position on canvas%

at least something like this if I understood correctly..
Check my source code editor for GLBasic - link Update: 20.04.2020

UBERmonkeybot

You got my brain going.

Code (glbasic) Select
// --------------------------------- //
// Project: revealPainter
// Start: Thursday, January 12, 2017
// IDE Version: 14.497


// SETCURRENTDIR("Media") // go to media files
SYSTEMPOINTER 1
GLOBAL array%[]
CONSTANT size=128
DIM array%[size*size]

GLOBAL back%=3000//GENSPRITE()


GLOBAL sc=5//GENSCREEN()
CREATESCREEN sc,back,size,size
USESCREEN sc
FOR q=0 TO 500
DRAWRECT RND(size),RND(size),10+RND(40),10+RND(40),RND(0xffffff)
NEXT

USESCREEN -1
DRAWSPRITE back,100,100

//IF
SPRITE2MEM(array%[],back)

GLOBAL newone%=2999//GENSPRITE()

MEM2SPRITE(array%[],newone,size,size)


LOCAL mx,my,b1,b2
FOR a=0 TO (size*size)-1
array%[a]=bAND(array%[a],0x00ffffff)
NEXT
LOCAL pos
LOCAL bs=10
REPEAT
MOUSESTATE mx,my,b1,b2
IF mx>size-bs THEN mx=size-bs
IF my>size-bs THEN my=size-bs
IF mx<=0 THEN mx=0
IF my<=0 THEN my=0
IF b1
FOR h =0 TO bs-1
FOR w=0 TO bs-1
//array[(my+h)*size+(mx+w)]=0x00000000
pos=(my+h)*size+(mx+w)
array%[pos]=bOR(array%[pos],0xff000000)
NEXT
NEXT
ENDIF
MEM2SPRITE(array%[],newone,size,size)

DRAWRECT 0,0,size+2,size+2,0xffffff
DRAWRECT 1,1,size,size,0


DRAWSPRITE newone,1,1

DRAWSPRITE back,size*1.2,2
PRINT "DRAW WITH LEFT MB IN THE PANE",0,size*1.2


SHOWSCREEN
UNTIL FALSE

MOUSEWAIT

mentalthink

Sorry Erico I don't understand too much the question (my bad english  :-[), if I'm not wrong you want get the color palette from the image?¿ and no use grabsprite. I thikn if you paint the image out the screen and then do something like getpixel WDxHG getting each color and putting into an array you can get all the colors of the image.

Sorry how I comment, I don't understood well the question.

UBERmonkeybot

I would assume getpixel would be realllllllly slow because it is reading from video memory.

Alex_R

I'd use polyvectors and the most important with POLYNEWSTRIP for fast performance solution. With one polyvector you can select the part of your pattern you want to draw. And you can zoom your canvas.

erico

#10
Gee, that is A LOT of help! Thenks everyone!
Mental, I was looking for exactly what the code posted by Monkeybot does.

I need brushes that will paint from a fixed pattern, I just am not that skilled enough to figure out quickly and I was a bit scared it was too hard and close to an unsolved subject we had some many moons ago about masks and alpha.

Monkeybot´s code seems to fit the bill, I took a quick look at it but will study it more later.

In case you guys want to know the use of it, here it is:

I want to do a very simple pixel art tool that will produce tandy color computer I and II images (coco).
The exact resolution of the image is 256x192 black and white, but on some systems and some tv, it will display artifact colors.
Here you can take a look at a general info:
https://en.wikipedia.org/wiki/TRS-80_Color_Computer#Artifact_colors

(edit: if you came from the apple II computers...you probably know what I mean as it had similar features when connected to a TV)

I have a bunch of black and white patterns and a fake artifact color patterns to match it.
Both must be fixed on screen, a single pixel off produces a whole different thing.

So I´m keeping 256x192 patterns of both and when I draw on screen I get to see the artifact while keeping a black and white buffer of a working image. Then I export that to the real hardware and voila! It should be close enough.

I think I´m not quite explaining this correctly but I will give a shot soon and we will see the results.
Thanks again for all the very usefull help and directions! There is a lot to learn here (heck...sprite to mem does not look that hard to use by your example and it is such a small code :O, super thanks!)

Here is an example image of the color and the B/W versions (coco max 2 running inside MOCHA)
I´m targeting some of the patterns you see on the lower parts.


UBERmonkeybot

#11
I will post a brush version soon but have been busy,you need to study up on logic gates and or xor, ery useful.
And binary math stuff.


UBERmonkeybot

New version with a tweak for custom brushes.

Code (glbasic) Select
// --------------------------------- //
// Project: revealPainter
// Start: Thursday, January 12, 2017
// IDE Version: 14.497


// SETCURRENTDIR("Media") // go to media files

GLOBAL brushW=14
GLOBAL brushH=7
GLOBAL brushStar[]
DIM brushStar[brushW*brushH]


//RESTORE square
RESTORE star
makeBrush(brushW,brushH)

SETSCREEN 800,600,0



SYSTEMPOINTER 1
GLOBAL array%[]
CONSTANT size=256
DIM array%[size*size]

GLOBAL back%=3000//GENSPRITE()


GLOBAL sc=5//GENSCREEN()
CREATESCREEN sc,back,size,size
USESCREEN sc
FOR q=0 TO 500
DRAWRECT RND(size),RND(size),10+RND(40),10+RND(40),RND(0xffffff)
NEXT

USESCREEN -1
DRAWSPRITE back,100,100

//IF
SPRITE2MEM(array%[],back)

GLOBAL newone%=2999//GENSPRITE()

MEM2SPRITE(array%[],newone,size,size)


LOCAL mx,my,b1,b2
FOR a=0 TO (size*size)-1
array%[a]=bAND(array%[a],0x00ffffff)
NEXT
LOCAL pos
//LOCAL bs=10
REPEAT
MOUSESTATE mx,my,b1,b2
IF mx>size-brushW THEN mx=size-brushW
IF my>size-brushH THEN my=size-brushH
IF mx<=0 THEN mx=0
IF my<=0 THEN my=0
IF b1
FOR h =0 TO brushH-1
FOR w=0 TO brushW-1
IF queryBrush(w,h,brushW,brushH)=1 //NEW BIT
pos=(my+h)*size+(mx+w)
array%[pos]=bOR(array%[pos],0xff000000)
ENDIF
NEXT
NEXT
ENDIF
MEM2SPRITE(array%[],newone,size,size)

DRAWRECT 0,0,size+2,size+2,0xffffff
DRAWRECT 1,1,size,size,0


DRAWSPRITE newone,1,1

DRAWSPRITE back,size*1.2,2
PRINT "DRAW WITH LEFT MB IN THE PANE",0,size*1.2

showBrush(brushW,brushH,5)

SHOWSCREEN
UNTIL FALSE

MOUSEWAIT

FUNCTION makeBrush:w,h
LOCAL b$,r$,c
FOR y= 0 TO h-1
READ r$
FOR x=0 TO w-1
IF MID$(r$,x,1)="*" THEN brushStar[c]=1
INC c
NEXT
NEXT
ENDFUNCTION

FUNCTION showBrush:w,h,s
LOCAL c
FOR y= 0 TO h-1
FOR x=0 TO w-1
IF  brushStar[c]=1 THEN DRAWRECT 400+(x*s),400+(y*s),s,s,0x00ff00
INC c
NEXT
NEXT
ENDFUNCTION

FUNCTION queryBrush:x,y,w,h

IF  brushStar[y*w+x]=1 THEN RETURN 1
ENDFUNCTION




STARTDATA square:
DATA "**************"
DATA "*            *"
DATA "*            *"
DATA "*            *"
DATA "*            *"
DATA "*            *"
DATA "**************"
ENDDATA

STARTDATA star:
DATA "      *       "
DATA "     ***      "
DATA "    *****     "
DATA "************* "
DATA " ***********  "
DATA "   *******    "
DATA "  ***   ***   "
DATA " **       **  "

ENDDATA


erico

#13
Quote from: monkeybot1968 on 2017-Jan-15
I will post a brush version soon but have been busy,you need to study up on logic gates and or xor, ery useful.
And binary math stuff.

Attached is my study on logic gates :)  ... (robot odissey)

Seriously, super thanks for the heads up, it´s pretty much what I was looking for from running it.
It is a very complex code to me, even being GLBasic I see a lot of stuff that I have no idea about.

There is a lot to learn there for me, thanks for the time spent into it. :)

edit: I should be a free man in about a week, it is when I´m going to delve into it. :)