Draw to screen without StartDrawing(ScreenOutput())

Just starting out? Need help? Post your questions and find answers here.
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Draw to screen without StartDrawing(ScreenOutput())

Post by coco2 »

Is there a way to draw to the screen without using StartDrawing? I don't mean using sprites, I already know about them, I mean to write raw pixels to the screen. StartDrawing is too slow and will drop the framerate down too much.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Draw to screen without StartDrawing(ScreenOutput())

Post by netmaestro »

Sprites are much faster. There is no scenario where what you want drawn can't be drawn to a sprite first and then displayed. Maximum speed.
BERESHEIT
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: Draw to screen without StartDrawing(ScreenOutput())

Post by coco2 »

Can you do a CRT filter with sprites?
pjay
Enthusiast
Enthusiast
Posts: 254
Joined: Thu Mar 30, 2006 11:14 am

Re: Draw to screen without StartDrawing(ScreenOutput())

Post by pjay »

coco2 wrote: Sun Nov 03, 2024 1:57 am Can you do a CRT filter with sprites?
Depends.

If you're only adding shadow-mask scanlines then I think you could probably do it. If it's scanlines, softness, screen curvature, phosphor bloom and so on, then you are more in the territory of GPU shaders.

Edit - Do you have a sample that demonstrates slow drawing with ScreenOutput()?
Fred
Administrator
Administrator
Posts: 18274
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Draw to screen without StartDrawing(ScreenOutput())

Post by Fred »

Screenoutput will always been very slow. You should work with premade sprite
pjay
Enthusiast
Enthusiast
Posts: 254
Joined: Thu Mar 30, 2006 11:14 am

Re: Draw to screen without StartDrawing(ScreenOutput())

Post by pjay »

Fred wrote: Sun Nov 03, 2024 12:05 pm Screenoutput will always been very slow. You should work with premade sprite
You can output to a screen (without using Start/Stopdrawing) by using the available OpenGL commands (assuming the default OpenGL subsystem is being used).

This will massively speed-up 2d drawing operations, with the downside being you need to implement the routines yourself. I've done most of them already, so can help where needed.
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: Draw to screen without StartDrawing(ScreenOutput())

Post by coco2 »

pjay wrote: Sun Nov 03, 2024 11:10 am If you're only adding shadow-mask scanlines then I think you could probably do it. If it's scanlines, softness, screen curvature, phosphor bloom and so on, then you are more in the territory of GPU shaders.
I might be able to do it with an overlay for the scanlines.
User avatar
idle
Always Here
Always Here
Posts: 5930
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Draw to screen without StartDrawing(ScreenOutput())

Post by idle »

this was done as a CRT effect with a jitter see DisplayMessageCenter

Code: Select all

