Introduction
Welcome to my 3D engine.
It's called H3D Engine, and it draws 3D shapes in wireframe, dots.
I tried to make it easy to use, and the code is different and well understood (from my viewpoint, but your suggestions will be appreciated).
Background
- A background in mathematics such as cos, sin, etc.
- A background about matrices (addition, multiplication).
- It would be better if you have a good idea about OOP, and if you don't that means this article may be not helpful for you, or it might be interesting, who knows?
- Any background about 3Ds (vertices, triangles, etc.)
Using the Code
In our engine, we have four main structures that can help us to organize data. They are defined as:
public struct tri_angle
{
public tri_angle(float x, float y, float z)
{
p1 = x; p2 = y; p3 = z;
}
public float p1, p2, p3;
}
public struct GVerts3D
{
public GVerts3D(float x, float y, float z)
{
X = x; Y = y; Z = z;
}
public float X;
public float Y;
public float Z;
}
public struct GVerts2D
{
public int X;
public int Y;
}
public enum RenderType {
DotsR = 1,
Indx
}
The first structure tri_angle is used to describe our indices (triangles) and the second one GVerts3D is used to describe our 3D Geometry (Vertices). The third one would help us when we project from 3D to 2D since our screen is flat and the last one is enum, which can help us to determine the rendering type in an easy way.
Here I'm going to show you how to use H3D Engine and if you are interested in its design, you can download the source code (from the link at the top of this page) and check it yourself.
Here we define the two main objects, and the instance from the engine which is called h3d here.
private GVerts3D[] Geom;
private tri_angle[] trt;
private H3DX h3d;
The H3DX is defined as:
namespace H_3D_Engine
{
class H3DX
{
}
}
Now after we defined our variables, we can initialize them only once in Form1_Load as:
private void Form1_Load(object sender, EventArgs e)
{
Angle = xAngle = yAngle = zAngle = 0;
iX = iZ = 0;
iY = 1;
SetupDefaultMesh();
h3d = new H3DX(Paper.Width, Paper.Height, 256);
hRotMatrixX = new CMatrix4();
hRotMatrixY = new CMatrix4();
hTrans = new CMatrix4();
hscaleMatrix = new CMatrix4();
objMatrix = new CMatrix4();
g = Paper.CreateGraphics();
text4.Text = ms.ToString();
}
Paper is just a PictureBox which we are drawing into.
But the question is: what is CMatrix4?
CMatrix4 is a very helpful class that helps us to Rotate, Translate, or Scale 3D objects in an easy way and it is defined as:
namespace H_3D_Engine
{
class CMatrix4
{
}
}
Now we are ready to set up our geometry. Here is a simple procedure to define a simple cube:
void SetupDefaultMesh()
{
Geom = new GVerts3D[]{
new GVerts3D( 1 ,1, 1),
new GVerts3D(-1 ,1, 1),
new GVerts3D(-1,-1, 1),
new GVerts3D( 1,-1, 1),
new GVerts3D( 1 ,1, -1),
new GVerts3D(-1 ,1, -1),
new GVerts3D(-1,-1, -1),
new GVerts3D( 1,-1, -1),
};
trt = new tri_angle[]{
new tri_angle(0,3,1),
new tri_angle(1,2,3),
new tri_angle(0,4,7),
new tri_angle(0,3,7),
new tri_angle(1,5,6),
new tri_angle(5,6,2),
new tri_angle(1,5,4),
new tri_angle(4,0,1),
new tri_angle(6,7,3),
new tri_angle(2,3,7),
new tri_angle(4,5,6),
new tri_angle(4,7,6),
};
}
So here we are going to do the interesting thing, the DrawScene procedure, which is defined as:
void DrawScene()
{
h3d.Clear(Color.Blue);
objMatrix.LoadIdentity(45);
hscaleMatrix.Scale(ms);
objMatrix *= hscaleMatrix;
hTrans.Translate(new GVerts3D(0, 0, 0));
objMatrix *= hTrans;
hTrans.Translate(new GVerts3D(-1, 0, -1));
objMatrix *= hTrans;
hRotMatrixY.RotateY(CMatrix4.ToRadian(yAngle));
objMatrix *= hRotMatrixY;
hTrans.Translate(new GVerts3D(1, 0, 1));
objMatrix *= hTrans;
h3d.SetMatrix(objMatrix);
h3d.SetStream(Geom);
h3d.SetStreamIndex(trt);
h3d.Push();
objMatrix.LoadIdentity(45);
hscaleMatrix.Scale(ms);
objMatrix *= hscaleMatrix;
hTrans.Translate(new GVerts3D(4, 0, 0));
objMatrix *= hTrans;
hRotMatrixY.RotateY(CMatrix4.ToRadian(yAngle));
objMatrix *= hRotMatrixY;
h3d.SetMatrix(objMatrix);
h3d.SetStream(Geom);
h3d.SetStreamIndex(trt);
h3d.Push();
h3d.Present(g);
}
What did we do?
At first, we made the screen clear with blue background color and then we drew our cube two times, the first time around the point (-1, 0, -1) and the second time around its center.
Good luck!
History
- 24th January, 2009: Initial version