Bootstrap

DirectX12魔方的简易实现

DirectX12魔方的简易实现

最近在看DirectX12,想要写个小东西练手一下。一直有一个思路就是做一个模拟魔方的程序,感觉跟DirectX12也没啥关系,就当是熟悉下《DirectX12 3D游戏开发实战》的源码吧。
效果图:
在这里插入图片描述
按A键可以更改旋转平面,B键可以选择旋转平面,T键进行旋转,通过更改参数可以达到任意阶数(只要电脑好。。)
如图:
在这里插入图片描述
1.代码思路
对于n阶阶数的魔方,可以看作n* n* n个小立方体的组成,然后旋转其实就是对于旋转平面内所有的小立方体的旋转,故只要写一个类用来生成,操作小立方体即可。但是正常一想,其实魔方需要只是6个面而已,这样作的确是浪费空间了,也会影响渲染效率(影响的确很大),但是这样考虑更简单,对于7阶及以下没有任何压力,代码也更简单。
在渲染上面,没有进行更多的更改。按道理来讲,因为我们的立方体的位置是会发生变化的,所以应该放在上传堆中,但是这样就很麻烦。《DirectX12 3D游戏开发实战》中直接有现成的MeshGeometry来用。我是直接用了一个n* n*n的MeshGeometry数组,每个MeshGeometry都只负责一个立方体的绘制。其实可以把所有的立方体数据都放在一个MeshGeometry中,但是这样要修改索引,在渲染的时候也很烦。太懒了,干脆直接在渲染的时候切换MeshGeometry数据好了。
2.关键部分
1.顶点数据

struct Vertex
{
	XMFLOAT3 Pos;
	XMFLOAT4 Color;
};

2.立方体

struct Box_part {
	Vertex v[8];//八个顶点,但是不够用了
	Vertex colored_v[36];//能正确映射颜色的定点组
	XMFLOAT3 center;//中心
};

3.外线条

struct Line_part {
	Vertex v[8];
};

4.BoxController类(最关键的一个)

class BoxController
{
private:
	int m_levels;//魔方的阶数
	float m_size;//魔方的大小,这是单位正方体边长的1/2
	int m_move_step[3];//表示往x,y,z面的选取次数
	int m_convert_step;//表示转换旋转面的次数
	bool if_transformed = false;
	bool if_inited = false;

	XMFLOAT4 m_colors_line_chosed;
	XMFLOAT4 m_colors_line_unchosed;

	XMFLOAT4 m_offset_color;
	//因为物体已经放在了世界坐标系的原点,所以
	//旋转方向实际上就是x,y,z,直接用,但是先计算好旋转矩阵可能会简单和效率些
	XMMATRIX m_rotation_mat[3];//这里的顺序有一定要求

	XMFLOAT4 m_colors_array[6];//六个面六个颜色

	/*
	*	其中0表示前面,1表示后面,2表示左面,3表示右面,4表示上面,5表示下面
	*/
	XMFLOAT4 m_default_color;//没有颜色的顶点的默认颜色

	//内部方法
	void InitBox();//这个方法有缺陷,但是它可以正确计算到每一个小正方形的位置,保留
	void InitSingleCube(int _i,int _j,int _k);//这个方法进行完善,使Box中的每一个cube都产生魔方一样的效果
	void UpdateBoxColor();
	//这个函数有点难,需要进行线性插值,暂时先不管线性插值了
	void UpdateBoxPosition();//这里的position指box_part

	//数据
	Box_part box_array[max_levels][max_levels][max_levels];
	Line_part line_array[max_levels][max_levels][max_levels];

