March 08, 2021, 04:41:00 PM

Author Topic: [bmx] 3D Terrain with Hidden Line Removal by Endive [ 1+ years ago ]  (Read 1014 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
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
  1. Graphics 1000,600
  2. SetBlend solidblend
  3. Type point
  4. Field x#,y#
  5. End Type
  6. Global SCREENWIDTH#=GraphicsWidth()
  7. Global SCREENHEIGHT#=GraphicsHeight()
  9. While Not KeyDown(KEY_ESCAPE)
  10. Cls
  11. ticks = ticks + 1
  12. For zz = 700 To 100 Step -5
  13.         SetColor 255-zz/2,255-zz/2,255-zz/2
  14.         For xx = -500 To 500 Step 5
  15.                 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)
  16.         Next
  17. Next
  19. Flip
  20. Wend
  22. Function drawquad3d(x1#,y1#,z1#, x2#,y2#,z2#, x3#,y3#,z3#, x4#,y4#,z4#)
  23.         drawline3d(x1,y1,z1, x2,y2,z2)
  24.         drawline3d(x2,y2,z2, x3,y3,z3)
  25.         drawline3d(x3,y3,z3, x4,y4,z4)
  26.         drawline3d(x4,y4,z4, x1,y1,z1)
  27. End Function
  30. Function drawline3d(x1#,y1#,z1#, x2#,y2#,z2#)
  31.         Local point1:point = map3d(x1,y1,z1)
  32.         Local point2:point = map3d(x2,y2,z2)
  33.         If point1.x>0 Or point2.x > 0
  34.                 If point1.x <GraphicsWidth() Or point2.x<GraphicsWidth()
  35.                         DrawLine point1.x, point1.y, point2.x, point2.y
  36.                 EndIf
  37.         EndIf
  38. End Function
  40. Function drawfilledline3d(x1#,y1#,z1#, x2#,y2#,z2#)
  41. ' Draws a polygon to the bottom of the screen first
  42.         Local point1:point = map3d(x1,y1,z1)
  43.         Local point2:point = map3d(x2,y2,z2)
  45.         Local xx1#=point1.x
  46.         Local yy1#=point1.y
  47.         Local xx2#=point2.x
  48.         Local yy2#=point2.y
  49.         ' First, check to make sure x coords are within screen width extents
  50.         If xx1>0 Or xx2>0
  51.                 If xx1<GraphicsWidth() Or xx2 < GraphicsWidth()
  52.                         Local quad#[]=[xx1,yy1, xx1,SCREENHEIGHT, xx2,SCREENHEIGHT, xx2,yy2]
  53.                         SetColor 0,0,0
  54.                         DrawPoly quad
  55.                         SetColor 0,255-(z1/2),0
  56.                         DrawLine point1.x, point1.y, point2.x, point2.y
  57.                 EndIf
  58.         EndIf
  59. End Function
  62. Function plot3d(x#,y#,z#)
  63.         Local plotpoint:point = New point ' holds the 2d point we will plot
  64.         plotpoint = map3d(x,y,z)
  65.         Plot plotpoint.x, plotpoint.y
  66. End Function
  68. Function map3d:point(x#,y#,z#)
  69. Local myx = ((x / z) * 300) + (GraphicsWidth() *.5)
  70. Local myy = ((y / z) * 100) + (GraphicsHeight() *.5)
  71. Local outpoint:point = New point
  72. outpoint.x = myx; outpoint.y = myy
  73. Return outpoint
  74. 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!


SimplePortal 2.3.6 © 2008-2014, SimplePortal