欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

obj 文件读取 openGL 显示3D图

程序员文章站 2022-03-26 18:25:46
...

// GenericModel.cpp : Defines the entry point for the console application.

//

 

#include "stdafx.h"

 

#include <glut.h> 

 

#include "objLoader/AccessObj.h"

 

/*

cube.obj 文件内容:

# cube

v  1.0000  1.0000  1.0000

v -1.0000  1.0000  1.0000

v -1.0000 -1.0000  1.0000

v  1.0000 -1.0000  1.0000

v  1.0000  1.0000 -1.0000

v -1.0000  1.0000 -1.0000

v -1.0000 -1.0000 -1.0000

v  1.0000 -1.0000 -1.0000

f  1  2  3  4

f  1  5  6  2

f  2  6  7  3

f  3  7  8  4

f  4  8  5  1

f  5  8  7  6

*/

 

 

/// 最简单的显示一个cube

void cubeDisplay1()

{

    /// 导入obj文件

    CAccessObj OBJ;

    OBJ.LoadOBJ("cube.obj"); 

 

    /// 初始化

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 

    /// 为了将图像显示在窗口,看x,y,z轴上的最大值最小值

    float x1 = OBJ.m_vMax.x;

    float y1 = OBJ.m_vMax.y;

    float z1 = OBJ.m_vMax.z;

    float x2 = OBJ.m_vMin.x;

    float y2 = OBJ.m_vMin.y;

    float z2 = OBJ.m_vMin.z;

    float ratio[3] = {x1-x2, y1-y2, z1-z2};

 

    

    /// 依次画每一个面,每个面就是一个三角形

    for ( int m=0; m<OBJ.m_pModel->nTriangles; m++ )

    {

        /// 开始绘制

        glBegin(GL_TRIANGLES);  

 

        /// 顶点——v

        unsigned int *pVertIdx = ( OBJ.m_pModel->pTriangles )[m].VertIdx;

 

        /// 依次画三角形的三个点

        for ( int i=0; i<3; i++ )

        {

            /// 设置颜色

            glColor3f(m&i&0x04, m&i&0x02, m&i&0x01);

        

            /// 这里注意,为了显示要除以一个数

            float x = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].x / ratio[0] ;

            float y = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].y / ratio[1] ;

            float z = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].z / ratio[2] ;

 

            glVertex3f( x, y, z ); 

        } 

 

        glEnd();

    }

 

    /// 旋转

    float degree = 45;

    glRotatef(degree, 1, 1, 1 );

 

 

    glFlush();

}

 

/// 显示一个cube, 加了纹理

void cubeDisplay2()

{

 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 

    /// 新建纹理

    static float T0[64][64][4];

    static GLuint Tname0;

    int i, j, c;

    

    // 纹理,渐变绿色,*64

    for (i = 0; i < 64; i++) {

        for (j = 0; j < 64; j++) {

            T0[i][j][0] = (float) 0;

            T0[i][j][1] = (float) i * 5 + j * 5;

            T0[i][j][2] = (float) 255;

            T0[i][j][3] = (float) 255;

        }

    }

 

    /// 导入obj文件

    CAccessObj OBJ;

    OBJ.LoadOBJ("cube.obj"); 

 

 

    /// 为了将图像显示在窗口,看x,y,z轴上的最大值最小值

    float x1 = OBJ.m_vMax.x;

    float y1 = OBJ.m_vMax.y;

    float z1 = OBJ.m_vMax.z;

    float x2 = OBJ.m_vMin.x;

    float y2 = OBJ.m_vMin.y;

    float z2 = OBJ.m_vMin.z;

    float ratio[3] = {x1-x2, y1-y2, z1-z2};

 

 

    /// 依次画每一个面,每个面就是一个三角形

    for ( int m=0; m<OBJ.m_pModel->nTriangles; m++ )

    {

        glBegin(GL_TRIANGLES);  

 

        /// 顶点——v

        unsigned int *pVertIdx = ( OBJ.m_pModel->pTriangles )[m].VertIdx;

        /// 纹理坐标 texture point ——vt

        unsigned int *pTexIdx = ( OBJ.m_pModel->pTriangles )[m].TexIdx;//< 在texture中找对应的点

        /// 曲面法线——vn

        unsigned int *pNormIdx = ( OBJ.m_pModel->pTriangles )[m].NormIdx;            

 

        /// 依次画三角形的三个点

        for ( int i=0; i<3; i++ )

        {

            /// 这里注意,为了显示要除以一个数

            float x = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].x / ratio[0] ;

            float y = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].y / ratio[1] ;

            float z = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].z / ratio[2] ;

        

            /// 我们设定的纹理

            int t1 = (x+0.5)*64;

            int t2 = (y+0.5)*64;

            glColor3f( T0[t1][t2][0],  T0[t1][t2][1],  T0[t1][t2][2] );

 

            /// 顶点

            glVertex3f( x, y, z ); 

        } 

 

        glEnd();

    }

 

    float degree = 45;

    glRotatef(degree, 1, 1, 1 );

 

    /// 旋转

    glFlush();

}

 

 

