您的位置:首页 > 编程语言

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

2018-01-17 17:13 375 查看

本系列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:回到家里,真的是一点都不想再整理,所以就使用了原始的笔记。

考研结果如何,充满了纠结。

处在这种时间,真是尴尬。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: