Making 3D object using Blitz3D script.

Disclaimer: This post is archived. It was written when I was much younger and less experienced, and is really only here for nostalgia reasons. Information is possibly incorrect, and opinions are likely outdated.

Blitz3D is a really old language for making games, but it has all kinds of useful perks that I enjoy that make it worth putting up with having to inform users to enable DirectPlay. But with all of the easy and useful features, there are a few that prove to be very hard. One such feature is custom script-based meshes in 3D games. What follows is a tutorial to the arduous process of making a mesh.

Fair warning: This tutorial expects that you have experience with the 3D functions of Blitz3D, as I will go into little detail explaining anything other than mesh-related functions. This isn't as much a real tutorial as it is an explaination of how hard it is to make Blitz3D meshes.

Step 1: Concept

A good place to start is with an image of the mesh you want to make, and where all of the edges and vetexes will be. Keep in mind while doing this that the faces can only be triangles, meaning three vertexes/edges to a face. For this tutorial, I'll be making a spaceship.

A hand-drawing of the mesh I am going to make

Step 2: Starting the .bb file and the mesh

I assume that if you're reading this tutorial, you've already downloaded Blitz3D (if not, look it up on Itch.io). The first thing to do is to set the 3D graphics mode, which is what tells the program how, what, and where to draw.

Graphics3D 800,600

