openg魔方

只完成了4个面,剩下2面
代码

OpenGL 魔方

#pragma once
#include <glad/glad.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include <vector>
#include <Class/Shader/Shader.h>

namespace CubeN {

	// 定义一个枚举类型,表示方向。其中FRONT表示前,BACK表示后,UP表示上,DOWN表示下,LEFT表示左,RIGHT表示右
	enum Direction {
		FRONT, // 前
		BACK,  // 后
		UP,    // 上
		DOWN,  // 下
		LEFT,  // 左
		RIGHT  // 右
	};

	// 定义一个结构体,表示魔方的颜色。其中front表示前面的颜色,back表示后面的颜色,up表示上面的颜色,down表示下面的颜色,left表示左边的颜色,right表示右边的颜色
	static struct MagicCubeColor
	{
		glm::vec3 front = glm::vec3(1.0f, 1.0f, 1.0f); // 前面的颜色为白色
		glm::vec3 back = glm::vec3(1.0f, 0.0f, 0.0f);  // 后面的颜色为红色
		glm::vec3 up = glm::vec3(1.0f, 1.0f, 0.0f);     // 上面的颜色为黄色
		glm::vec3 down = glm::vec3(0.0f, 1.0f, 0.0f);   // 下面的颜色为绿色
		glm::vec3 left = glm::vec3(0.0f, 0.0f, 1.0f);   // 左边的颜色为蓝色
		glm::vec3 right = glm::vec3(0.83f, 0.0f, 1.0f);  // 右边的颜色为紫色
	};

	// 定义一个结构体,表示魔方的位置和顶点属性。其中VAO表示顶点属性对象,VBO表示顶点缓冲对象,position表示魔方的位置
	struct MagicCubeStruct
	{
		unsigned int VAO, VBO;
		int count;
		Direction direction[3];
		bool isRotating = false;
		glm::vec3 color[3];
		glm::vec3 position;
	};

	struct MagicCubeStructInd {
		float front[9];
		float back[9];

		float up[9];
		float down[9];

		float left[9];
		float right[9];
	};

	class MagicCube
	{
	private:
		float* PCube;
		int CubeSize;
		float Cube[216] = {
			// 前面
			 1.0f, -1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			-1.0f, -1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			 1.0f,  1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			-1.0f, -1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			-1.0f,  1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			 1.0f,  1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			 // 后面
			 -1.0f,  1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
			 -1.0f, -1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
			  1.0f, -1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
			  1.0f, -1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
			  1.0f,  1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
			 -1.0f,  1.0f, -1.0f, 0.5f, 0.5f, 0.5f,

			 // 上面
			 -1.0f,  1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
			  1.0f,  1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
			  1.0f,  1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			  1.0f,  1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			 -1.0f,  1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			 -1.0f,  1.0f, -1.0f, 0.5f, 0.5f, 0.5f,

			 // 下面
			 -1.0f, -1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			  1.0f, -1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			  1.0f, -1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
			  1.0f, -1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
			 -1.0f, -1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
			 -1.0f, -1.0f,  1.0f, 0.5f, 0.5f, 0.5f,

			 // 左面
			 -1.0f, -1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			 -1.0f, -1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
			 -1.0f,  1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			 -1.0f, -1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
			 -1.0f,  1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
			 -1.0f,  1.0f,  1.0f, 0.5f, 0.5f, 0.5f,

			 // 右面
			 1.0f, -1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
			 1.0f, -1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			 1.0f,  1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
			 1.0f, -1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			 1.0f,  1.0f,  1.0f, 0.5f, 0.5f, 0.5f,
			 1.0f,  1.0f, -1.0f, 0.5f, 0.5f, 0.5f
		};
		float deltaTime;
		// 上一帧的时间
		float lastFrame;
		// 移动速度
		float speed;
		// 要旋转的面
		float* TheToRotate;
		// 旋转方向
		float rotDir = 1.0;
		// 旋转角度
		float angle;
		// 旋转向量
		glm::vec3 angleVec;
		// 创建魔方的骨架
		void Skeleton();
		// 创建魔方的上面部分
		void CreateUpper();
		// 创建魔方的中心部分
		void CreateCentre();
		// 创建魔方的下面部分
		void CreateBelow();
		// 修改魔方的面的颜色
		void ModifyCubeColor(Direction* direction, MagicCubeStruct& mcf, int count);
		// 设置魔方的网格数据
		void setupMesh(MagicCubeStruct& mcf);
		// 根据给定的方向,返回相应的颜色。
		glm::vec3 ReturnColor(Direction direction);
		// 根据给定的方向,返回相应的面
		float* ReturnFace(Direction direction);
		// 重新渲染
		void ReRendering();
		// 销毁 vao vbo
		void DeleteVertexData();
		// 是否旋转
		void IsRotating(bool rotating);
	public:
		// 魔方的颜色属性
		MagicCubeColor color;
		// 存放魔方各个位置的结构体数组
		std::vector<MagicCubeStruct> CubePos;
		MagicCubeStructInd CubeInd;
		// 初始化魔方的方法
		void MagicCubeInit();
		// 旋转
		void rotate(Direction direction);
		void Draw(Shader& shader, double currentTime);
		// 销毁
		void DeleteCube();
	};
}
#include "MagicCube.h"
namespace CubeN {

