opengl学习笔迹——读取ply文件并绘制模型

首先要做的是读取ply文件,我们打开notepad++查看ply文件可以看到如上格式。有用的是第四行的37702代表顶点数量,11行的75404,代表面数。所以我们设置了如下的读取代码(非常地暴力)

        char ch[50];
	ifstream in("lizhenxiout-repaired.ply");
	bool www = in.fail();
	for (int i = 0; i < 3; i++)
		in.getline(ch, 50);
	in >> ch;
	in >> ch;
	in >> ch;
	v_num = atoi(ch);
	for (int i = 0; i < 7; i++)
		in.getline(ch, 50);
	in >> ch;
	in >> ch;
	in >> ch;
	index_num = atoi(ch);
	for (int i = 0; i < 2; i++)
		in.getline(ch, 50);
	in.getline(ch, 50);

接着我们将数据读入顶点数组v_arr,面索引index_arr,并根据面索引数组初始化三角形线框绘制数组index_line_arr。

        v_arr = new Vertex[v_num];
	index_arr = new Index[index_num];
	index_line_arr = new Index_Line[3 * index_num];
	for (int i = 0; i < v_num; i++)
	{
		in >> v_arr[i].x >> v_arr[i].y >> v_arr[i].z >> v_arr[i].nx >> v_arr[i].ny >> v_arr[i].nz;
		T_x += v_arr[i].x;
		T_y += v_arr[i].y;
		T_z += v_arr[i].z;
	}
	T_x /= v_num;//模型重心的三个参数
	T_y /= v_num;
	T_z /= v_num;
	for (int i = 0; i < index_num; i++)
	{
		in >> index_arr[i].a >> index_arr[i].a >> index_arr[i].b >> index_arr[i].c;
		index_line_arr[3 * i].a = index_line_arr[3 * i + 2].b = index_arr[i].a;
		index_line_arr[3 * i + 1].a = index_line_arr[3 * i].b = index_arr[i].b;
		index_line_arr[3 * i + 2].a = index_line_arr[3 * i + 1].b = index_arr[i].c;
	}

我们使用顶点缓冲的方法绘制我们的数据(将数据发送入GPU,提高绘制速率)

注意,如果你和我一样是用glut库写opengl,会找不到VBO的相关支持,需要配置glew库。

        //使用VBO加载数据
	glGenBuffers(1, &VBO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, v_num*sizeof(Vertex), v_arr, GL_STATIC_DRAW);
	//建立EBO索引
	glGenBuffers(2, EBO);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[0]);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_num*sizeof(Index), index_arr, GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[1]);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * index_num*sizeof(Index_Line), index_line_arr, GL_STATIC_DRAW);
	//设置顶点和法线指针
	glVertexPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), BUFFER_OFFSET(0));
	glNormalPointer(GL_FLOAT, 6 * sizeof(GLfloat), BUFFER_OFFSET(3 * sizeof(GLfloat)));
        //开启对应功能
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_NORMAL_ARRAY);

完成这些准备工作之后,我们就可以简单地使用glBindBuffer和glDrawElements绘制我们的图像了。

下面是一些数据定义的补充

#define BUFFER_OFFSET(bytes) ((GLubyte*)NULL+bytes)//偏移量的宏定义
struct Vertex
{
	GLfloat  x, y, z, nx, ny, nz;
}ver;
struct Index
{
	GLuint a, b, c;
};
struct Index_Line
{
	GLuint a, b;
};
Vertex* v_arr;//点集
Index* index_arr;//面索引
Index_Line* index_line_arr;//线索引
int v_num, index_num;
GLuint VBO;//只有一个的孤独VBO
GLuint EBO[2];//索引缓冲指针

下一讲我们将设置一些用户操作,并附上源代码。

猜你喜欢

转载自blog.csdn.net/qq_38782152/article/details/80255938
今日推荐