Author Topic: [Bmax] Zawran's render engine and vector display.  (Read 4466 times)

0 Members and 1 Guest are viewing this topic.

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1382
  • Karma: 83
    • View Profile

I've liked the look of oscilliscopes for some time. I like that they have very sharp lines that seem to bleed light around the edges. I think Zawran's rendering framework would be perfect for the task.

My initial thought was:

1 first create one of his zImageBuffers at a smaller size than the screen resolution.
2 Draw lines to the buffer using a light blend mode so overlaps will be brighter spots
3 draw the zImagebuffer stretched to the screen resolution (causing smooth interpolationand the light bleeding effect would happen here.)

My problem is that I'm not how to implement additive blending mode for the way his engine handles primative shapes.

Challenge Trophies Won:

Offline zawran

  • Sponsor
  • Pentium
  • *******
  • Posts: 909
  • Karma: 67
    • View Profile
Re: [Bmax] Zawran's render engine and vector display.
« Reply #1 on: November 10, 2009 »
One way of doing it might be:

Make a buffer that you draw to, then when done drawing copy that buffer and do a box blur on it. Then draw the original buffer ontop of the new buffer using mask draw so that the crisp lines gets drawn ontop of the blured version. That could give you the bleeding light around the crisp lines.

Another way might be:

Using the code from the drawAdditiveMasked() method as inspiration to make a new line draw method that allows for additive drawing of pixels. And for each pixel in the line have it draw the fullbright in the center, and half bright to the left and right of it.

I was thinking about revisiting the framework, so I might be taking another look at updating it, and perhaps adding too it.

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1382
  • Karma: 83
    • View Profile
Re: [Bmax] Zawran's render engine and vector display.
« Reply #2 on: November 11, 2009 »
The blur can come from scaling with hardware but the increased intensity at intersections is really what sells the effect.
Challenge Trophies Won:

Offline zawran

  • Sponsor
  • Pentium
  • *******
  • Posts: 909
  • Karma: 67
    • View Profile
Re: [Bmax] Zawran's render engine and vector display.
« Reply #3 on: November 14, 2009 »
Try and add the following to the framework code:

Code: [Select]
' add to the color of a pixel in the image buffer
Method setPixelAdditive(x:Int,y:Int,r:Byte,g:Byte,b:Byte,a:Byte=255)
Local pixPtr:Byte Ptr = PixmapPixelPtr(Self.buffer)
If x > -1 And x < Self.width And y > -1 And y < Self.height Then
Local offset:Int = y*Self.pitch+x*Self.bcount
If r + pixPtr[offset] > 255 Then
pixPtr[offset] = 255
Else
pixPtr[offset] :+ r
End If
If g + pixPtr[offset+1] > 255 Then
pixPtr[offset+1] = 255
Else
pixPtr[offset+1] :+ g
End If
If b + pixPtr[offset+2] > 255 Then
pixPtr[offset+2] = 255
Else
pixPtr[offset+2] :+ b
End If
If Self.bcount = 4 Then
If a + pixPtr[offset+3] > 255 Then
pixPtr[offset+3] = 255
Else
pixPtr[offset+3] :+ a
End If
End If
End If
End Method

Then try something like this:

Code: [Select]
SuperStrict

Framework BRL.GLMax2D
Import BRL.Pixmap
Import BRL.PNGLoader
Import BRL.Random
Import BRL.Retro

SetGraphicsDriver GLMax2DDriver()

Include "E:\zSoftwareRenderFramework\zSoftwareRenderFramework_v05.bmx"

Graphics 640,480

Global timerUpd:Int = MilliSecs()
Global timerFrq:Int = 1000/30 ' 30 fps

Global screenBuffer:zImageBuffer = zImageBuffer.make(640,480)

While Not KeyHit(KEY_ESCAPE)
Cls
screenBuffer.drawToScreen()
Flip

While MilliSecs() < timerUpd+timerFrq
Wend
timerUpd = MilliSecs()

additiveLine(screenBuffer,Rnd(0,320),Rnd(0,240),Rnd(320,640),Rnd(240,480),32,64,32)

Wend
End

Function additiveLine(buf:zImageBuffer,x1:Float,y1:Float,x2:Float,y2:Float,r:Byte,g:Byte,b:Byte,a:Byte=255)
Local r2:Byte = r/2,g2:Byte = g/2,b2:Byte = b/2
Local steps:Float,xI:Float,i:Int
x2 :- x1
y2 :- y1
If Abs(x2) > Abs(y2) Then
steps = Abs(x2)
Else
steps = Abs(y2)
End If
xI = Float(x2 / steps)
y2 = Float(y2 / steps)
For x2 = 0 To steps
buf.setPixelAdditive(Int(x1)-1,Int(y1),r2,g2,b2,a)
buf.setPixelAdditive(Int(x1)+1,Int(y1),r2,g2,b2,a)
buf.setPixelAdditive(Int(x1),Int(y1),r,g,b,a)
buf.setPixelAdditive(Int(x1),Int(y1)-1,r2,g2,b2,a)
buf.setPixelAdditive(Int(x1),Int(y1)+2,r2,g2,b2,a)
x1 :+ xI
y1 :+ y2
Next
End Function

You will have to change the include path to where you have stored the software render framework file.

Is that somewhat like the effect you are after?

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1382
  • Karma: 83
    • View Profile
