首先要做的是读取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];//索引缓冲指针
下一讲我们将设置一些用户操作,并附上源代码。