	//辅助方法
	XMFLOAT3 add(XMFLOAT3& v1, XMFLOAT3& v2);
	XMFLOAT4 add(XMFLOAT4& v1,XMFLOAT4& v2);
	XMFLOAT3 Muliply(XMFLOAT3& v1,float scale);
public:
	BoxController(int _levels,float _size);
	BoxController();
	void SetColors(XMFLOAT4* _colors_array);
	void MovePlane();
	void ConvertPlane();
	void TransformPlane();//旋转了
	void Update();//对外界进行的一个函数
	void GetBoxVertex(int _i,int _j,int _k,Vertex* _v);//返回指定小box的顶点信息
	void GetLineVertex(int _i,int _j,int _k,Vertex* _v);
	//void GetData(Box_part*** box_array);
	~BoxController();
};

4.BoxController细节
(1).BoxController构造函数

BoxController::BoxController(int _levels,float _size) {
	m_levels = _levels;
	m_size = _size;
	//默认颜色
	m_colors_array[0] = XMFLOAT4(Colors::Cyan);
	m_colors_array[1] = XMFLOAT4(Colors::PaleVioletRed);
	m_colors_array[2] = XMFLOAT4(Colors::Green);
	m_colors_array[3] = XMFLOAT4(Colors::DarkOrange);
	m_colors_array[4] = XMFLOAT4(Colors::Lavender);
	m_colors_array[5] = XMFLOAT4(Colors::Lime);
	m_default_color = XMFLOAT4(Colors::Blue);
	//默认状态
	m_move_step[0]=0,m_move_step[1]=0,m_move_step[2]=0;
	m_convert_step = 0;
	//计算旋转矩阵
	m_rotation_mat[0] = XMMatrixRotationX(PI * 0.5f);
	m_rotation_mat[1] = XMMatrixRotationY(PI * 0.5f);
	m_rotation_mat[2] = XMMatrixRotationZ(PI * 0.5f);
	//设置线条颜色
	m_colors_line_chosed = XMFLOAT4(Colors::Red);
	m_colors_line_unchosed = XMFLOAT4(Colors::Blue);
	m_offset_color = XMFLOAT4(0.2f,0.2f,0.2f,0.5f);
	InitBox();
}
BoxController::BoxController() {
	BoxController(3,2);
}

(2).MovePlane() //用来移动旋转平面的

void BoxController::MovePlane() {
	m_move_step[m_convert_step]++;
	if (m_move_step[m_convert_step] > m_levels - 1) {
		m_move_step[m_convert_step] = 0;
	}
}

(3).ConvertPlane() //用来转换旋转平面的

void BoxController::ConvertPlane() {
	m_convert_step++;
	if (m_convert_step > 2) {
		m_convert_step = 0;
	}
}

(4).TransformPlane() //旋转

void BoxController::TransformPlane() {
	if_transformed = true;
}

(5).向量操作的辅助函数
好像这些运算似乎内置了,不过没找到就自己写了下

XMFLOAT3 BoxController::add(XMFLOAT3& v1, XMFLOAT3& v2) {
	XMFLOAT3 temp = XMFLOAT3(0, 0, 0);
	temp.x = v1.x + v2.x;
	temp.y = v1.y + v2.y;
	temp.z = v1.z + v2.z;
	return temp;
}

XMFLOAT4 BoxController::add(XMFLOAT4& v1, XMFLOAT4& v2) {
	XMFLOAT4 temp = XMFLOAT4(0, 0, 0,0);
	temp.x = v1.x + v2.x;
	temp.y = v1.y + v2.y;
	temp.z = v1.z + v2.z;
	temp.w = v1.w + v2.w;
	return temp;
}

XMFLOAT3 BoxController::Muliply(XMFLOAT3& v1, float scale) {
	XMFLOAT3 temp = XMFLOAT3(0, 0, 0);
	temp.x = v1.x * scale;
	temp.y = v1.y * scale;
	temp.z = v1.z * scale;
	return temp;
}

(5).InitBox() //初始化魔方

