设计自己的软渲染器-附代码相关

本系列github代码库地址

https://github.com/YIWANFENG/MiniRenderer

本系列可运行项目下载地址

http://download.csdn.net/download/hffhjh111/10210438

一些的参考资料

大牛Blog:

https://www.davrous.com/2013/06/13/tutorial-series-learning-how-to-write-a-3d-soft-engine-from-scratch-in-c-typescript-or-javascript/

浅谈 GPU图形固定渲染管线

http://www.cnblogs.com/QG-whz/p/4644213.html?utm_source=tuicool


加载从Blender导出的Json格式模型

从Blemder导出参考:https://www.davrous.com/2013/06/17/tutorial-part-3-learning-how-to-write-a-3d-soft-engine-in-c-ts-or-js-loading-meshes-exported-from-blender/

将相应Jsoncpp的C++头文件与源文件加入工程后稍加调整,或者你自己配置Json库。


添加下列读取函数
int ReadJsonFromFile(const char* filename, Mesh &mesh)
{

	Json::Reader reader;// 解析json用Json::Reader   
	Json::Value root; // Json::Value是一种很重要的类型,可以代表任意类型。如int, string, object, array         

	std::ifstream is;
	is.open(filename, std::ios::binary);
	if (reader.parse(is, root, 0))
	{
		std::string mesh_name;
		//Mesh mesh;
		int mesh_count = 0;
		if (!root["meshes"].isNull())  // 访问节点,Access an object value by name, create a null member if it does not exist.  
			mesh_count = root["meshes"].size();
		for (int i = 0; i < mesh_count; i++) {

			int vertices_count = root["meshes"][i]["vertices"].size();
			int faces_count = root["meshes"][i]["indices"].size();
			int uvCount = root["meshes"][i]["uvCount"].asInt();

			int ver_span = 1;	//每个顶底跨距
			int face_span = 3;	//每个面跨距
			switch (uvCount)
			{
			case 0:
				ver_span = 6;
				break;
			case 1:
				ver_span = 8;
				break;
			case 2:
				ver_span = 10;
				break;
			}

			mesh.face_count = faces_count / face_span;
			mesh.vertex_count = vertices_count / ver_span;
			mesh.vertices = new Vertex[mesh.vertex_count];
			mesh.faces = new Face[mesh.face_count];
			//解析顶点
			Json::Value vertices = root["meshes"][i]["vertices"];
			for (int j = 0; j < mesh.vertex_count; j++) {
				// 加载Blender导出的顶点
				mesh.vertices[j].WorldCoordinates.x = vertices[j*ver_span].asDouble();
				mesh.vertices[j].WorldCoordinates.y = vertices[j*ver_span + 1].asDouble();
				mesh.vertices[j].WorldCoordinates.z = vertices[j*ver_span + 2].asDouble();
				mesh.vertices[j].WorldCoordinates.w = 1.0f;
				// 加载Blender导出的顶点法线
				mesh.vertices[j].Normal.x = vertices[j*ver_span + 3].asDouble();
				mesh.vertices[j].Normal.y = vertices[j*ver_span + 4].asDouble();
				mesh.vertices[j].Normal.z = vertices[j*ver_span + 5].asDouble();
				mesh.vertices[j].Normal.w = 1.0f;
			}
			//解析面
			Json::Value faces = root["meshes"][i]["indices"];
			for (int j = 0; j < mesh.face_count; j++) {
				mesh.faces[j].v1 = faces[j*face_span].asInt();
				mesh.faces[j].v2 = faces[j*face_span + 1].asInt();
				mesh.faces[j].v3 = faces[j*face_span + 2].asInt();
			}
			//解析设置的mesh位置
			Json::Value js_position = root["meshes"][i]["position"];
			int k = 0;
			mesh.Position.x = js_position[k].asDouble();
			mesh.Position.y = js_position[1].asDouble();
			mesh.Position.z = js_position[2].asDouble();

		}
	}
	is.close();

	return 0;
}

加载纹理图片

使用opencv3
void Texture::Load(const char *filename) {
	buf = cv::imread(filename);
	width = buf.size().width;
	height = buf.size().height;
	//cv::imshow("buf", buf);
}

Color Texture::Map(float tu, float tv) {
	Color re;
	re.Set(0x00000000, 1.0f);			//默认为黑
	if (buf.empty()) return re;
	int u = (int)(tu*width) % width;	//%为防止复用
	int v = (int)(tv*height) % height;
	if (u<0 || v<0)
		cout << tu << ' ' << tv << endl;
	u = u >= 0 ? u : -u;
	v = v >= 0 ? v : -v;

	cv::Vec3b tex_w = buf.at<cv::Vec3b>(v, u);	//U是X,V是Y
	re.argb[3] = 0x00;
	re.argb[0] = tex_w[0];	//B
	re.argb[1] = tex_w[1];	//G
	re.argb[2] = tex_w[2];	//R
	return re;
}

PS:回到家里,真的是一点都不想再整理,所以就使用了原始的笔记。
考研结果如何,充满了纠结。
处在这种时间,真是尴尬。





猜你喜欢

转载自blog.csdn.net/hffhjh111/article/details/79086868