65.9K
CodeProject 正在变化。 阅读更多。
Home

H_3D_Engine

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.56/5 (5投票s)

2009年1月27日

CPOL

2分钟阅读

viewsIcon

36143

downloadIcon

1517

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

CoolCode2.JPG

引言

欢迎来到我的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日:初始版本
© . All rights reserved.