Draw to screen without StartDrawing(ScreenOutput())
Draw to screen without StartDrawing(ScreenOutput())
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.
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Draw to screen without StartDrawing(ScreenOutput())
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
Re: Draw to screen without StartDrawing(ScreenOutput())
Can you do a CRT filter with sprites?
Re: Draw to screen without StartDrawing(ScreenOutput())
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()?
Re: Draw to screen without StartDrawing(ScreenOutput())
Screenoutput will always been very slow. You should work with premade sprite
Re: Draw to screen without StartDrawing(ScreenOutput())
You can output to a screen (without using Start/Stopdrawing) by using the available OpenGL commands (assuming the default OpenGL subsystem is being used).Fred wrote: Sun Nov 03, 2024 12:05 pm Screenoutput will always been very slow. You should work with premade sprite
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.
Re: Draw to screen without StartDrawing(ScreenOutput())
I might be able to do it with an overlay for the scanlines.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.
Re: Draw to screen without StartDrawing(ScreenOutput())
this was done as a CRT effect with a jitter see DisplayMessageCenter
https://github.com/idle-PB/Putin_ACME_clock
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
Re: Draw to screen without StartDrawing(ScreenOutput())
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.
Re: Draw to screen without StartDrawing(ScreenOutput())
Yes you can do that too but if you draw it after you can also create more effects
Re: Draw to screen without StartDrawing(ScreenOutput())
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.
Re: Draw to screen without StartDrawing(ScreenOutput())
I don't know I still think the overlay would work better and you can just zoom it see line 48 and 76coco2 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.
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)
Re: Draw to screen without StartDrawing(ScreenOutput())
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.
Re: Draw to screen without StartDrawing(ScreenOutput())
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!
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