void BoxController::InitBox() {
	//box_array = new Box_part**[m_levels];
	//一开始本来想动态分配内存的,但是太麻烦了就懒得弄了
	//先计算位置
	XMFLOAT3 offset_p = XMFLOAT3(-m_size*m_levels,-m_size*m_levels,-m_size*m_levels);//计算偏移中心原点的量
	XMFLOAT3 ways[8] = { {-1.0f,-1.0f,-1.0f},{-1.0f,1.0f,-1.0f},{1.0f,1.0f,-1.0f},{1.0f,-1.0f,-1.0f},{-1.0f,-1.0f,1.0f},{-1.0f,1.0f,1.0f},{1.0f,1.0f,1.0f},{1.0f,-1.0f,1.0f} };
	for (int i = 0; i < 8; i++) {
		ways[i] = Muliply(ways[i],m_size);
	}
	for (int i = 0; i < m_levels; i++) {
		for (int j = 0; j < m_levels; j++) {
			for (int k = 0; k < m_levels; k++) {
				//计算得到中心位置
				XMFLOAT3 p = XMFLOAT3(m_size+i*m_size*2,m_size+j*m_size*2,m_size+k*m_size*2);
				p = add(p, offset_p);
				box_array[i][j][k].center = p;
				//向八个方向计算顶点
				for (int temp = 0; temp < 8; temp++) {
					box_array[i][j][k].v[temp].Pos = add(p, ways[temp]);
				}
				InitSingleCube(i, j, k);
			}
		}
	}
	//UpdateBoxColor();//一开始就得有显色的效果不然看不出来
	if_inited = true;
}

(6).InitSingleCube() //最烦的函数之一。。

void BoxController::InitSingleCube(int _i,int _j,int _k) {
	/*
*	其中0表示前面,1表示后面,2表示左面,3表示右面,4表示上面,5表示下面
*/
	//这里的define完全是为了书写方便。。。。,太懒了
#define d1 box_array[_i][_j][_k].colored_v
#define d2 box_array[_i][_j][_k].v
	//前边
	d1[0] = Vertex({ d2[0].Pos,m_colors_array[0] });//设置位置和颜色
	d1[1] = Vertex({ d2[1].Pos,m_colors_array[0] });
	d1[2] = Vertex({ d2[2].Pos,m_colors_array[0] });

	d1[3] = Vertex({ d2[0].Pos,m_colors_array[0] });
	d1[4] = Vertex({ d2[2].Pos,m_colors_array[0] });
	d1[5] = Vertex({ d2[3].Pos,m_colors_array[0] });
	//后边
	d1[6] = Vertex({ d2[4].Pos,m_colors_array[1] });
	d1[7] = Vertex({ d2[6].Pos,m_colors_array[1] });
	d1[8] = Vertex({ d2[5].Pos,m_colors_array[1] });

	d1[9] = Vertex({ d2[4].Pos,m_colors_array[1] });
	d1[10] = Vertex({ d2[7].Pos,m_colors_array[1] });
	d1[11] = Vertex({ d2[6].Pos,m_colors_array[1] });
	//左面
	d1[12] = Vertex({ d2[4].Pos,m_colors_array[2] });
	d1[13] = Vertex({ d2[5].Pos,m_colors_array[2] });
	d1[14] = Vertex({ d2[1].Pos,m_colors_array[2] });

	d1[15] = Vertex({ d2[4].Pos,m_colors_array[2] });
	d1[16] = Vertex({ d2[1].Pos,m_colors_array[2] });
	d1[17] = Vertex({ d2[0].Pos,m_colors_array[2] });
	//右边
	d1[18] = Vertex({ d2[3].Pos,m_colors_array[3] });
	d1[19] = Vertex({ d2[2].Pos,m_colors_array[3] });
	d1[20] = Vertex({ d2[6].Pos,m_colors_array[3] });

	d1[21] = Vertex({ d2[3].Pos,m_colors_array[3] });
	d1[22] = Vertex({ d2[6].Pos,m_colors_array[3] });
	d1[23] = Vertex({ d2[7].Pos,m_colors_array[3] });
	//上面
	d1[24] = Vertex({ d2[1].Pos,m_colors_array[4] });
	d1[25] = Vertex({ d2[5].Pos,m_colors_array[4] });
	d1[26] = Vertex({ d2[6].Pos,m_colors_array[4] });

	d1[27] = Vertex({ d2[1].Pos,m_colors_array[4] });
	d1[28] = Vertex({ d2[6].Pos,m_colors_array[4] });
	d1[29] = Vertex({ d2[2].Pos,m_colors_array[4] });
	//下边
	d1[30] = Vertex({ d2[4].Pos,m_colors_array[5] });
	d1[31] = Vertex({ d2[0].Pos,m_colors_array[5] });
	d1[32] = Vertex({ d2[3].Pos,m_colors_array[5] });

	d1[33] = Vertex({ d2[4].Pos,m_colors_array[5] });
	d1[34] = Vertex({ d2[3].Pos,m_colors_array[5] });
	d1[35] = Vertex({ d2[7].Pos,m_colors_array[5] });

#define i1 line_array[_i][_j][_k].v
	for (int i = 0; i < 8; i++) {
		i1[i] = Vertex({d2[i].Pos,m_colors_line_unchosed});
	}
	//线条也在这里进行位置的初始化

}

