欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-11 08:10:38
...

本系列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:回到家里,真的是一点都不想再整理,所以就使用了原始的笔记。
考研结果如何,充满了纠结。
处在这种时间,真是尴尬。





相关标签: renderer