	void MagicCube::Skeleton()
	{
		MagicCubeStruct mcf;
		mcf.count = 1;
		// 后面
		mcf.direction[0] = BACK;
		mcf.color[0] = ReturnColor(BACK);
		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		mcf.position = glm::vec3(0.0f, 0.0f, -2.0f);
		CubePos.push_back(mcf); // 0
		// 前面
		mcf.direction[0] = FRONT;
		mcf.color[0] = ReturnColor(FRONT);
		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		mcf.position = glm::vec3(0.0f, 0.0f, 2.0f);
		CubePos.push_back(mcf); // 1
		// 上面
		mcf.direction[0] = UP;
		mcf.color[0] = ReturnColor(UP);
		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		mcf.position = glm::vec3(0.0f, 2.0f, 0.0f);
		CubePos.push_back(mcf);// 2
		// 下面
		mcf.direction[0] = DOWN;
		mcf.color[0] = ReturnColor(DOWN);
		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		mcf.position = glm::vec3(0.0f, -2.0f, 0.0f);
		CubePos.push_back(mcf);// 3
		// 左面
		mcf.direction[0] = LEFT;
		mcf.color[0] = ReturnColor(LEFT);
		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		mcf.position = glm::vec3(-2.0f, 0.0f, 0.0f);
		CubePos.push_back(mcf);// 4
		// 右面
		mcf.direction[0] = RIGHT;
		mcf.color[0] = ReturnColor(RIGHT);
		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		mcf.position = glm::vec3(2.0f, 0.0f, 0.0f);
		CubePos.push_back(mcf);// 5
	}

	void MagicCube::CreateUpper()
	{
		MagicCubeStruct mcf;
		mcf.count = 3;
		// 左前
		mcf.position = glm::vec3(-2.0f, 2.0f, 2.0f);
		mcf.direction[0] = FRONT; // 前
		mcf.direction[1] = LEFT; // 左
		mcf.direction[2] = UP; // 上

		mcf.color[0] = ReturnColor(FRONT);
		mcf.color[1] = ReturnColor(LEFT);
		mcf.color[2] = ReturnColor(UP);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 6

		// 左后
		mcf.position = glm::vec3(-2.0f, 2.0f, -2.0f);
		mcf.direction[0] = BACK; // 后
		mcf.direction[1] = LEFT; // 左
		mcf.direction[2] = UP; // 上

		mcf.color[0] = ReturnColor(BACK);
		mcf.color[1] = ReturnColor(LEFT);
		mcf.color[2] = ReturnColor(UP);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 7

		// 右前
		mcf.position = glm::vec3(2.0f, 2.0f, 2.0f);
		mcf.direction[0] = FRONT; // 前
		mcf.direction[1] = RIGHT; // 右
		mcf.direction[2] = UP; // 上

		mcf.color[0] = ReturnColor(FRONT);
		mcf.color[1] = ReturnColor(RIGHT);
		mcf.color[2] = ReturnColor(UP);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 8

		// 右后
		mcf.position = glm::vec3(2.0f, 2.0f, -2.0f);
		mcf.direction[0] = BACK; // 后
		mcf.direction[1] = RIGHT; // 右
		mcf.direction[2] = UP; // 上

		mcf.color[0] = ReturnColor(BACK);
		mcf.color[1] = ReturnColor(RIGHT);
		mcf.color[2] = ReturnColor(UP);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 9

		mcf.count = 2;
		// 前中
		mcf.position = glm::vec3(0.0f, 2.0f, 2.0f);
		mcf.direction[0] = FRONT; // 前
		mcf.direction[1] = UP; // 上

		mcf.color[0] = ReturnColor(FRONT);
		mcf.color[1] = ReturnColor(UP);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 10

		// 右中
		mcf.position = glm::vec3(2.0f, 2.0f, 0.0f);
		mcf.direction[0] = RIGHT; // 右
		mcf.direction[1] = UP; // 上

		mcf.color[0] = ReturnColor(RIGHT);
		mcf.color[1] = ReturnColor(UP);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 11

		// 后中
		mcf.position = glm::vec3(0.0f, 2.0f, -2.0f);
		mcf.direction[0] = BACK; // 后
		mcf.direction[1] = UP; // 上

		mcf.color[0] = ReturnColor(BACK);
		mcf.color[1] = ReturnColor(UP);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 12

		// 左中
		mcf.position = glm::vec3(-2.0f, 2.0f, 0.0f);
		mcf.direction[0] = LEFT; // 左
		mcf.direction[1] = UP; // 上

		mcf.color[0] = ReturnColor(LEFT);
		mcf.color[1] = ReturnColor(UP);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 13
	}

	void MagicCube::CreateCentre()
	{
		MagicCubeStruct mcf;
		mcf.count = 2;

		// 左前
		mcf.position = glm::vec3(-2.0f, 0.0f, 2.0f);
		mcf.direction[0] = FRONT; // 前
		mcf.direction[1] = LEFT; // 左

		mcf.color[0] = ReturnColor(FRONT);
		mcf.color[1] = ReturnColor(LEFT);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 14

		// 右前
		mcf.position = glm::vec3(2.0f, 0.0f, 2.0f);
		mcf.direction[0] = FRONT; // 前
		mcf.direction[1] = RIGHT; // 右

		mcf.color[0] = ReturnColor(FRONT);
		mcf.color[1] = ReturnColor(RIGHT);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);

		CubePos.push_back(mcf); // 15