/// 显示example10.obj

void ExampleDisplay()

{

    /// 导入obj文件

    CAccessObj OBJ;

    OBJ.LoadOBJ("example10.obj");

 

    /// 为了将图像显示在窗口,看x,y,z轴上的最大值最小值

    float x1 = OBJ.m_vMax.x;

    float y1 = OBJ.m_vMax.y;

    float z1 = OBJ.m_vMax.z;

    float x2 = OBJ.m_vMin.x;

    float y2 = OBJ.m_vMin.y;

    float z2 = OBJ.m_vMin.z;

 

    float ratio[3] = {x1-x2, y1-y2, z1-z2};

 

    ///////////////////////////////////////////////////////////

    /// 用这幅图像作为纹理

    IplImage *img = cvLoadImage( "example10.bmp"  );

    img->origin = 0;

    int w = img->width;

    int h = img->height;

 

    ///////////////////////////////////////////////////////////

 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 

 

    for ( int m=0; m<OBJ.m_pModel->nTriangles; m++ )

    {

        glBegin(GL_TRIANGLES);  

 

        /// 顶点

        unsigned int *pVertIdx = ( OBJ.m_pModel->pTriangles )[m].VertIdx;

        /// 纹理坐标 texture point 

        unsigned int *pTexIdx = ( OBJ.m_pModel->pTriangles )[m].TexIdx; ///< 在texture中找对应的点

 

        for ( int i=0; i<3; i++ )

        {

            float x = 0;

            float y = 0;

            float z = 0;

 

            x = ( OBJ.m_pModel->vpTexCoords )[pTexIdx[i]].x * h;

            y = ( OBJ.m_pModel->vpTexCoords )[pTexIdx[i]].y * w;

 

            uchar* temp_ptr = &((uchar*)(img->imageData + img->widthStep*((int)y)))[(int)x*3];

            glColor3f( (float)temp_ptr[2]/256, (float)temp_ptr[1]/256, (float)temp_ptr[0]/256 );///< 注意顺序

 

            x = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].x / ratio[0] ;

            y = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].y / ratio[1] ;

            z = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].z / ratio[2] ;

            glVertex3f( x, y, z );     

        } 

        

        glEnd();

    }

 

    /*float degree = 45;

    glRotatef(degree, 1, 1, 1 );*/

 

    glFlush();

 

    cvReleaseImage( &img );

}

 

 

int _tmain(int argc, char* argv[])

{

 

    /// 对GLUT进行初始化,这个函数必须在其它的GLUT使用之前调用一次。其格式比较死板,一般照抄这句glutInit(&argc, argv)就可以了。

     glutInit( &argc,  argv ); 

 

    /// 设置显示方式

    /// GLUT_RGB表示使用RGB颜色,与之对应的还有GLUT_INDEX(表示使用索引颜色)。

    /// GLUT_SINGLE表示使用单缓冲,与之对应的还有GLUT_DOUBLE(使用双缓冲)。

    glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE ); 

 

 

    glutInitWindowPosition( 100, 100 ); 

    glutInitWindowSize( 400, 400 ); 

 

    glutCreateWindow( "Test" ); 

 

 

    /// 这里选择要显示的对象,即上面的三个函数——cubeDisplay1,cubeDisplay2,ExampleDisplay

    // glutDisplayFunc( &cubeDisplay1 ); 

    // glutDisplayFunc( &cubeDisplay2 ); 

    glutDisplayFunc( &ExampleDisplay ); 

 

    glutMainLoop(); 

 

 

 

    return 0;

}

 

 

/*

没搞定的几个函数:

    glGenTextures(1, &Tname0); // 获取纹理名字

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, T0); // 设置纹理对象内容

    glEnable(GL_TEXTURE_2D); // 使纹理可用

    glBindTexture(GL_TEXTURE_2D, Tname0); // **纹理

    glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // 设置纹理贴图方式

*/

这里调用了网上的一个读obj文件的类。
版权声明:转载http://www.blogbus.com/shijuanfeng-logs/226093549.html