(7).UpdateBoxColor() //把未选中平面的立方体颜色改成默认颜色

void BoxController::UpdateBoxColor(){
	for (int i = 0; i < m_levels; i++) {
		for (int j = 0; j < m_levels; j++) {
			for (int k = 0; k < m_levels; k++) {
				for (int temp = 0; temp < 8; temp++) {
					line_array[i][j][k].v[temp].Color = m_colors_line_unchosed;
				}
			}
		}
	 }
}

(8).UpdateBoxPosition() //最烦的函数,光是bug就改了好几天

void BoxController::UpdateBoxPosition() {
	//还要转成向量来进行计算,在转回来
	int state = m_move_step[m_convert_step];
	//m_convert_step决定了是哪种面(x,y,z)
	//state决定了该面种的哪个面(0-m_levles)
	XMVECTOR v;
	UpdateBoxColor();
	float sub = 0.0f;
	const float max_sub = 0.1f;
	//处理x坐标的
	int num = 0;
#define debugv box_array[i][j][k].center
	OutputDebugString(L"\n");
	if (m_convert_step == 0) {
		for (int i = 0; i < m_levels; i++) {
			for (int j = 0; j < m_levels; j++) {
				for (int k = 0; k < m_levels; k++) {
					//找到这些box
					sub=abs(box_array[i][j][k].center.x-(m_size + (float)state * m_size * 2 - m_size * (float)m_levels));
					if (sub<max_sub) {
						for (int temp = 0; temp < 36; temp++) {
							XMFLOAT3 temp_p = box_array[i][j][k].colored_v[temp].Pos;
							v = XMLoadFloat3(&temp_p);
							v = XMVector3TransformCoord(v, m_rotation_mat[0]);
							XMStoreFloat3(&box_array[i][j][k].colored_v[temp].Pos, v);
							//box_array[i][j][k].colored_v[temp].Color.x += 0.25f;
							//box_array[i][j][k].colored_v[temp].Color = add(box_array[i][j][k].colored_v[temp].Color ,m_offset_color);
							//UpdateBoxColor(i, j, k);
						}
						for (int temp = 0; temp < 8; temp++) {
							line_array[i][j][k].v[temp].Color = m_colors_line_chosed;
							XMFLOAT3 temp_p = line_array[i][j][k].v[temp].Pos;
							v = XMLoadFloat3(&temp_p);
							v = XMVector3TransformCoord(v, m_rotation_mat[0]);
							XMStoreFloat3(&line_array[i][j][k].v[temp].Pos, v);
						}
						XMFLOAT3 temp_p = box_array[i][j][k].center;
						v = XMLoadFloat3(&temp_p);
						v = XMVector3TransformCoord(v, m_rotation_mat[0]);
						XMStoreFloat3(&box_array[i][j][k].center, v);
					}
				}
			}
		}
		return;
	}
	if (m_convert_step == 1) {
		for (int i = 0; i < m_levels; i++) {
			for (int j = 0; j < m_levels; j++) {
				for (int k = 0; k < m_levels; k++) {
					//找到这些box
					sub = abs(box_array[i][j][k].center.y - (m_size + (float)state * m_size * 2 - m_size * (float)m_levels));
					if (sub<max_sub) {
						for (int temp = 0; temp < 36; temp++) {
							XMFLOAT3 temp_p = box_array[i][j][k].colored_v[temp].Pos;
							v = XMLoadFloat3(&temp_p);
							v = XMVector3TransformCoord(v, m_rotation_mat[1]);
							XMStoreFloat3(&box_array[i][j][k].colored_v[temp].Pos, v);
							//box_array[i][j][k].colored_v[temp].Color.x += 0.25f;
							//box_array[i][j][k].colored_v[temp].Color = add(box_array[i][j][k].colored_v[temp].Color, m_offset_color);
							//UpdateBoxColor(i,j,k);
						}
						for (int temp = 0; temp < 8; temp++) {
							line_array[i][j][k].v[temp].Color = m_colors_line_chosed;
							XMFLOAT3 temp_p = line_array[i][j][k].v[temp].Pos;
							v = XMLoadFloat3(&temp_p);
							v = XMVector3TransformCoord(v, m_rotation_mat[1]);
							XMStoreFloat3(&line_array[i][j][k].v[temp].Pos, v);
						}
						XMFLOAT3 temp_p = box_array[i][j][k].center;
						v = XMLoadFloat3(&temp_p);
						v = XMVector3TransformCoord(v, m_rotation_mat[1]);
						XMStoreFloat3(&box_array[i][j][k].center, v);
					}
				}
			}
		}
		return;
	}
	if (m_convert_step == 2) {
		for (int i = 0; i < m_levels; i++) {
			for (int j = 0; j < m_levels; j++) {
				for (int k = 0; k < m_levels; k++) {
					//找到这些box
					sub = abs(box_array[i][j][k].center.z - (m_size + (float)state * m_size * 2 - m_size * (float)m_levels));
					if (sub<max_sub) {
						for (int temp = 0; temp < 36; temp++) {
							XMFLOAT3 temp_p = box_array[i][j][k].colored_v[temp].Pos;
							v = XMLoadFloat3(&temp_p);
							v = XMVector3TransformCoord(v, m_rotation_mat[2]);
							XMStoreFloat3(&box_array[i][j][k].colored_v[temp].Pos, v);
							//box_array[i][j][k].colored_v[temp].Color.x += 0.25f;
							//box_array[i][j][k].colored_v[temp].Color = add(box_array[i][j][k].colored_v[temp].Color, m_offset_color);
							//UpdateBoxColor(i, j, k);
						}
						for (int temp = 0; temp < 8; temp++) {
							line_array[i][j][k].v[temp].Color = m_colors_line_chosed;
							XMFLOAT3 temp_p = line_array[i][j][k].v[temp].Pos;
							v = XMLoadFloat3(&temp_p);
							v = XMVector3TransformCoord(v, m_rotation_mat[2]);
							XMStoreFloat3(&line_array[i][j][k].v[temp].Pos, v);
						}
						XMFLOAT3 temp_p = box_array[i][j][k].center;
						v = XMLoadFloat3(&temp_p);
						v = XMVector3TransformCoord(v, m_rotation_mat[2]);
						XMStoreFloat3(&box_array[i][j][k].center, v);
					}
				}
			}
		}
		return;
	}
}

