2012年10月7日 星期日

Read mesh file and display wireframe in OpenGL

since: 2012/10/07
update: 2012/10/07

reference:
1. Openmesh 读入off文件并用opengl显示

A. 說明:
     1. 主要參考上方的資料, 並作適度的簡化與調整.
     2. 調整為: 不加入光源效果, 只顯示線框圖(wireframe), 採用正交投影.

----------------------------------------------------------------------------------------

B. 前置作業:
     1. 安裝 GLUT  與 GLEW: 參考這篇CD.

     2. 取得 OpenMesh Libraries: 參考這篇, 在此會使用 C. 方式二所產生的
         Libraries, 即:        
          OpenMesh Libraries 目錄位置
          C:\Lanli\projects\OpenMesh-2.2\lib
          內含: libOpenMeshCore.lib
                    libOpenMeshCored.lib
                    libOpenMeshTools.lib
                    libOpenMeshToolsd.lib
                    (有 d 的為 debug 版本)

          OpenMesh Headers 目錄位置
          C:\Lanli\projects\OpenMesh-2.2\src

----------------------------------------------------------------------------------------

C. 新增專案:
     1. Visual Studio 2010 > 檔案 > 新增 > 專案

     2. Visual C++ > Win32 > Win32 主控台應用程式
         名稱: OpenMesh_Hello
         位置: C:\Lanli\projects
         為方案建立目錄: 取消勾選
          > 確定

     3. 下一步
          > 空專案: 勾選
          > 完成

     4. 新增主程式檔案
         點選 "OpenMesh_Hello" 專案 > 滑鼠右鍵 > 加入 > 新增項目:
         Visual C++ > C++ 檔 (.cpp)
         名稱: main.cpp
          > 新增

----------------------------------------------------------------------------------------

D. 為專案加入 OpenMesh 的 Libraries 與 Header Files:
     1. OpenMesh_Hello 專案的根目錄, 新增 meshlib 資料夾.

     2. B. 前置作業2. 的:
         a. OpenMesh Libraries 目錄下所有檔案 copy 到 lib 目錄下.
              即 lib 目錄下的檔案為:
              ----------------------------
              libOpenMeshCore.lib
              libOpenMeshCored.lib
              libOpenMeshTools.lib
              libOpenMeshToolsd.lib
              (有 d 的為 debug 版本)

         b. OpenMesh Headers 目錄下所有檔案 copy 到 mesh 目錄下.
             即 mesh 目錄下的檔案為:
             ----------------------------
             OpenMesh 資料夾
             Unittests 資料夾

----------------------------------------------------------------------------------------

E. 專案屬性設定:
     點選 "OpenMesh_Hello" 專案 > 滑鼠右鍵
     > 屬性
     > 組態屬性

     1. > 一般: (Debug Release)
         字元集: 使用 Unicode 字元集
         Common Language Runtime 支援: Common Language Runtime 支援 (/clr)
          > 確定

     2. > VC++ 目錄: (Debug Release)
            Include 目錄: mesh
            程式庫目錄: lib
            > 確定

            備註: 也可以使用以下的方式
            Include 目錄: C:\Lanli\projects\OpenMesh-2.2\include
            程式庫目錄: C:\Lanli\projects\OpenMesh-2.2\lib


     3. > C/C++ 前置處理器: (Debug Release)
             前置處理器定義: _USE_MATH_DEFINES

     4. > 連結器 > 輸入 > 其他相依性:
             Debug: (檔案有 d 的版本)
             -----------------------------------
             libOpenMeshCored.lib
             libOpenMeshToolsd.lib
             glut32.lib
             glew32.lib
             glew32s.lib
            > 確定

             Release:
             -----------------------------------
             libOpenMeshCore.lib
             libOpenMeshTools.lib
             glut32.lib
             glew32.lib
             glew32s.lib
            > 確定

----------------------------------------------------------------------------------------

F.下載模型檔:
     網址: models
     檔名: teapot.off
     下載後, copy 到 OpenMesh_Hello 專案的根目錄下.
     用 MeshLab 看一下模型檔:

----------------------------------------------------------------------------------------

G. 撰寫程式碼:
     開啟 main.cpp 檔案, 修改如下:
#include <iostream>
#include <vector>
#include <math.h>
#include <stdio.h>
#include <string.h>