		// 右后
		mcf.position = glm::vec3(2.0f, 0.0f, -2.0f);
		mcf.direction[0] = BACK; // 后
		mcf.direction[1] = RIGHT; // 右

		mcf.color[0] = ReturnColor(BACK);
		mcf.color[1] = ReturnColor(RIGHT);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 16

		// 左后
		mcf.position = glm::vec3(-2.0f, 0.0f, -2.0f);
		mcf.direction[0] = BACK; // 后
		mcf.direction[1] = LEFT; // 左

		mcf.color[0] = ReturnColor(BACK);
		mcf.color[1] = ReturnColor(LEFT);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 17
	}

	void MagicCube::CreateBelow()
	{
		MagicCubeStruct mcf;
		mcf.count = 3;

		// 左前
		mcf.position = glm::vec3(-2.0f, -2.0f, 2.0f);
		mcf.direction[0] = FRONT; // 前
		mcf.direction[1] = LEFT; // 左
		mcf.direction[2] = DOWN; // 下

		mcf.color[0] = ReturnColor(FRONT);
		mcf.color[1] = ReturnColor(LEFT);
		mcf.color[2] = ReturnColor(DOWN);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 18

		// 左后
		mcf.position = glm::vec3(-2.0f, -2.0f, -2.0f);
		mcf.direction[0] = BACK; // 后
		mcf.direction[1] = LEFT; // 左
		mcf.direction[2] = DOWN; // 下

		mcf.color[0] = ReturnColor(BACK);
		mcf.color[1] = ReturnColor(LEFT);
		mcf.color[2] = ReturnColor(DOWN);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 19

		// 右前
		mcf.position = glm::vec3(2.0f, -2.0f, 2.0f);
		mcf.direction[0] = FRONT; // 前
		mcf.direction[1] = RIGHT; // 右
		mcf.direction[2] = DOWN; // 下

		mcf.color[0] = ReturnColor(FRONT);
		mcf.color[1] = ReturnColor(RIGHT);
		mcf.color[2] = ReturnColor(DOWN);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 20

		// 右后
		mcf.position = glm::vec3(2.0f, -2.0f, -2.0f);
		mcf.direction[0] = BACK; // 后
		mcf.direction[1] = RIGHT; // 右
		mcf.direction[2] = DOWN; // 下

		mcf.color[0] = ReturnColor(BACK);
		mcf.color[1] = ReturnColor(RIGHT);
		mcf.color[2] = ReturnColor(DOWN);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 21

		mcf.count = 2;

		// 前中
		mcf.position = glm::vec3(0.0f, -2.0f, 2.0f);
		mcf.direction[0] = FRONT; // 前
		mcf.direction[1] = DOWN; // 下

		mcf.color[0] = ReturnColor(FRONT);
		mcf.color[1] = ReturnColor(DOWN);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 22

		// 右中
		mcf.position = glm::vec3(2.0f, -2.0f, 0.0f);
		mcf.direction[0] = RIGHT; // 右
		mcf.direction[1] = DOWN; // 下

		mcf.color[0] = ReturnColor(RIGHT);
		mcf.color[1] = ReturnColor(DOWN);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 23

		// 后中
		mcf.position = glm::vec3(0.0f, -2.0f, -2.0f);
		mcf.direction[0] = BACK; // 后
		mcf.direction[1] = DOWN; // 下

		mcf.color[0] = ReturnColor(BACK);
		mcf.color[1] = ReturnColor(DOWN);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 24

		// 左中
		mcf.position = glm::vec3(-2.0f, -2.0f, 0.0f);
		mcf.direction[0] = LEFT; // 左
		mcf.direction[1] = DOWN; // 下

		mcf.color[0] = ReturnColor(LEFT);
		mcf.color[1] = ReturnColor(DOWN);

		ModifyCubeColor(mcf.direction, mcf, mcf.count);
		CubePos.push_back(mcf); // 25
	}

	void MagicCube::ModifyCubeColor(Direction* direction, MagicCubeStruct& mcf, int count)
	{
		// 获取立方体
		memmove(PCube, Cube, CubeSize);
		for (int i = 0; i < count; i++) {
			// 获取颜色
			glm::vec3 CubeColor = mcf.color[i];

			// 修改颜色
			int start = direction[i] * 6;
			int end = start + 6;
			for (int i = start; i < end; i++)
			{
				PCube[i * 6 + 3] = CubeColor.x;
				PCube[i * 6 + 4] = CubeColor.y;
				PCube[i * 6 + 5] = CubeColor.z;
			}
		}
		setupMesh(mcf);
	}

	void MagicCube::setupMesh(MagicCubeStruct& mcf)
	{
		// 创建 vao 
		glGenVertexArrays(1, &mcf.VAO);
		// 创建 vbo
		glGenBuffers(1, &mcf.VBO);

		// 绑定 vao
		glBindVertexArray(mcf.VAO);

		// 把顶点数据绑定到 vbo
		glBindBuffer(GL_ARRAY_BUFFER, mcf.VBO);
		glBufferData(GL_ARRAY_BUFFER, CubeSize, PCube, GL_STATIC_DRAW);

		// 设置属性指针
		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
		glEnableVertexAttribArray(0);
		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(sizeof(float) * 3));
		glEnableVertexAttribArray(1);

		// 解绑
		glBindVertexArray(0);
	}

	glm::vec3 MagicCube::ReturnColor(Direction direction)
	{
		switch (direction) {
		case FRONT:
			return color.front;
		case BACK:
			return color.back;
		case UP:
			return color.up;
		case DOWN:
			return color.down;
		case LEFT:
			return color.left;
		case RIGHT:
			return color.right;
		default:
			return glm::vec3(0.0f);
		}
	}

	float* MagicCube::ReturnFace(Direction direction)
	{
		switch (direction) {
		case FRONT:
			return CubeInd.front;
		case BACK:
			return CubeInd.back;
		case UP:
			return CubeInd.up;
		case DOWN:
			return CubeInd.down;
		case LEFT:
			return CubeInd.left;
		case RIGHT:
			return CubeInd.right;
		default:
			exit(EXIT_FAILURE);
		}
	}

	void MagicCube::ReRendering()
	{
		DeleteVertexData();
		for (auto& mcf : CubePos)
		{
			ModifyCubeColor(mcf.direction, mcf, mcf.count);
		}
	}

	void MagicCube::DeleteVertexData()
	{
		for (const auto& mcf : CubePos)
		{
			glDeleteVertexArrays(1, &mcf.VAO);
			glDeleteBuffers(1, &mcf.VBO);
		}
	}

	void MagicCube::IsRotating(bool rotating)
	{
		for (int i = 0; i < 9; i++)
		{
			CubePos[TheToRotate[i]].isRotating = rotating;
		}
		if (!rotating) TheToRotate = nullptr;
	}

	void MagicCube::MagicCubeInit()
	{
		PCube = new float[256];
		angle = 0;
		TheToRotate = nullptr;
		CubeSize = 216 * sizeof(float);
		speed = 0.005;

		Skeleton();
		CreateUpper();
		CreateCentre();
		CreateBelow();

		// ----------------------- 前 -----------------------
		// 左 中 右(第一排)
		CubeInd.front[0] = 6;
		CubeInd.front[1] = 10;
		CubeInd.front[2] = 8;

		// 左 右(第二排)
		CubeInd.front[3] = 14;
		CubeInd.front[4] = 15;

		// 左 中 右(第三排)
		CubeInd.front[5] = 18;
		CubeInd.front[6] = 22;
		CubeInd.front[7] = 20;

		// ----------------------- 后 -----------------------
		// 左 中 右(第一排)
		CubeInd.back[0] = 7;
		CubeInd.back[1] = 12;
		CubeInd.back[2] = 9;

		// 左 右(第二排)
		CubeInd.back[3] = 16;
		CubeInd.back[4] = 17;

		// 左 中 右(第三排)
		CubeInd.back[5] = 19;
		CubeInd.back[6] = 24;
		CubeInd.back[7] = 21;

		// ----------------------- 上 -----------------------
		// 左 中 右(第一排)
		CubeInd.up[0] = 7;
		CubeInd.up[1] = 12;
		CubeInd.up[2] = 9;

		// 左 右(第二排)
		CubeInd.up[3] = 13;
		CubeInd.up[4] = 11;

		// 左 中 右(第三排)
		CubeInd.up[5] = 6;
		CubeInd.up[6] = 10;
		CubeInd.up[7] = 8;

		// ----------------------- 下 -----------------------
		// 左 中 右(第一排)
		CubeInd.down[0] = 18;
		CubeInd.down[1] = 22;
		CubeInd.down[2] = 20;

		// 左 右(第二排)
		CubeInd.down[3] = 25;
		CubeInd.down[4] = 23;

		// 左 中 右(第三排)
		CubeInd.down[5] = 19;
		CubeInd.down[6] = 24;
		CubeInd.down[7] = 21;

		// ----------------------- 左 -----------------------
		// 左 中 右(第一排)
		CubeInd.left[0] = 7;
		CubeInd.left[1] = 13;
		CubeInd.left[2] = 6;

		// 左 右(第二排)
		CubeInd.left[3] = 17;
		CubeInd.left[4] = 14;

		// 左 中 右(第三排)
		CubeInd.left[5] = 19;
		CubeInd.left[6] = 25;
		CubeInd.left[7] = 18;

		// ----------------------- 右 -----------------------
		// 左 中 右(第一排)
		CubeInd.right[0] = 8;
		CubeInd.right[1] = 11;
		CubeInd.right[2] = 9;

		// 左 右(第二排)
		CubeInd.right[3] = 15;
		CubeInd.right[4] = 16;

		// 左 中 右(第三排)
		CubeInd.right[5] = 20;
		CubeInd.right[6] = 23;
		CubeInd.right[7] = 21;


		// ----------------------- 中 -----------------------
		CubeInd.front[8] = 1;
		CubeInd.back[8] = 0;

		CubeInd.left[8] = 4;
		CubeInd.right[8] = 5;

		CubeInd.up[8] = 2;
		CubeInd.down[8] = 3;
	}

	void MagicCube::rotate(Direction direction)
	{
		if (TheToRotate != nullptr) return;
		// 受影响的面有 上 左 下 右
		TheToRotate = ReturnFace(direction);
		IsRotating(true);
		// 前
		if (direction == FRONT) {
			// 旋转轴
			angleVec = glm::vec3(0.0f, 0.0f, 1.0f);

			glm::vec3 vec1 = CubePos[CubeInd.up[5]].color[2];
			glm::vec3 vec2 = CubePos[CubeInd.up[6]].color[1];
			glm::vec3 vec3 = CubePos[CubeInd.up[7]].color[2];

			// 上
			CubePos[CubeInd.up[5]].color[2] = CubePos[CubeInd.right[0]].color[1];
			CubePos[CubeInd.up[6]].color[1] = CubePos[CubeInd.right[3]].color[1];
			CubePos[CubeInd.up[7]].color[2] = CubePos[CubeInd.right[5]].color[1];

			// 右
			CubePos[CubeInd.right[0]].color[1] = CubePos[CubeInd.down[2]].color[2];
			CubePos[CubeInd.right[3]].color[1] = CubePos[CubeInd.down[1]].color[1];
			CubePos[CubeInd.right[5]].color[1] = CubePos[CubeInd.down[0]].color[2];

			// 下
			CubePos[CubeInd.down[0]].color[2] = CubePos[CubeInd.left[2]].color[1];
			CubePos[CubeInd.down[1]].color[1] = CubePos[CubeInd.left[4]].color[1];
			CubePos[CubeInd.down[2]].color[2] = CubePos[CubeInd.left[7]].color[1];

			// 左
			CubePos[CubeInd.left[2]].color[1] = vec3;
			CubePos[CubeInd.left[4]].color[1] = vec2;
			CubePos[CubeInd.left[7]].color[1] = vec1;

			// 前
			vec1 = CubePos[CubeInd.front[0]].color[0];
			vec2 = CubePos[CubeInd.front[1]].color[0];
			vec3 = CubePos[CubeInd.front[2]].color[0];

			CubePos[CubeInd.front[0]].color[0] = CubePos[CubeInd.front[2]].color[0];
			CubePos[CubeInd.front[1]].color[0] = CubePos[CubeInd.front[4]].color[0];
			CubePos[CubeInd.front[2]].color[0] = CubePos[CubeInd.front[7]].color[0];

			CubePos[CubeInd.front[2]].color[0] = CubePos[CubeInd.front[7]].color[0];
			CubePos[CubeInd.front[4]].color[0] = CubePos[CubeInd.front[6]].color[0];
			CubePos[CubeInd.front[7]].color[0] = CubePos[CubeInd.front[5]].color[0];

			CubePos[CubeInd.front[7]].color[0] = CubePos[CubeInd.front[5]].color[0];
			CubePos[CubeInd.front[5]].color[0] = CubePos[CubeInd.front[0]].color[0];
			CubePos[CubeInd.front[6]].color[0] = CubePos[CubeInd.front[3]].color[0];

			CubePos[CubeInd.front[0]].color[0] = vec3;
			CubePos[CubeInd.front[3]].color[0] = vec2;
			CubePos[CubeInd.front[5]].color[0] = vec1;
		}
		// 右
		else if (direction == RIGHT) {
			// 旋转轴
			angleVec = glm::vec3(1.0f, 0.0f, 0.0f);

			glm::vec3 vec1 = CubePos[CubeInd.right[0]].color[2];
			glm::vec3 vec2 = CubePos[CubeInd.right[1]].color[1];
			glm::vec3 vec3 = CubePos[CubeInd.right[2]].color[2];

			// 上
			CubePos[CubeInd.right[0]].color[2] = CubePos[CubeInd.back[2]].color[0];
			CubePos[CubeInd.right[1]].color[1] = CubePos[CubeInd.back[3]].color[0];
			CubePos[CubeInd.right[2]].color[2] = CubePos[CubeInd.back[7]].color[0];

			// 右
			CubePos[CubeInd.back[2]].color[0] = CubePos[CubeInd.down[7]].color[2];
			CubePos[CubeInd.back[3]].color[0] = CubePos[CubeInd.down[4]].color[1];
			CubePos[CubeInd.back[7]].color[0] = CubePos[CubeInd.down[2]].color[2];

			// 下
			CubePos[CubeInd.down[2]].color[2] = CubePos[CubeInd.front[2]].color[0];
			CubePos[CubeInd.down[4]].color[1] = CubePos[CubeInd.front[4]].color[0];
			CubePos[CubeInd.down[7]].color[2] = CubePos[CubeInd.front[7]].color[0];

			// 左
			CubePos[CubeInd.front[2]].color[0] = vec3;
			CubePos[CubeInd.front[4]].color[0] = vec2;
			CubePos[CubeInd.front[7]].color[0] = vec1;

			// 右
			vec1 = CubePos[CubeInd.right[0]].color[1];
			vec2 = CubePos[CubeInd.right[1]].color[0];
			vec3 = CubePos[CubeInd.right[2]].color[1];

			CubePos[CubeInd.right[0]].color[1] = CubePos[CubeInd.right[2]].color[1];
			CubePos[CubeInd.right[1]].color[0] = CubePos[CubeInd.right[4]].color[1];
			CubePos[CubeInd.right[2]].color[1] = CubePos[CubeInd.right[7]].color[1];

			CubePos[CubeInd.right[2]].color[1] = CubePos[CubeInd.right[7]].color[1];
			CubePos[CubeInd.right[4]].color[1] = CubePos[CubeInd.right[6]].color[0];
			CubePos[CubeInd.right[7]].color[1] = CubePos[CubeInd.right[5]].color[1];

			CubePos[CubeInd.right[7]].color[1] = CubePos[CubeInd.right[5]].color[1];
			CubePos[CubeInd.right[5]].color[1] = CubePos[CubeInd.right[0]].color[1];
			CubePos[CubeInd.right[6]].color[0] = CubePos[CubeInd.right[3]].color[1];

			CubePos[CubeInd.right[0]].color[1] = vec3;
			CubePos[CubeInd.right[3]].color[1] = vec2;
			CubePos[CubeInd.right[5]].color[1] = vec1;
		}
		// 后
		else if (direction == BACK) {
			// 旋转轴
			angleVec = glm::vec3(0.0f, 0.0f, 1.0f);

			glm::vec3 vec1 = CubePos[CubeInd.back[0]].color[2];
			glm::vec3 vec2 = CubePos[CubeInd.back[1]].color[1];
			glm::vec3 vec3 = CubePos[CubeInd.back[2]].color[2];

			CubePos[CubeInd.back[0]].color[2] = CubePos[CubeInd.right[2]].color[1];
			CubePos[CubeInd.back[1]].color[1] = CubePos[CubeInd.right[4]].color[1];
			CubePos[CubeInd.back[2]].color[2] = CubePos[CubeInd.right[7]].color[1];

			CubePos[CubeInd.right[2]].color[1] = CubePos[CubeInd.down[7]].color[2];
			CubePos[CubeInd.right[4]].color[1] = CubePos[CubeInd.down[6]].color[1];
			CubePos[CubeInd.right[7]].color[1] = CubePos[CubeInd.down[5]].color[2];

			CubePos[CubeInd.down[5]].color[2] = CubePos[CubeInd.left[0]].color[1];
			CubePos[CubeInd.down[6]].color[1] = CubePos[CubeInd.left[3]].color[1];
			CubePos[CubeInd.down[7]].color[2] = CubePos[CubeInd.left[5]].color[1];

			CubePos[CubeInd.left[0]].color[1] = vec3;
			CubePos[CubeInd.left[3]].color[1] = vec2;
			CubePos[CubeInd.left[5]].color[1] = vec1;

			vec1 = CubePos[CubeInd.back[0]].color[0];
			vec2 = CubePos[CubeInd.back[1]].color[0];
			vec3 = CubePos[CubeInd.back[2]].color[0];

			CubePos[CubeInd.back[0]].color[0] = CubePos[CubeInd.back[2]].color[0];
			CubePos[CubeInd.back[1]].color[0] = CubePos[CubeInd.back[3]].color[0];
			CubePos[CubeInd.back[2]].color[0] = CubePos[CubeInd.back[7]].color[0];

			CubePos[CubeInd.back[2]].color[0] = CubePos[CubeInd.back[7]].color[0];
			CubePos[CubeInd.back[3]].color[0] = CubePos[CubeInd.back[6]].color[0];
			CubePos[CubeInd.back[7]].color[0] = CubePos[CubeInd.back[5]].color[0];

			CubePos[CubeInd.back[7]].color[0] = CubePos[CubeInd.back[5]].color[0];
			CubePos[CubeInd.back[5]].color[0] = CubePos[CubeInd.back[0]].color[0];
			CubePos[CubeInd.back[6]].color[0] = CubePos[CubeInd.back[4]].color[0];

			CubePos[CubeInd.back[0]].color[0] = vec3;
			CubePos[CubeInd.back[4]].color[0] = vec2;
			CubePos[CubeInd.back[5]].color[0] = vec1;
		}
		// 左
		else if (direction == LEFT) {
			// 旋转轴
			angleVec = glm::vec3(1.0f, 0.0f, 0.0f);

			glm::vec3 vec1 = CubePos[CubeInd.left[0]].color[2];
			glm::vec3 vec2 = CubePos[CubeInd.left[1]].color[1];
			glm::vec3 vec3 = CubePos[CubeInd.left[2]].color[2];

			CubePos[CubeInd.left[0]].color[2] = CubePos[CubeInd.back[5]].color[0];
			CubePos[CubeInd.left[1]].color[1] = CubePos[CubeInd.back[4]].color[0];
			CubePos[CubeInd.left[2]].color[2] = CubePos[CubeInd.back[0]].color[0];

			CubePos[CubeInd.back[0]].color[0] = CubePos[CubeInd.down[5]].color[2];
			CubePos[CubeInd.back[4]].color[0] = CubePos[CubeInd.down[3]].color[1];
			CubePos[CubeInd.back[5]].color[0] = CubePos[CubeInd.down[0]].color[2];

			CubePos[CubeInd.down[0]].color[2] = CubePos[CubeInd.front[0]].color[0];
			CubePos[CubeInd.down[3]].color[1] = CubePos[CubeInd.front[3]].color[0];
			CubePos[CubeInd.down[5]].color[2] = CubePos[CubeInd.front[5]].color[0];

			CubePos[CubeInd.front[0]].color[0] = vec1;
			CubePos[CubeInd.front[3]].color[0] = vec2;
			CubePos[CubeInd.front[5]].color[0] = vec3;


			vec1 = CubePos[CubeInd.left[0]].color[1];
			vec2 = CubePos[CubeInd.left[1]].color[0];
			vec3 = CubePos[CubeInd.left[2]].color[1];

			CubePos[CubeInd.left[0]].color[1] = CubePos[CubeInd.left[5]].color[1];
			CubePos[CubeInd.left[1]].color[0] = CubePos[CubeInd.left[3]].color[1];
			CubePos[CubeInd.left[2]].color[1] = CubePos[CubeInd.left[0]].color[1];

			CubePos[CubeInd.left[0]].color[1] = CubePos[CubeInd.left[5]].color[1];
			CubePos[CubeInd.left[3]].color[1] = CubePos[CubeInd.left[6]].color[0];
			CubePos[CubeInd.left[5]].color[1] = CubePos[CubeInd.left[7]].color[1];

			CubePos[CubeInd.left[7]].color[1] = CubePos[CubeInd.left[5]].color[1];
			CubePos[CubeInd.left[5]].color[1] = CubePos[CubeInd.left[7]].color[1];
			CubePos[CubeInd.left[6]].color[0] = CubePos[CubeInd.left[4]].color[1];

			CubePos[CubeInd.left[2]].color[1] = vec1;
			CubePos[CubeInd.left[4]].color[1] = vec2;
			CubePos[CubeInd.left[7]].color[1] = vec3;
		}
	}

	void MagicCube::Draw(Shader& shader, double currentTime)
	{
		if (TheToRotate) {
			deltaTime = currentTime - lastFrame;
			if (deltaTime > speed) {
				angle += rotDir;
				lastFrame = currentTime;
			}
		}
		if (angle > 90|| angle < -90) {
			IsRotating(false);
			angle = 0;
			// 重新渲染
			ReRendering();
		}
		for (int i = 0; i < 26; i++)
		{
			glBindVertexArray(CubePos[i].VAO);
			glm::mat4 mMat = glm::scale(glm::mat4(1.0f), glm::vec3(0.1f));
			if (CubePos[i].isRotating) {
				mMat = glm::rotate(mMat, glm::radians(angle), angleVec);
			}
			// 模型矩阵
			mMat = glm::translate(mMat, CubePos[i].position);
			// 模型矩阵
			shader.setPUFMat4("m_matrix", glm::value_ptr(mMat));
			// 绘制模型
			glDrawArrays(GL_TRIANGLES, 0, 36);
		}
	}

	void MagicCube::DeleteCube()
	{
		delete[]PCube;
		DeleteVertexData();
	}
}

