opengl學習筆跡——讀取ply檔案並繪製模型
阿新 • • 發佈:2018-11-24
首先要做的是讀取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];//索引緩衝指標
下一講我們將設定一些使用者操作,並附上原始碼。