1. 程式人生 > >opengl學習筆跡——讀取ply檔案並繪製模型

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];//索引緩衝指標

下一講我們將設定一些使用者操作,並附上原始碼。