main.cpp

#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include <ImgUI/imgui.h>
#include <ImgUI/imgui_impl_glfw.h>
#include <ImgUI/imgui_impl_opengl3.h>

#include <iostream>
#include <assert.h>
#include <cmath>
#include <map>
#include <ctime>
#include <stack>
#include <vector>
#include <Class/Shader/Shader.h>
#include <Class/Camera/Camera.h>
#include "MagicCube.h"

// 创建着色器类
Shader shader;
// 创建魔法类
CubeN::MagicCube myMagicCube;

// 位置、目标、上向量
Camera myCamera(glm::vec3(0.0f, 0.0f, 3.0f),glm::vec3(0.0f, 0.0f, -1.0f),glm::vec3(0.0f, 1.0f, 0.0f));

float aspect;// 屏幕宽度比
bool isCtrlPressed = true;

GLuint
vLoad,// 视图矩阵
mLoad,// 模型矩阵
pLoad;// 透视矩阵

glm::mat4
mMat,	// 模型矩阵
pMat,  // 透视矩阵
vMat;  // 视图矩阵

// 初始自定义代码
void init(GLFWwindow* window);
// 渲染自定义代码
void display(GLFWwindow* window, double currentTime);
// 销毁
void destroy(GLFWwindow* window);
// 窗口改变事件
void window_reshape_callback(GLFWwindow* window, int width, int height);
// 注册了鼠标移动事件
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
// 注册了鼠标移动事件
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
// 监听按键,鼠标事件
void ProcessInput(GLFWwindow* window);
// 键盘按下和抬起事件的回调函数
void onKey(GLFWwindow* window, int key, int scancode, int action, int mods);