Next, we should start the mesh so that we have some sort of reference. Create a simple function like the one below (don't forget "End Function"!). Using a function will make it easy to replicate our spaceship mesh on the fly.

Function starship (ship_r, ship_g, ship_b) ;This function returns a starship mesh, used for the player, use rgb inputs as arguments

After that is done, we'll want some way to sample our spaceship and to see how everything looks as we put it together. Use this code to make a simple 3D space, spawn in the starship mesh, and make the ship rotate until the user hits 'esc'

camera = CreateCamera() ;Our eyes into the 3D plane
PositionEntity camera, 0, 0.5, -6
CameraViewport camera, 0, 0, 800, 600 ;Attach eyeballs to sockets

backplane = CreatePlane()
PositionEntity backplane, 0, 0, 30
EntityColor backplane. 50, 50, 100
RotateEntity backplane, 270, 0, 0

light = CreateLight()

player = starship(150, 10, 150) ; The starship
;RotateEntity player, 0, 180, 0 ;enable this to start it rotated slightly

SetBuffer BackBuffer()

While Not KeyHit(1) ;Main game loop, play until user hits Esc
	
	WaitTimer(frameTimer)
	
	TurnEntity player, 0.5, 1, 0 ;Turn the ship so we can see it
	
	UpdateWorld ;Bring the world to life
	RenderWorld
	Flip

Wend

End
				

If you were to run that now, it would probably throw a ton of errors since we haven't made our starship mesh yet. Let's get on with that...

Step 3: Brushes and surfaces (materials)

"p"As with "real" art, you need to get the materials before you can start making your masterpiece. In Blitz3D, you do this using brushes. You then assign the brush to a surface, which you will see in the next step. You use surfaces when adding faces to a mesh. Assigned to faces when the faces are created, surfaces allow you to choose the color, material, shading, etc. of different faces. For our spaceship: we'll be using these brushes:

hullbrush = CreateBrush() ;Shiny silver (metal)
BrushColor hullbrush, 170, 170, 170
BrushShininess hullBrush, 0.7

windowbrush = CreateBrush() ;Shiny black brush (glass)
BrushColor windowbrush, 18, 18, 18
BrushShininess windowbrush, 1

wingbrush = CreateBrush() ;Less-shiny customizable brush for wings
brushColor wingBrush, ship_r, ship_g, ship_b
BrushShininess wingbrush, 1
				

Just place that code at the start of your mesh-spawning function

Step 4: Making the mesh

Now comes the tedious part: the part where you have to define every vertex and face. When you do this, you have to be careful not to make your faces invert, or you'll see through your mesh. Usually, you would have to do this yourself, but I've already gotten everything done for this tutorial. Just copy this code into your mesh function:

First, we start a new mesh:

ship = CreateMesh() ;Return this at the end

Now, to make a face, we add out vertexes to a surface. As we add vertexes, they will be assigned an identifier that is exclusive to that vertex on that surface (the vertex IDs are seperate on seperate surfaces). You then take the IDs of the vertexes, then use three to add a face between them.

Make the ship's body:

hull = CreateSurface(ship, hullbrush) ;The hull/body of the ship
;Ship vertexes:
AddVertex hull, 0, 0.6, 0 ;0
AddVertex hull, 0.75, 0.2, 0.3 ;1
AddVertex hull, 0.75, 0.2, -0.3 ;2
AddVertex hull, 1.5, 0.2, 0.2 ;3
AddVertex hull, 1.5, 0.2, -0.2 ;4
AddVertex hull, 2, 0.2, 0 ;5
AddVertex hull, 1.1, -0.13, 0 ;6
AddVertex hull, 0, -0.19, 0 ;7
AddVertex hull, 0, 0.205, 0.3 ;8
AddVertex hull, 0, 0.205, -0.3 ;9
AddVertex hull, -0.7, 0.6, 0 ;10
AddVertex hull, -0.7, -0.13, 0 ;11
AddVertex hull, -0.7, 0.205, -0.3 ;12
AddVertex hull, -0.7, 0.205, 0.3 ;13
AddVertex hull, -1.7, 0.4, 0 ;14
;Ship triangles (faces)
AddTriangle hull, 0, 1, 2
AddTriangle hull, 3, 2, 1
AddTriangle hull, 3, 4, 2
AddTriangle hull, 5, 4, 3
AddTriangle hull, 4, 5, 6
AddTriangle hull, 6, 5, 3
AddTriangle hull, 6, 3, 1
AddTriangle hull, 2, 4, 6
AddTriangle hull, 6, 1, 7
AddTriangle hull, 7, 2, 6
AddTriangle hull, 7, 1, 8
AddTriangle hull, 9, 2, 7
AddTriangle hull, 8, 1, 0
AddTriangle hull, 9, 0, 2
AddTriangle hull, 7, 8, 11
AddTriangle hull, 7, 11, 9
AddTriangle hull, 13, 11, 8
AddTriangle hull, 9, 11, 12
AddTriangle hull, 8, 0, 13
AddTriangle hull, 12, 0, 9
AddTriangle hull, 10, 13, 0
AddTriangle hull, 0, 12, 10
AddTriangle hull, 14, 11, 13
AddTriangle hull, 13, 10, 14
AddTriangle hull, 14, 12, 11
AddTriangle hull, 14, 10, 12
				

And the window:

window = CreateSurface(ship, windowbrush) ;The following vertex/triangle code adds the window on the ship
	
AddVertex window, 0, 0.6, 0 ;0
AddVertex window, 0.68, 0.48, 0 ;1
AddVertex window, 0.75, 0.2, 0.3 ;2
AddVertex window, 0.75, 0.2, -0.3 ;3
AddVertex window, 1.5, 0.2, 0.2 ;4
AddVertex window, 1.5, 0.2, -0.2 ;5

AddTriangle window, 2, 1, 0
AddTriangle window, 0, 1, 3
AddTriangle window, 4, 1, 2
AddTriangle window, 3, 1, 5
AddTriangle window, 1, 4, 5
				

And the wings:

wings = CreateSurface(ship, wingbrush) ;The ship's wings 'n' stuff
	
AddVertex wings, -0.2, 0.1, 0 ;0
AddVertex wings, 0.4, 0.2, 0 ;1
AddVertex wings, 1, 0.1, 0 ;2
AddVertex wings, 0.4, 0, 0 ;3
AddVertex wings, -1.2, -0.4, -1.2 ;4
AddVertex wings, -1.2, -0.4, 1.2 ;5
AddVertex wings, 1.25, 0, 0 ;6
AddVertex wings, 1.25, 0.05, 0 ;7
AddVertex wings, 1.4, 0, 0 ;8
AddVertex wings, 1.25, -0.05, 0 ;9
AddVertex wings, 0.8, -0.4, 0.6 ;10
AddVertex wings, 1, -0.4, -0.6 ;11
AddVertex wings, -0.4, 0.6, 0 ;12
AddVertex wings, -1.4, 0.4, 0.02 ;13
AddVertex wings, -1.4, 0.4, -0.02;14
AddVertex wings, -2, 0.8, 0 ;15

AddTriangle wings, 0, 1, 4 ;Main wings
AddTriangle wings, 5, 1, 0
AddTriangle wings, 1, 2, 4
AddTriangle wings, 5, 2, 1
AddTriangle wings, 2, 3, 4
AddTriangle wings, 5, 3, 2
AddTriangle wings, 3, 0, 4
AddTriangle wings, 5, 0, 3
AddTriangle wings, 10, 7, 6 ;Aux wings
AddTriangle wings, 6, 7, 11
AddTriangle wings, 10, 8, 7
AddTriangle wings, 7, 8, 11
AddTriangle wings, 10, 9, 8
AddTriangle wings, 8, 9, 11
AddTriangle wings, 10, 6, 9
AddTriangle wings, 9, 6, 11
AddTriangle wings, 12, 14, 15 ;Fin
AddTriangle wings, 15, 13, 12
AddTriangle wings, 13, 15, 14
				

Step 5: Wrapping up

Now, to finalize our mesh, we have to update our normals. This would usually take many lines of code, but Blitz has a nice feature for that:

UpdateNormals(ship)

Lastly, we'll want to return our ship so that our program will actually use the mesh it just assembled:

Return ship ;Use 'var = starship(r, g, b)' to shove this all into a variable and add it to the world

Step 6: We're done!

Now save the program, run it, and you should get this:

The result of the above code, a finished starship

I encourage you to poke around at the code and see what you can do. I hope that by reading this, you realize how convenient it is that 3D design software exists so that we don't get carpal-tunnel typing in the vertexes for a single low-poly mesh.

If you can't get it to work or are too lazy to do all of that typing, click here to download the finished file.