H_3D_Engine
简单的 3D 引擎绘制线框 3D 图形。

引言
欢迎来到我的3D引擎。
它被称为H3D
引擎,并且以线框和点绘制3D形状。
我试图使其易于使用,并且代码不同且易于理解(从我的角度来看,但您的建议将不胜感激)。
背景
- 需要具备数学基础,例如 cos、sin 等。
- 需要具备矩阵的基础知识(加法、乘法)。
- 如果您对面向对象编程(OOP)有很好的了解,那就最好不过了,如果您没有,那么这篇文章可能对您没有帮助,或者它可能会很有趣,谁知道呢?
- 需要具备关于3D图形的基础知识(顶点、三角形等)。
Using the Code
在我们的引擎中,我们有四个主要结构,可以帮助我们组织数据。它们定义如下:
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
}
第一个结构tri_angle
用于描述我们的索引(三角形),第二个结构GVerts3D
用于描述我们的3D几何体(顶点)。第三个结构将在我们从3D投影到2D时提供帮助,因为我们的屏幕是平面的,最后一个是enum
,它可以帮助我们以一种简单的方式确定渲染类型。
在这里,我将向您展示如何使用H3D
引擎,如果您对其设计感兴趣,可以下载源代码(从此页顶部的链接),并自行检查。
在这里,我们定义了两个主要对象,以及引擎的实例,这里称为h3d
。
private GVerts3D[] Geom;
private tri_angle[] trt;
private H3DX h3d;
H3DX
定义如下:
namespace H_3D_Engine
{
class H3DX
{
// -------Constructors-------
//public H3DX()
//public H3DX(int w,int h,int FOVLens)
// -------Methods-------
//public void SetView(int w, int h)
//public void SetStream(GVerts3D[] Verts)
//public void SetStreamIndex(tri_angle[] indx)
//public void SetMatrix(CMatrix4 TM)
//public void Trnslate(int x,int y,int z)
//public CMatrix4 GetMatrix()
//public void SetRenderMode(RenderType t)
//public RenderType GetRenderMode()
//public void Clear(Color c)
//public void Push()
//public void Present(Graphics g)
//
//private GVerts2D Project2DD(GVerts3D Verts)
// -------Variables-------
//private Bitmap mb;
//private Graphics tdc;
//private CMatrix4 HMat = new CMatrix4();
//private GVerts3D[] HVerts;
//private tri_angle[] index;
//private int HWidth;
//private int Lens;
//private int HHeight;
//private int tx, ty, tz;
//private bool Ver_Render = false;
}
}
现在,在定义了变量之后,我们可以在Form1_Load
中只初始化它们一次,如下所示:
private void Form1_Load(object sender, EventArgs e)
{
//variables needed for rotation
Angle = xAngle = yAngle = zAngle = 0;
iX = iZ = 0;
iY = 1;
//setup our cube
SetupDefaultMesh();
//initializing our variables...
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 只是一个PictureBox
,我们正在其中绘制。
但是问题是:CMatrix4
是什么?CMatrix4
是一个非常有用的类,可以帮助我们以一种简单的方式旋转、平移或缩放3D对象,它定义如下:
namespace H_3D_Engine
{
class CMatrix4
{
// -------Constructors-------
//public CMatrix4()
// -------Methods-------
//public void RotateX(double degree); //| 0 1 2 3 |
//public void RotateY(double degree); //| 4 5 6 7 |
//public void RotateZ(double degree); //| 8 9 10 11 |
//public void Scale(float s); //| 12 13 14 15 |
//public void Translate(GVerts3D v)
//public static double ToRadian(double angle)
//operators
//static public CMatrix4 operator *(CMatrix4 m1, CMatrix4 m2)
// -------Variables-------
//public float[] _Mat = new float[16];
}
}
现在我们准备好设置我们的几何体了。以下是定义一个简单立方体的一个简单过程:
void SetupDefaultMesh()
{
Geom = new GVerts3D[]{
new GVerts3D( 1 ,1, 1), //0 right up
new GVerts3D(-1 ,1, 1), //1 left up
new GVerts3D(-1,-1, 1), //2 left down
new GVerts3D( 1,-1, 1), //3 right down
new GVerts3D( 1 ,1, -1), //4
new GVerts3D(-1 ,1, -1), //5
new GVerts3D(-1,-1, -1), //6
new GVerts3D( 1,-1, -1), //7
};
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),
};
}
所以,在这里我们将要做有趣的事情,DrawScene
过程,定义如下:
void DrawScene()
{
h3d.Clear(Color.Blue);
objMatrix.LoadIdentity(45);
//scale our mesh to 1
hscaleMatrix.Scale(ms);
objMatrix *= hscaleMatrix;
//Translate to origin
hTrans.Translate(new GVerts3D(0, 0, 0));
objMatrix *= hTrans;
//rotate around (-1,0,-1) in 3 steps
//1.translate into that point
hTrans.Translate(new GVerts3D(-1, 0, -1));
objMatrix *= hTrans;
//2. do rotation
hRotMatrixY.RotateY(CMatrix4.ToRadian(yAngle));
objMatrix *= hRotMatrixY;
//3.Translate it back
hTrans.Translate(new GVerts3D(1, 0, 1));
objMatrix *= hTrans;
//hRotMatrixZ.RotateZ(CMatrix.ToRadian(zAngle));
//objMatrix *= hRotMatrixZ;
h3d.SetMatrix(objMatrix);
h3d.SetStream(Geom);
h3d.SetStreamIndex(trt);
//h3d.SetRenderMode(RenderType.Indx);
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.SetRenderMode(RenderType.DotsR);
h3d.Push();
//Present the scene...
h3d.Present(g);
}
我们做了什么?
首先,我们用蓝色背景颜色清除了屏幕,然后我们绘制了两次立方体,第一次围绕点(-1, 0, -1)
,第二次围绕其中心。
祝您好运!
历史
- 2009年1月24日:初始版本