If Not overlay 
    overlay = CreateSprite(#PB_Any,width,height) ;make the crt overlay   
    If overlay 
      If StartDrawing(SpriteOutput(overlay))   
        Box(0,0,width,height,RGB(1,1,1)) 
        For a = 2 To width-1 Step 2  
          For b = 2 To height-3 Step 3 
            Plot(a,b,0) 
            Plot(a,b+1,0)
          Next 
        Next
        StopDrawing() 
      EndIf  
    EndIf      
  EndIf 
https://github.com/idle-PB/Putin_ACME_clock
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: Draw to screen without StartDrawing(ScreenOutput())

Post by coco2 »

Can you display a sprite within a sprite? That would be most useful if you created a sprite for the entire screen and drew onto it instead of the screen. That way you could resize the screen to any arbitrary size you want.
User avatar
idle
Always Here
Always Here
Posts: 5930
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Draw to screen without StartDrawing(ScreenOutput())

Post by idle »

Yes you can do that too but if you draw it after you can also create more effects
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: Draw to screen without StartDrawing(ScreenOutput())

Post by coco2 »

I don't think you can display a sprite within a sprite, the documentation says it only draws to a screen. But I thought of a way to do it. Make the screen as big as possible where the pixels are all the same zoom (eg 3x3, 4x4, 5x5 etc) and then you can draw to the screen without flipping the buffer. Then grab the screen into a sprite, then zoom the sprite to the full screen size then place the zoomed sprite and flip the buffers. Unless the sprite zoom makes it look weird maybe.
User avatar
idle
Always Here
Always Here
Posts: 5930
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Draw to screen without StartDrawing(ScreenOutput())

Post by idle »

coco2 wrote: Tue Nov 05, 2024 7:54 am I don't think you can display a sprite within a sprite, the documentation says it only draws to a screen. But I thought of a way to do it. Make the screen as big as possible where the pixels are all the same zoom (eg 3x3, 4x4, 5x5 etc) and then you can draw to the screen without flipping the buffer. Then grab the screen into a sprite, then zoom the sprite to the full screen size then place the zoomed sprite and flip the buffers. Unless the sprite zoom makes it look weird maybe.
I don't know I still think the overlay would work better and you can just zoom it see line 48 and 76

Code: Select all

Global font,width,height 

Procedure DisplayMessageCenter(window,msg.s,color=255,scale.f=1.00)
  
  Protected spriteNumber,tempImage,fontsTextWidth,fontsTextHeight,cx,cy,a,b
  Static overlay,ct1
  
  ct1+1 
  
  If Not overlay 
    overlay = CreateSprite(#PB_Any,width,height) ;make the crt overlay   
    If overlay 
      If StartDrawing(SpriteOutput(overlay))   
        Box(0,0,width,height,RGB(1,1,1)) 
        For a = 2 To width-1 Step 2  
          For b = 2 To height-3 Step 3 
            Plot(a,b,0) 
            Plot(a,b+1,0)
          Next 
        Next
        StopDrawing() 
      EndIf  
    EndIf      
  EndIf 
  
  tempImage = CreateImage(#PB_Any,1,1)    ;if you need to get the size of a font in pixels         
  If tempImage
    If StartDrawing(ImageOutput(tempImage)) ;draw to the temp image 
      DrawingFont(FontID(font))             ;with the selected font  
      fontsTextWidth = TextWidth(msg)       ;get the width and height in pixles     
      fontsTextHeight = TextHeight(msg)  
      
      StopDrawing()  
      spriteNumber = CreateSprite(#PB_Any,fontsTextWidth,fontsTextHeight) ;create the sprite of required size 
      
      If spriteNumber 
        If StartDrawing(SpriteOutput(spriteNumber))   ;now you can draw the text to the sprite 
          DrawingFont(FontID(font)) 
          DrawText(0,0,msg,color)
          StopDrawing()
          TransparentSpriteColor(spriteNumber,0)
          cx = (((width - (fontsTextWidth*scale)) / 2)) 
          cy = (((height - (fontsTextHeight*scale)) / 2))         
          ZoomSprite(spriteNumber,fontsTextWidth*scale,fontsTextHeight*scale)  
          DisplayTransparentSprite(spriteNumber,cx-(ct1&2),cy-(ct1&1))  ;jitter the x and y ccoordinates  
        EndIf   
        FreeSprite(spriteNumber)
        ZoomSprite(overlay,width*scale,height*scale)   ;<--zoom overlay
        TransparentSpriteColor(overlay,0)
        DisplayTransparentSprite(overlay,0,0,255)  
      EndIf 
    EndIf  
    FreeImage(tempImage)       
  EndIf 
  
EndProcedure 

InitSprite()
InitKeyboard()
InitMouse()
ExamineDesktops() 
width = DesktopWidth(0)
height = DesktopHeight(0) 

font = LoadFont(#PB_Any,"Arial",72,#PB_Font_HighQuality | #PB_Font_Bold)
OpenWindow(0,0,0,width,height,"overlay",#PB_Window_BorderLess) 
OpenWindowedScreen(WindowID(0),0,0,width,height)

Repeat  
  
  ExamineKeyboard() 
  ExamineMouse() 
     
  ClearScreen(0)
  color=RGB(0,255,0)
  DisplayMessageCenter(0,FormatDate("%hh:%ii:%ss", Date()),color,4) ;<- scales the overlay and text together
     
  FlipBuffers()
    
 Until KeyboardPushed(#PB_Key_Escape)   
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: Draw to screen without StartDrawing(ScreenOutput())

Post by coco2 »

Actually I was first trying to accomplish a 2D game screen that could be resized to any size and I don't think it can be done at native monitor frequency. I was trying to draw on the screen then grab that screen and then zoom it to the full size of the windowscreen but something is slowing it down, I think GrabImage() EDIT: probably ZoomSprite come to think of it. I can't think of any other way of doing it. EDIT2: I made a dumb mistake and fixed it and now its running at full monitor frequency. I think it's possible to make a 2D game at full speed of the monitor as well as a CRT filter if you want. It's done with sprites so very fast.
User avatar
SPH
Enthusiast
Enthusiast
Posts: 577
Joined: Tue Jan 04, 2011 6:21 pm

Re: Draw to screen without StartDrawing(ScreenOutput())

Post by SPH »

I was always afraid that a sprite as big as the screen would consume a lot of memory.
And then, one thing (still valid?) that we can't do: draw a sprite on a sprite!

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Portable LENOVO ideapad 110-17ACL 64 bits
Version de PB : 6.12LTS - 64 bits
Post Reply