[bmx] 3D Terrain with Hidden Line Removal by Endive [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:38

Previous topic - Next topic

BlitzBot

Title : 3D Terrain with Hidden Line Removal
Author : Endive
Posted : 1+ years ago

Description : This is a simple terrain engine that performs hidden line elimination.  It does this by plotting back to front in Z order and instead of just drawing lines, drawing a black vertical polygon from the line in question down to the bottom of the screen, then drawing the line itself.  

The core here is really in the map3d function which performs the requisite perspective transforms.


Code :
Code (blitzmax) Select
Graphics 1000,600
SetBlend solidblend
Type point
Field x#,y#
End Type
Global SCREENWIDTH#=GraphicsWidth()
Global SCREENHEIGHT#=GraphicsHeight()

While Not KeyDown(KEY_ESCAPE)
Cls
ticks = ticks + 1
For zz = 700 To 100 Step -5
SetColor 255-zz/2,255-zz/2,255-zz/2
For xx = -500 To 500 Step 5
drawfilledline3d (xx,(25+Sin(xx*4+ticks*2)*25+(Cos(zz*2+ticks*2))*100) + 200,zz, xx+5,(25+Sin((xx+3)*4+ticks*2)*25+(Cos(zz*2+ticks*2))*100) + 200,zz)
Next
Next

Flip
Wend

Function drawquad3d(x1#,y1#,z1#, x2#,y2#,z2#, x3#,y3#,z3#, x4#,y4#,z4#)
drawline3d(x1,y1,z1, x2,y2,z2)
drawline3d(x2,y2,z2, x3,y3,z3)
drawline3d(x3,y3,z3, x4,y4,z4)
drawline3d(x4,y4,z4, x1,y1,z1)
End Function


Function drawline3d(x1#,y1#,z1#, x2#,y2#,z2#)
Local point1:point = map3d(x1,y1,z1)
Local point2:point = map3d(x2,y2,z2)
If point1.x>0 Or point2.x > 0
If point1.x <GraphicsWidth() Or point2.x<GraphicsWidth()
DrawLine point1.x, point1.y, point2.x, point2.y
EndIf
EndIf
End Function

Function drawfilledline3d(x1#,y1#,z1#, x2#,y2#,z2#)
' Draws a polygon to the bottom of the screen first
Local point1:point = map3d(x1,y1,z1)
Local point2:point = map3d(x2,y2,z2)

Local xx1#=point1.x
Local yy1#=point1.y
Local xx2#=point2.x
Local yy2#=point2.y
' First, check to make sure x coords are within screen width extents
If xx1>0 Or xx2>0
If xx1<GraphicsWidth() Or xx2 < GraphicsWidth()
Local quad#[]=[xx1,yy1, xx1,SCREENHEIGHT, xx2,SCREENHEIGHT, xx2,yy2]
SetColor 0,0,0
DrawPoly quad
SetColor 0,255-(z1/2),0
DrawLine point1.x, point1.y, point2.x, point2.y
EndIf
EndIf
End Function


Function plot3d(x#,y#,z#)
Local plotpoint:point = New point ' holds the 2d point we will plot
plotpoint = map3d(x,y,z)
Plot plotpoint.x, plotpoint.y
End Function

Function map3d:point(x#,y#,z#)
Local myx = ((x / z) * 300) + (GraphicsWidth() *.5)
Local myy = ((y / z) * 100) + (GraphicsHeight() *.5)
Local outpoint:point = New point
outpoint.x = myx; outpoint.y = myy
Return outpoint
End Function


Comments :


dw817(Posted 1+ years ago)

 Delicious. Would be interesting to see this code do an upgrade on the original BATTLEZONE game.


BlitzSupport(Posted 1+ years ago)

 Nice little piece of code -- reminds me of magazine type-ins from the 80s!


Endive(Posted 1+ years ago)

 Funny you would say that, there were some function plotters that ran on the Apple that looked a little bit like this but I'm pretty sure they used some sort of clipping-based hidden line removal instead of the way this does it-- among other things this can currently only do horizontal lines and those would display meshes.  It would take them some 15-20 minutes to do one frame.  There was also a book on 3D graphics for the Apple that was pretty interesting, I wish I could find it again.  One of the things I like about Blitzmax is that it somehow reminds me of the old-school programming feel.I'm sort of surprised how fast this is, it's essentially pushing ~40,000 polygons.  That number could be doubled by eliminating rear-facing polygons.  Flat shading could be added for very little cost on the basis of the above-mentioned normal calculation so should be easily paid for by the savings from not rendering back-facing polys.  If I do shading calculations I will do the lighting with a lookup table for approximate normal values and that should make lighting close to free.Quake 1 was possible in software in 1996.  Think about that and think about what a technical tour deforce it was.  Even my little piece of crap code here is benefiting from hardware acceleration (2d acceleration used for hidden line elimination) and a machine that's roughly 40x faster than my pentium 90 was.  And that p90 ran Quake so fast it was mindblowing, especially when you played it on... never mind.Maybe I will poke around with this a little bit more while I work my way through the OpenGL Orange Book.  I know a fair bit of that already but the programmable pipeline stuff is new to me, the old book I had was the Red Book from around 1998.Tangentially, the average salary of OpenGL programmers is around $140,000 per year.  This number is going to skyrocket in the next five years, because of VR headsets emerging all of a sudden everywhere there are not going to be nearly enough 3D graphics programmers to fill all the desks.  Personally that's my plan.Battlezone was definitely amazing, easily my favorite game from that time period though I very rarely broke 30,000 score on it.  Now, looking back, I think Defender was a far better game but Battlezone had that creepy cold war feeling to it and was actually VR of sorts!