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