Re: [Bmax] Zawran's render engine and vector display.
« Reply #4 on: November 15, 2009 »
Honestly dude, I think your framework really adds something that they should have implemented all along. Why not have multiple screen buffers? Good job.
« Last Edit: November 15, 2009 by Pixel_Outlaw »
Challenge Trophies Won:

Offline zawran

  • Sponsor
  • Pentium
  • *******
  • Posts: 909
  • Karma: 67
    • View Profile
Re: [Bmax] Zawran's render engine and vector display.
« Reply #5 on: November 15, 2009 »
One of the things a lot of people have been posting about on the official blitzmax forum is why there isn't more features in the max2d module. One of the problems of adding features is that blitz research wants those features to run the exact same on all three platforms, and sometimes solutions are not that obvious so that a feature can just be added. But I do think that there is room for improvements for sure. And I am fairly certain that I could make a module which had more useful features and that would even be faster than the max2d that comes with the language. The main problem is that I wouldn't really be able to make it work the way most users would want, because whether or not I like it, most of them would want a directX solution for the window side of things, and I just don't know enough about directX to make something like that. I would know how to make everything work using opengl though. And I have previously made a replacement module, basically a sprite module which did more or less everything the max2d module did, but just faster because it was based on single texture rendering and batching of opengl calls. But that was a couple of years back and I have learned a lot more about opengl since, so I would probably be able to make it even more efficient now.

Having multiple screenbuffers are more pratical for retro looking stuff than current tech where everything is done with textures and shaders. But it still have its merits and I can understand why it is dissapointing that its not part of the standard features. The good thing for us is that blitzmax is such an open language to work with, that it is fairly easy to add these features ourselves.

I just had another look at the example code I posted earlier on, and I have done a quick sine wave thingy. You can switch to the lines by tapping on spacebar. I have provided a link to an exe as well if someone without blitzmax wanted to take a peek.

Code: [Select]
SuperStrict

Framework BRL.GLMax2D
Import BRL.Pixmap
Import BRL.PNGLoader
Import BRL.Random
Import BRL.Retro

SetGraphicsDriver GLMax2DDriver()

Include "E:\zSoftwareRenderFramework\zSoftwareRenderFramework_v05.bmx"

Graphics 640,480

Global timerUpd:Int = MilliSecs()
Global timerFrq:Int = 1000/30 ' 30 fps
Global cnt:Int = 0
Global mode:Int = 1

Global screenBuffer:zImageBuffer = zImageBuffer.make(640,480)

While Not KeyHit(KEY_ESCAPE)
Cls
screenBuffer.drawToScreen()
Flip

While MilliSecs() < timerUpd+timerFrq
Wend
timerUpd = MilliSecs()

Select mode
Case 0
additiveLine(screenBuffer,Rnd(0,320),Rnd(0,240),Rnd(320,640),Rnd(240,480),32,64,32)
Case 1
Local r:Int = Rnd(359)
Local v:Int = Rnd(120)
For Local i:Int = 0 To 639
additivePlot(screenBuffer,i,240+Sin(r)*v,32,64,32)
r :+ 1
Next
End Select

cnt :+ 1
If cnt > 19 Then
cnt = 0
screenBuffer.clear()
If mode = 1 Then
additiveLine(screenBuffer,0,240,639,240,32,64,32)
additiveLine(screenBuffer,320,0,320,479,32,64,32)
For Local i:Int = 0 To 640 Step 32
additiveLine(screenBuffer,i,220,i,260,32,64,32)
Next
End If
End If

If KeyHit(KEY_SPACE) Then mode = 1-mode
Wend
End

Function additivePlot(buf:zImageBuffer,x:Float,y:Float,r:Byte,g:Byte,b:Byte,a:Byte=255)
Local r2:Byte = r/2,g2:Byte = g/2,b2:Byte = b/2
buf.setPixelAdditive(x-1,y,r2,g2,b2,a)
buf.setPixelAdditive(x+1,y,r2,g2,b2,a)
buf.setPixelAdditive(x,y,r,g,b,a)
buf.setPixelAdditive(x,y-1,r2,g2,b2,a)
buf.setPixelAdditive(x,y+1,r2,g2,b2,a)
End Function

Function additiveLine(buf:zImageBuffer,x1:Float,y1:Float,x2:Float,y2:Float,r:Byte,g:Byte,b:Byte,a:Byte=255)
Local r2:Byte = r/2,g2:Byte = g/2,b2:Byte = b/2
Local steps:Float,xI:Float,i:Int
x2 :- x1
y2 :- y1
If Abs(x2) > Abs(y2) Then
steps = Abs(x2)
Else
steps = Abs(y2)
End If
xI = Float(x2 / steps)
y2 = Float(y2 / steps)
For x2 = 0 To steps
buf.setPixelAdditive(Int(x1)-1,Int(y1),r2,g2,b2,a)
buf.setPixelAdditive(Int(x1)+1,Int(y1),r2,g2,b2,a)
buf.setPixelAdditive(Int(x1),Int(y1),r,g,b,a)
buf.setPixelAdditive(Int(x1),Int(y1)-1,r2,g2,b2,a)
buf.setPixelAdditive(Int(x1),Int(y1)+1,r2,g2,b2,a)
x1 :+ xI
y1 :+ y2
Next
End Function

http://zac-interactive.dk/temp/srft.zip

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1382
  • Karma: 83
    • View Profile
Re: [Bmax] Zawran's render engine and vector display.
« Reply #6 on: November 15, 2009 »
That is really cool. Almost a demo effect in its own right. Have some karma.
Challenge Trophies Won: