Page 2 of 3

Re: You could write 2D games on the CanvasGadget

Posted: Mon Jul 18, 2011 6:42 pm
by netmaestro
iirc I never said you should use a canvas for 2D games, only that its graphics performance is good enough that you could. If you did you'd also have to write your own collision routines. Anyway, that said, here's a small demo moving thousands of objects on a canvas gadget. You be the judge if it would support a 2D game or not. Turn the debugger off for smoothest results:

Code: Select all

Structure shrapnel
  x.f 
  y.f 
  u.f 
  v.f 
  life.f 
  s.f
  c.l
EndStructure 

Global NewList dot.shrapnel() 

CreateImage(0, 64, 64, 32|#PB_Image_Transparent)
StartDrawing(ImageOutput(0))
  DrawingMode(#PB_2DDrawing_Gradient|#PB_2DDrawing_AllChannels)      
  BackColor (RGBA(0,0,255,255))
  FrontColor(RGBA(0,0,0,0))
  EllipticalGradient(20, 20, 64, 64)
  Circle(31, 31, 31)   
StopDrawing() 

CreateImage(1, 64, 64, 32|#PB_Image_Transparent)
StartDrawing(ImageOutput(1))
  DrawingMode(#PB_2DDrawing_Gradient|#PB_2DDrawing_AllChannels)      
  BackColor (RGBA(255,0,0,255))
  FrontColor(RGBA(0,0,0,0))
  EllipticalGradient(20, 20, 64, 64)
  Circle(31, 31, 31)   
StopDrawing() 

OpenWindow(0,0,0,640,480,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
CanvasGadget(0,0,0,640,480)

Procedure BlowemUp(spotx,spoty) 
  For g=0 To 900 
    AddElement(dot()) 
    angle.f=Random(359)*3.141592/180 
    dot()\life=1+Random(254) 
    dot()\u=Cos(angle)*Random(128)/64 
    dot()\v=Sin(angle)*Random(128)/64 
    dot()\v=dot()\v-2  
    dot()\x=spotx 
    dot()\y=spoty 
    dot()\s=Random(15)/10 
    dot()\c = Random($FFFFFF)
  Next g 
EndProcedure 

x=0:y=0:quit=0:f=1:d=1:rt=576:bt=416:x1=350:y1=100:f1=1:d1=1
Repeat 
  ev=WindowEvent()
  While ev
    If ev=#PB_Event_CloseWindow:quit=1:EndIf
    ev=WindowEvent()
  Wend
  
  If f:x+1:If x>=rt:f=0:EndIf:Else:x-1:If x<=0:f=1:EndIf:EndIf
  If d:y+1:If y>=bt:d=0:EndIf:Else:y-1:If y<=0:d=1:EndIf:EndIf  
  If f1:x1+1:If x1>=rt:f1=0:EndIf:Else:x1-1:If x1<=0:f1=1:EndIf:EndIf
  If d1:y1+1:If y1>=bt:d1=0:EndIf:Else:y1-1:If y1<=0:d1=1:EndIf:EndIf  
  
  StartDrawing(CanvasOutput(0)) 
    Box(0,0,640,480,$000000)
    DrawAlphaImage(ImageID(0),x,y)
    DrawAlphaImage(ImageID(1),x1,y1)
    If ListSize(dot())<400 
      BlowemUp(100+Random(480),100+Random(280)) 
    EndIf 
    ForEach dot() 
      dot()\x=dot()\x+dot()\u 
      dot()\y=dot()\y+dot()\v 
      dot()\v=dot()\v+0.05 
      If dot()\x=>(0) And dot()\x<=(639) And dot()\y=>(0) And dot()\y<=(479)
        c=dot()\life 
        c=c+c<<8+c<<16 
        Circle(dot()\x,dot()\y,1,dot()\c) 
      EndIf 
      dot()\life=dot()\life-1:If dot()\life<=0:DeleteElement(dot()):EndIf 
    Next 
  StopDrawing() 
  
  Delay(5)
Until quit
End 

Re: You could write 2D games on the CanvasGadget

Posted: Mon Jul 18, 2011 6:48 pm
by RASHAD
This is out of the discussion
Fantastic NM; just beautiful
Keep going

Edit :The moving of the balls not smooth

Re: You could write 2D games on the CanvasGadget

Posted: Mon Jul 18, 2011 7:07 pm
by luis
CanvasGadget is very useful and a very nice addition, but I would expect that kind of performance graphic-wise even without it.
What I mean is I think the normal GDI api performance is in the same league, and that something like the demo posted above by netmaestro can be achieved using normal GDI api on bitmap for example, or an imagegadget. Am I wrong ? I didn't try to do same thing, but I remember some times ago I did a star wars like scroller (the text scrolling up with perspective correction) using GDI and was smooth.
After all current graphic card drivers accelerate most if not all of the desktop drawing, and from Vista and beyond the desktop is in reality a graphic screen like the one in a game.

So... I'm not so surprised, but as I said I do not tried to do a direct comparison.

Re: You could write 2D games on the CanvasGadget

Posted: Mon Jul 18, 2011 8:29 pm
by Andre
@netmaestro: nice example! :D

To make it compile/run on MacOS (and probably Linux too) just replace the Win-only constants #White by $FFFFFF and #Black by $000000 :wink:

Re: You could write 2D games on the CanvasGadget

Posted: Tue Jul 19, 2011 2:53 am
by rsts
Another fabulous canvasGadget example.

Between your and einander's http://www.purebasic.fr/english/viewtop ... 12&t=46933 examples it would certainly seem possible.

This stuff is great. Thanks for sharing.

Re: You could write 2D games on the CanvasGadget

Posted: Tue Jul 19, 2011 5:07 am
by Demivec
The example works just as well using an ImageGadget() instead of a CanvasGadget().

Here's the changes that need to be made:

Code: Select all

;add this before the OpenWindow()
CreateImage(2, 640, 480)

;change
;CanvasGadget(0,0,0,640,480) to 
ImageGadget(0,0,0,640,480, ImageID(2))

;change
;StartDrawing(CanvasOutput(0)) to
StartDrawing(ImageOutput(2)) 

;add after the StopDrawing() in the event loop
SetGadgetState(0,ImageID(2))
I didn't see a difference between using an ImageGadget() and using a CanvasGadget().


A CanvasGadget() only has advantages in what it can do that an ImageGadget() can't, namely its ability to react to more events.

Re: You could write 2D games on the CanvasGadget

Posted: Tue Jul 19, 2011 5:27 am
by netmaestro
In the CanvasGadget double-buffering is automatic; You can simply write to CanvasOutPut() and there is no need to draw to an image first and then switch outputs (manual double-buffering). Also, the image contained in an ImageGadget must be 24bits depth or you will experience remarkable flickering on rapid updates. If you want to layer your window and have true-to-desktop transparency with alphablending, the CanvasGadget will be superior to the ImageGadget in this regard because CanvasOutput doesn't suffer from the alpha-redraw flicker problem. Yes it can be done by alphablending to a 24bit image and swapping the contained image in an ImageGadget, I'm aware of that. I covered this five years ago here: http://www.purebasic.fr/english/viewtop ... 12&t=18587 My point is that the CanvasGadget automates this for you and CanvasOutput is simpler to implement.

Re: You could write 2D games on the CanvasGadget

Posted: Tue Jul 19, 2011 8:02 am
by eesau
Nice example maestro! However, I get the tiniest, slightest of tearing (flicker). Can be seen easily when looking at the red ball, especially if the explosions are disabled.

Re: You could write 2D games on the CanvasGadget

Posted: Tue Jul 19, 2011 8:12 am
by MachineCode
eesau wrote:I get the tiniest, slightest of tearing (flicker).
Must be a video driver issue. I have a low-end PC (dual-core CPU) and low-end video card (nVidia 8400 GS) and I get no flickering or tearing at all, and the smoothness and speed is exactly the same no matter if I run the example with the debugger on or off.

Re: You could write 2D games on the CanvasGadget

Posted: Tue Jul 19, 2011 8:27 am
by eesau
MachineCode wrote:
eesau wrote:I get the tiniest, slightest of tearing (flicker).
Must be a video driver issue. I have a low-end PC (dual-core CPU) and low-end video card (nVidia 8400 GS) and I get no flickering or tearing at all, and the smoothness and speed is exactly the same no matter if I run the example with the debugger on or off.
Mine is a low-end dual-core as well, with nVidia 9800 GT with latest drivers and Windows 7. Tested with both debugger on and off. Granted, the tearing was pretty minuscule. Maybe I'll test again.

Re: You could write 2D games on the CanvasGadget

Posted: Tue Jul 19, 2011 8:30 am
by MachineCode
I have XP, if that makes any difference. It might, as 7 has extra slowness.

Re: You could write 2D games on the CanvasGadget

Posted: Tue Jul 19, 2011 9:21 am
by einander
Very nice example Netmaestro! :D

Re: You could write 2D games on the CanvasGadget

Posted: Tue Jul 19, 2011 10:29 am
by luis
Demivec wrote:The example works just as well using an ImageGadget() instead of a CanvasGadget().
Thank you, yesterday I was too lazy to try it by myself :)

Re: You could write 2D games on the CanvasGadget

Posted: Tue Jul 19, 2011 11:24 am
by Polo
MachineCode wrote:I have XP, if that makes any difference. It might, as 7 has extra slowness.
7 is a LOT slower indeed, didn't they drop the hardware accelerated support on GDI on 7?

Re: You could write 2D games on the CanvasGadget

Posted: Tue Jul 19, 2011 2:37 pm
by Demivec
netmaestro wrote:In the CanvasGadget double-buffering is automatic; You can simply write to CanvasOutPut() and there is no need to draw to an image first and then switch outputs (manual double-buffering). Also, the image contained in an ImageGadget must be 24bits depth or you will experience remarkable flickering on rapid updates. If you want to layer your window and have true-to-desktop transparency with alphablending, the CanvasGadget will be superior to the ImageGadget in this regard because CanvasOutput doesn't suffer from the alpha-redraw flicker problem. Yes it can be done by alphablending to a 24bit image and swapping the contained image in an ImageGadget, I'm aware of that. I covered this five years ago here: http://www.purebasic.fr/english/viewtop ... 12&t=18587 My point is that the CanvasGadget automates this for you and CanvasOutput is simpler to implement.
True, the double buffering is automatic, but you are simply saving a single SetGadgetState().

I can't comment on the true-to-desktop transparency with alphablending in a layered window. That seems to be a very isolated issue and one I don't have a good example of to compare between using a CanvasGadget and an ImageGadget. The current results seem to be identical with a 24bit image. How can you tell if the default image used for the CanvasGadget is 24bit or 32bit? I know the ImageID of the image can be retrieved but that is as far as I can get without API.