Creating a DPaint clone in BMax

BlitzMax Forums/BlitzMax Programming/Creating a DPaint clone in BMax

What would be the best way to go about making a pixel pushing paint program (say that ten times fast ;) in BMax? Is it a relatively simple task or would it be quite hard? I`m asking as I would like to try and make one but have never done anything other than games programming before. I`m not really sure as to how to go about it to tell the truth so any help would be great.

Jason.

It won't be fast.

Pixel operations in BM have to be done on pixmaps.
Those are either drawn to backbuffer (-> pixel per pixel copy) or have to be made an image which means texture generation and upload

In both cases, not fast enough to be "ten times faster" than anything done yet.

if you need it to be faster, check out shaders and do it as pixel shader for example.

Or even easier, use DirectDraw surfaces, and keep it all 2D & still fast ;)

say that ten times fast

I think he meant the alliteration :-p

A pixel-editor should be relatively easy to do in blitzmax. There are functions that can read/modify specific pixels in a pixmap, which is all you need.
The rest is up to you to implement how you wish :-)

Even with the limitations of Blitz pixel pushing, speed will not be an issue. If by DPaint you mean deluxe paint on the Amiga (the last paint program I ever enjoyed using), 10x as fast will be easy.

Yeah, these days with the GPU-accelerated drawing and fast CPU's you shouldn't have much problem at all making a relatively fast graphics app.

I say go with OpenGL since DX is Windows only. I think if it were me I would write my own routines accessing pixmaps in main memory to do all the drawing, since that lets you have precice control over what is drawn and can make much larger bitmaps bigger than the screen. Then you can do things like flood fills where you'll need to READ the image. It's not so efficient to read the backbuffer and the backbuffer can only be the size of the screen resolution.

I would write the routines using pointers to access the individual pixels in the pixmap. Writing a paint program usually means writing quite a large number of small-ish specialized routines so it can be quite a bit of coding, but it's a good project. You need to ask yourself what you want it to be able to do in terms of sizes of bitmaps, resolution, color depth/palettes, etc... and also you've got to give consideration to how to do a GUI.

DCTV Paint was the BEST! And DCTV itself was really cool... Ah, the good 'ol Amiga days...

Russell

Yah, Amiga had lots of good paint software. Deluxe Paint, Brilliance, Personal Paint, TV Paint, Spectrapaint, etc etc

Here is a small additon about fast pixmap manipulating and displaying. It is much faster for pixeloperations than the standard LockImage() or DrawPixmap stuff.

I think I have more time to explain it tomorrow.

SetGraphicsDriver(GLMax2DDriver())

Graphics 800,600,0,-1

Local Pix:TPixmap = CreatePixmap(512,512,PF_RGBA8888)
ClearPixels(Pix,$ffffffff)
Local Image:TImage = LoadImage(Pix)
Local Pix2:TPixmap 

'SetClsColor (255,255,255)
Local Mode:Int = 0
Local Radius:Int = 4
Local UpdateTime:Int = 0

Local fps:Int = 0
Local fpstime:Int = MilliSecs()
Local fps2:Int = 0
Local angle:Float = 0


While Not KeyHit(KEY_EScape)
	Cls
		SetColor 255,0,0
		DrawRect 0,0,516,516
		SetColor 255,255,255
		UpdateTime = MilliSecs()
		SetRotation Angle
		DrawImage Image,2,2
		UpdateTime = MilliSecs()-UpdateTime

		
		If KeyHit(Key_Space) Then 
			If Mode = 2 Then 
				Mode = 0 
			Else
				Mode = 1 - Mode
			EndIf
			Angle = 0
			SetHandle 0,0

		EndIf
		
		If KeyHit(KEY_Enter) Then 
			angle = 0
			Mode = 2
			SetHandle 256,256
		EndIf
		If KeyHit(Key_Up) Then Radius:+1
		If KeyHit(Key_Down) Then Radius:-1
		If Radius < 1 Then Radius = 1
		Local MX:Int = MouseX()
		Local MY:Int = MouseY()
		
		Local XX = Min(Max(2,MX),514)
		Local YY = Min(Max(2,MY),514)


		If Mode <> 2 Then 
		If MouseDown(1) = True Then
			If MX > 2 And MX < 512
				If MY > 2 And MY < 512
				If Mode = 1 Then
					Pix = LockImage(Image)
				 EndIf
					For Local Xi:Int = 0 To radius
						For Local yi:Int = 0 To radius
						 
							Local X = Min(Max(2,MX+xi),512)
							Local Y = Min(Max(2,MY+yi),512)

							WritePixel Pix,X-2,Y-2,$ff000000
							
						Next
					Next
					
					If Mode = 0 Then
						UploadPixToImg(Image,Pix,XX-2,YY-2,radius+2,radius+2)
					EndIf
					
				EndIf
			EndIf
		EndIf
			Else
			Angle:+0.2	
		EndIf
		
		SetRotation 0.0
		
		DrawText "Mode       : " + Mode,20,515
		DrawText "Radius     : " + Radius,20,535
		DrawText "UpdateTime : " + UpdateTime,20,555
		DrawText "FPS        : " + FPS,532,20
		DrawText "Space       -> Change Mode (0 = Fast,1 = LockImage)",532,40
		DrawText "Up and Down -> Change Radius",532,60
		DrawText "Color      :  $" + Hex(ReadPixel(Pix,Min(Max(0,MouseX()-2),511),Min(Max(0,MouseY()-2),511))),20,575
		
		fps2:+1
		
		
		If MilliSecs()-fpstime >= 1000 Then
			fps = fps2
			fpstime = MilliSecs()
			fps2 = 0
		EndIf
		
		If KeyHit(KEY_F1) Then SavePixmapPNG(Pix,"test.png")

	Flip 0
Wend




Function UploadPixtoImg(tex:TImage,Pixmap:TPixmap,x:Int = -1,y:Int=-1,w:Int=-1,h:Int=-1)
	Local ImgF:TGLImageFrame = TGLImageframe(tex.frame(0))
	Local mip_level:Int = 0

		If ImgF <> Null Then
			glBindtexture GL_TEXTURE_2D,ImgF.name
			glPixelStorei GL_UNPACK_ROW_LENGTH,pixmap.pitch/BytesPerPixel[pixmap.format]
			If X <> -1 And y <> -1 And w <> -1 And h <> -1 Then
				glTexSubImage2D GL_TEXTURE_2D,mip_level,X,y,W,H,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixelptr(X,Y)
				
			Else
				glTexSubImage2D GL_TEXTURE_2D,mip_level,0,0,pixmap.width,pixmap.height,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
			EndIf
			glPixelStorei GL_UNPACK_ROW_LENGTH,0
			glBindtexture GL_TEXTURE_2D,0
		EndIf
		
	DrawText " ",-20,-20
End Function


Hi all,

Tvpaint has been ported to PC.
You can try Aura from Newtek or Tvpaint or Mirage.
These 3 soft are Tvpaint version.
They are the best paint software for amiga lovers...