// -------------------- OpenMesh
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>


// -------------------- OpenGL
#include <GL/glut.h>

// -------------------- typedef
typedef OpenMesh::PolyMesh_ArrayKernelT<> MyMesh;
MyMesh mesh;

// -------------------- global variables
float gWidth; // width of the render window
float gHeight; // height of the render window

// -------------------- lights
//GLfloat gLightDiffuse[] = {0.0, 0.0, 1.0, 1.0}; // light diffuse
//GLfloat gLightPosition[] = {0.0, 0.0, 1.0, 1.0}; // light position

// -------------------- function declare
void display();
void drawFace();
void drawLine();
void glInit();
void idle();
void render();
void reshape(GLint width, GLint height);

// ----------------------------------------------------------------------------

int main(int argc, char* argv[])
{
    // read mesh object file
    if (!OpenMesh::IO::read_mesh(mesh, "teapot.off"))
    {
        std::cerr << "read error\n";
        exit(1);
    }

    // initialize the render window
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(640, 640);
    glutCreateWindow("Hello, OpenMesh!");

    // initialize the render environment
    glInit();

    // callback function
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);

    glutMainLoop();

    return 0;
}

// initialize the render environment
void glInit()
{
    // set color
    glClearColor(0.8, 0.8, 0.8, 1.0); // 背景: 灰色
    glColor3f(0.0, 0.0, 0.0); // 筆畫顏色: 黑

    // 光源設定
    /*
    glLightfv(GL_LIGHT0, GL_DIFFUSE, gLightDiffuse);
    glLightfv(GL_LIGHT0, GL_POSITION, gLightPosition);
    glEnable(GL_LIGHT0);
    */


    glEnable(GL_DEPTH_TEST); // 深度測試
    glEnable(GL_AUTO_NORMAL);
    glEnable(GL_NORMALIZE);
    glShadeModel(GL_SMOOTH);

    // set OpenGL projection mode
    glMatrixMode(GL_PROJECTION);
   
    // 透視投影
    /*
    gluPerspective(
        45.0, // field of view in degree
        1.0, // aspect ratio
        1.0, // Z near
        10.0); // Z far
    */
    // 正交投影

    glOrtho(-5, 5, -5, 5, 5, 15);

    // set OpenGL nodel view mode
    glMatrixMode(GL_MODELVIEW);

    // 眼睛(攝影機) 位置與觀看方向
    gluLookAt(
        0.0, 0.0, 10.0, // eye is at (0,0,10.0)
        0.0, 0.0, 0.0, // eye look at (0,0,0)
        0.0, 1.0, 0.0); // up is in positive Y direction
}

void display()
{
    glViewport(0, 0, gWidth, gHeight);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    render();

    glutSwapBuffers();
}

void render()
{
    //glEnable(GL_LIGHTING);

    //drawFace();

    drawLine();

    //glDisable(GL_LIGHTING);
}

void reshape(GLint width, GLint height)
{
    // record the width and height of the current render window
    gWidth = width;
    gHeight = height;
}

void idle()
{
    // refresh the screen
    glutPostRedisplay();
}

void drawFace()
{
    glPointSize(1.0f);
    glColor3f(1.0, 1.0, 0.0);

    for (MyMesh::FaceIter f_it = mesh.faces_begin(); f_it != mesh.faces_end(); ++f_it)
    {
        glBegin(GL_TRIANGLES);
        for(MyMesh::FaceVertexIter fv_it = mesh.fv_iter(f_it); fv_it; ++fv_it)
        {
            glVertex3fv(mesh.point(fv_it).data());
        }
        glEnd();
    }
}

void drawLine()
{
    glPointSize(1.0f);
    glColor3f(0.0, 0.0, 0.0);
    for (MyMesh::FaceIter f_it = mesh.faces_begin(); f_it != mesh.faces_end(); ++f_it)
    {
        glBegin(GL_LINE_LOOP);
        for(MyMesh::FaceVertexIter fv_it = mesh.fv_iter(f_it); fv_it; ++fv_it)
        {
            glVertex3fv(mesh.point(fv_it).data());
        }
        glEnd();
    }
}


----------------------------------------------------------------------------------------

H. 建置並啟動:
     

沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。