int main() {
	// 初始化 glfw
	if (!glfwInit()) { exit(EXIT_FAILURE); }
	// 设置 opengl 版本 (4.6 核心)
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	// 创建 window 窗口
	GLFWwindow* window = glfwCreateWindow(600, 600, "LearOpenGL 3.5", NULL, NULL);
	// 链接 opengl 上下文
	glfwMakeContextCurrent(window);

	// 初始化 glad 获取 opengl api 函数 地址
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { exit(EXIT_FAILURE); }
	// 开启垂直
	glfwSwapInterval(1);

	// 注册窗口改变事件
	glfwSetWindowSizeCallback(window, window_reshape_callback);
	// 隐藏光标
	// glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
	// 注册了鼠标移动事件
	glfwSetCursorPosCallback(window, mouse_callback);
	// 注册了鼠标滚动事件
	glfwSetScrollCallback(window, scroll_callback);
	// 设置键盘事件的回调函数
	glfwSetKeyCallback(window, onKey);

	// 创建imgui上下文
	ImGui::CreateContext();
	ImGuiIO& io = ImGui::GetIO();
	// 设置样式
	ImGui::StyleColorsDark();
	// 设置平台和渲染器
	ImGui_ImplGlfw_InitForOpenGL(window, true);
	ImGui_ImplOpenGL3_Init("#version 460");

	// 初始化着色器类
	shader.init("vertShader.glsl", "fragShader.glsl");

	// 初始化魔方
	myMagicCube.MagicCubeInit();

	// 初始自定义代码
	init(window);

	myCamera.fov = 45.0f;

	// 循环渲染
	while (!glfwWindowShouldClose(window))
	{
		// 监听键盘
		ProcessInput(window);

		ImGui_ImplOpenGL3_NewFrame();
		ImGui_ImplGlfw_NewFrame();
		ImGui::NewFrame();

		ImGui::Begin("imgui");
		ImGui::Text("%.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
		ImGui::End();

		// 渲染自定义代码
		display(window, glfwGetTime());

		// 渲染 gui
		ImGui::Render();
		ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

		// 交换缓存和轮询IO事件
		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	// 释放内存
	destroy(window);

	// 成功退出程序
	exit(EXIT_SUCCESS);
}

void init(GLFWwindow* window) {
	// 开启着色器程序
	shader.useProgram();
	mLoad = shader.getULocation("m_matrix");
	vLoad = shader.getULocation("v_matrix");
	pLoad = shader.getULocation("p_matrix");
	// 获取窗口的宽高
	int width, height;
	glfwGetFramebufferSize(window, &width, &height);// 获取屏幕宽,高
	// 计算宽高比
	aspect = (float)width / (float)height;//获取屏幕比例
}

void display(GLFWwindow* window, double currentTime) {
	// 填充颜色缓冲区
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	// 清除深度缓冲区
	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
	// 创建透视矩阵 / 设置投影矩阵
	pMat = glm::perspective(glm::radians(myCamera.fov), aspect, 0.1f, 1000.0f);
	// 将视图矩阵压入栈
	vMat = myCamera.getLookAt();

	// 开启着色器程序
	shader.useProgram();
	// 视图矩阵
	shader.setPUFMat4(vLoad, glm::value_ptr(vMat));
	// 透视矩阵
	shader.setPUFMat4(pLoad, glm::value_ptr(pMat));

	// 开启深度测试
	glEnable(GL_DEPTH_TEST);
	// 设置深度测试的比较方式
	glDepthFunc(GL_LESS);
	// 开启背面剔除
	glEnable(GL_CULL_FACE);
	// 设置立方体顶点的缠绕顺序为逆时针方向
	glFrontFace(GL_CW);

	myMagicCube.Draw(shader, currentTime);
}

void destroy(GLFWwindow* window) {
	// 销毁 vao vbo
	myMagicCube.DeleteCube();
	// 销毁着色器
	shader.deleteProgram();
	// 销毁窗口
	glfwDestroyWindow(window);
	glfwTerminate();
}

void window_reshape_callback(GLFWwindow* window, int width, int height)
{
	// 设置和帧缓冲区相关的屏幕区域
	glViewport(0, 0, width, height);
	aspect = (float)width / (float)height;//获取屏幕比例
}

// 监听按键,鼠标事件
void ProcessInput(GLFWwindow* window)
{
	// 检查用户是否按下了返回键(Esc)
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
	{
		// 下一次while循环的条件检测将会失败,程序将会关闭
		glfwSetWindowShouldClose(window, true);
	}

	static float deltaTime = 0.0f;
	static float lastFrame = 0.0f;

	float currentFrame = glfwGetTime();
	deltaTime = currentFrame - lastFrame; //  当前帧与上一帧的时间差
	lastFrame = currentFrame;             //  上一帧的时间

	if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
		myCamera.ProcessKeyboard(FORWARD, deltaTime);
	if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
		myCamera.ProcessKeyboard(BACKWARD, deltaTime);
	if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
		myCamera.ProcessKeyboard(LEFT, deltaTime);
	if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
		myCamera.ProcessKeyboard(RIGHT, deltaTime);
}

// 回调函数,鼠标进入程序窗口,获取焦点
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{
	static bool firstMouse = true;
	static float lastX = 0.0f;
	static float lastY = 0.0f;
	static float xoffset = 0.0f;
	static float yoffset = 0.0f;

	if (firstMouse)
	{
		lastX = xpos;
		lastY = ypos;
		firstMouse = false;
	}

	// 获取 x 坐标
	xoffset = xpos - lastX;
	// 注意这里是相反的,因为y坐标是从底部往顶部依次增大的
	yoffset = lastY - ypos;

	// 更新鼠标坐标
	lastX = xpos;
	lastY = ypos;
	if (!isCtrlPressed)
		myCamera.mouse_callback(xoffset, yoffset);
}

// 监听鼠标滚动
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
	myCamera.scroll_callback(xoffset, yoffset);
}

// 键盘按下和抬起事件的回调函数
void onKey(GLFWwindow* window, int key, int scancode, int action, int mods) {
	if (action == GLFW_PRESS) {
		// 键盘按下的处理逻辑
		if (key == GLFW_KEY_LEFT_CONTROL && !isCtrlPressed) {
			isCtrlPressed = true;
			glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
		}
		else if (key == GLFW_KEY_LEFT_CONTROL && isCtrlPressed) {
			isCtrlPressed = false;
			glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
		}

		if (key == GLFW_KEY_I) {
			myMagicCube.rotate(CubeN::FRONT);
		}
		else if (key == GLFW_KEY_L) {
			myMagicCube.rotate(CubeN::RIGHT);
		}
		else if (key == GLFW_KEY_M) {
			myMagicCube.rotate(CubeN::BACK);
		}
		else if (key == GLFW_KEY_J) {
			myMagicCube.rotate(CubeN::LEFT);
		}
	}
	else if (action == GLFW_RELEASE) {
		// 键盘抬起的处理逻辑
	}
}
  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值