(9).更新和得到顶点数据

void BoxController::Update() {
	if (!if_inited) return;
	//旋转了就旋转
	if (if_transformed == true ) {
		UpdateBoxPosition();
		if_transformed = false;
	}
}

void BoxController::GetBoxVertex(int _i, int _j, int _k, Vertex* _v) {
	Box_part temp_box_part = box_array[_i][_j][_k];
	for (int i = 0; i < 36; i++) {
		*(_v + i) = Vertex(
			{ XMFLOAT3(temp_box_part.colored_v[i].Pos.x,temp_box_part.colored_v[i].Pos.y,temp_box_part.colored_v[i].Pos.z),
				temp_box_part.colored_v[i].Color }
		);
	}
}

void BoxController::GetLineVertex(int _i, int _j, int _k, Vertex* _v) {
	Line_part temp_line_part = line_array[_i][_j][_k];
	for (int i = 0; i < 8; i++) {
		*(_v + i) = Vertex({temp_line_part.v[i].Pos,temp_line_part.v[i].Color});
	}
}

3.接下来就是渲染了
魔改了BoxApp
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

void BoxApp::BuildBoxes() {
    int p = 0;
    //mBoxGeo = std::make_unique<MeshGeometry>(m_boxes_geo[p]);
    for (int i = 0; i < m_levels; i++) {
        for (int j = 0; j < m_levels; j++) {
            for (int k = 0; k < m_levels; k++) {
                mBoxGeo[p] = std::make_unique<MeshGeometry>();
                mLineGeo[p] = std::make_unique<MeshGeometry>();
                BuildBoxGeometry(i, j, k,p);
                p++;
            }
        }
    }
}
//相当于每一次的Update都要进行一次
void BoxApp::BuildBoxGeometry(int _i,int _j,int _k,int _p)
{
    //原来有的注释掉了
    ObjectVertexs v;
    //顶点数据
    m_boxes_controller->GetBoxVertex(_i, _j, _k, v.v);
    std::array<Vertex, 36> vertices;
    for (int i = 0; i < 36; i++) {
        vertices[i] = v.v[i];
    }
    //m_boxes_vertex_ub[_i][_j][_k]->CopyData(0,v);
    /*
    std::array<Vertex, 8> vertices =
    {
        Vertex({ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::White) }),
		Vertex({ XMFLOAT3(-1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Black) }),
		Vertex({ XMFLOAT3(+1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Red) }),
		Vertex({ XMFLOAT3(+1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
		Vertex({ XMFLOAT3(-1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Blue) }),
		Vertex({ XMFLOAT3(-1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Yellow) }),
		Vertex({ XMFLOAT3(+1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Cyan) }),
		Vertex({ XMFLOAT3(+1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Magenta) })
    };
    */
    /*
	std::array<std::uint16_t, 36> indices =
	{
		// front face
		0, 1, 2,
		0, 2, 3,

		// back face
		4, 6, 5,
		4, 7, 6,

		// left face
		4, 5, 1,
		4, 1, 0,

		// right face
		3, 2, 6,
		3, 6, 7,

		// top face
		1, 5, 6,
		1, 6, 2,

		// bottom face
		4, 0, 3,
		4, 3, 7
	};
    */
    std::array<std::uint16_t, 108> indices;
    for (int i = 0; i < 108; i++) {
        indices[i] = i;
    }
    const UINT vbByteSize = (UINT)vertices.size() * sizeof(Vertex);
	const UINT ibByteSize = (UINT)indices.size() * sizeof(std::uint16_t);

	mBoxGeo[_p]->Name = "boxGeo";

	ThrowIfFailed(D3DCreateBlob(vbByteSize, &mBoxGeo[_p]->VertexBufferCPU));
	CopyMemory(mBoxGeo[_p]->VertexBufferCPU->GetBufferPointer(), vertices.data(), vbByteSize);

	ThrowIfFailed(D3DCreateBlob(ibByteSize, &mBoxGeo[_p]->IndexBufferCPU));
	CopyMemory(mBoxGeo[_p]->IndexBufferCPU->GetBufferPointer(), indices.data(), ibByteSize);

    //这两个地方被魔改了
    mBoxGeo[_p]->VertexBufferGPU = d3dUtil::CreateDefaultBuffer(md3dDevice.Get(),
		mCommandList.Get(), vertices.data(), vbByteSize, mBoxGeo[_p]->VertexBufferUploader);

    //mBoxGeo[_p]->SetVertexBufferView(m_boxes_vertex_ub[_i][_j][_k]->GetGPU_VIRTUAL_ADDRESS());

    mBoxGeo[_p]->IndexBufferGPU = d3dUtil::CreateDefaultBuffer(md3dDevice.Get(),
		mCommandList.Get(), indices.data(), ibByteSize, mBoxGeo[_p]->IndexBufferUploader);

    mBoxGeo[_p]->VertexByteStride = sizeof(Vertex);
    mBoxGeo[_p]->VertexBufferByteSize = vbByteSize;
    mBoxGeo[_p]->IndexFormat = DXGI_FORMAT_R16_UINT;
    mBoxGeo[_p]->IndexBufferByteSize = ibByteSize;

	SubmeshGeometry submesh;
	submesh.IndexCount = (UINT)indices.size();
	submesh.StartIndexLocation = 0;
	submesh.BaseVertexLocation = 0;

    mBoxGeo[_p]->DrawArgs["box"] = submesh;

    //接下里是线条的
        //原来有的注释掉了
    //顶点数据
    m_boxes_controller->GetLineVertex(_i, _j, _k, v.v);
    std::array<Vertex, 8> vertices_line;
    for (int i = 0; i < vertices_line.size(); i++) {
        vertices_line[i] = v.v[i];
    }

    std::array<std::uint16_t, 25> indices_line;
    indices_line = {
        0,1,1,2,2,3,3,0,
        4,5,5,6,6,7,7,4,
        0,4,1,5,2,6,3,7};

    const UINT vbByteSize_line = (UINT)vertices_line.size() * sizeof(Vertex);
    const UINT ibByteSize_line = (UINT)indices_line.size() * sizeof(std::uint16_t);

    mLineGeo[_p]->Name = "boxGeo";

    ThrowIfFailed(D3DCreateBlob(vbByteSize_line, &mLineGeo[_p]->VertexBufferCPU));
    CopyMemory(mLineGeo[_p]->VertexBufferCPU->GetBufferPointer(), vertices_line.data(), vbByteSize_line);

    ThrowIfFailed(D3DCreateBlob(ibByteSize_line, &mLineGeo[_p]->IndexBufferCPU));
    CopyMemory(mLineGeo[_p]->IndexBufferCPU->GetBufferPointer(), indices_line.data(), ibByteSize_line);

    //这两个地方被魔改了
    mLineGeo[_p]->VertexBufferGPU = d3dUtil::CreateDefaultBuffer(md3dDevice.Get(),
        mCommandList.Get(), vertices_line.data(), vbByteSize_line, mLineGeo[_p]->VertexBufferUploader);

    //mLineGeo[_p]->SetVertexBufferView(m_boxes_vertex_ub[_i][_j][_k]->GetGPU_VIRTUAL_ADDRESS());

    mLineGeo[_p]->IndexBufferGPU = d3dUtil::CreateDefaultBuffer(md3dDevice.Get(),
        mCommandList.Get(), indices_line.data(), ibByteSize_line, mLineGeo[_p]->IndexBufferUploader);

    mLineGeo[_p]->VertexByteStride = sizeof(Vertex);
    mLineGeo[_p]->VertexBufferByteSize = vbByteSize_line;
    mLineGeo[_p]->IndexFormat = DXGI_FORMAT_R16_UINT;
    mLineGeo[_p]->IndexBufferByteSize = ibByteSize_line;

    submesh.IndexCount = (UINT)indices_line.size();
    submesh.StartIndexLocation = 0;
    submesh.BaseVertexLocation = 0;

    mLineGeo[_p]->DrawArgs["box"] = submesh;
    
}

在这里插入图片描述
更新操作
在这里插入图片描述
这里的min_time是为了防止响应太快而按次a键操作两次

终于完成,代码跟屎一样,我要吐了,本人能力有限啊,终究是留下了没技术的眼泪,不过好歹功能是完成了,改代码,优化?不存在的。。。。

;