OpenGL---加载obj模型

来源:互联网 发布:淘宝号不能登陆优酷 编辑:程序博客网 时间:2024/05/31 19:46

obj文件格式介绍:http://www.cnblogs.com/youthlion/archive/2013/01/21/2870451.html

mesh.h

#pragma once#include "vector"#include "iostream"#include "string"#include "fstream"#include "sstream"#include "algorithm"#include "assert.h"#include <windows.h>#include <GL/gl.h>#include <GL/glu.h>#include <GL/glut.h>#pragma comment(lib, "glut.lib")using namespace std;struct vec3{    double x, y, z;};struct vec2{    double x, y;};class Vertex{public:     int vertIndex;     // 此顶点在顶点列表中的索引    int normIndex;     // 顶点的法线索引    int textIndex;     // 顶点的纹理索引};class Face{public:    vector<Vertex> vertex; // 顶点和法线索引组成的列表    Face(){}    ~Face(){}};class Mesh{private:    vector<vec3> vVertex;  // 顶点数组    vector<vec2> vText;    // 纹理数组    vector<vec3> vNorm;    // 法线数组    vector<Face> vFace;    // 面片数组public:    Mesh(){};    ~Mesh(){};    bool readFile(char* path);    void drawMesh();};bool Mesh::readFile(char* path){       ifstream file(path);    if (!file)    {        cerr << "Error::ObjLoader, could not open obj file:"            << path << " for reading." << std::endl;        return false;    }    string line;    while (getline(file, line))    {        if (line.substr(0, 2) == "vt")     // 顶点纹理坐标数据        {            istringstream s(line.substr(2));            vec2 v;            s >> v.x; s >> v.y;            //cout << "vt " << v.x << " " << v.y << endl;            v.y = -v.y;                     // 注意这里加载的dds纹理 要对y进行反转            vText.push_back(v);        }        else if (line.substr(0, 2) == "vn") // 顶点法向量数据        {            istringstream s(line.substr(2));            vec3 v;            s >> v.x; s >> v.y; s >> v.z;            //cout << "vn " << v.x << " " << v.y << " " << v.z << endl;            vNorm.push_back(v);        }        else if (line.substr(0, 1) == "v")  // 顶点位置数据        {            istringstream s(line.substr(1));            vec3 v;            s >> v.x; s >> v.y; s >> v.z;            //cout << "v " << v.x << " " << v.y << " " << v.z << endl;            vVertex.push_back(v);        }        else if (line.substr(0, 1) == "f")  // 面数据        {            Face face;            //cout << "f ";            istringstream vtns(line.substr(1));            string vtn;            while (vtns >> vtn)             // 处理一行中多个顶点属性            {                Vertex vertex;                replace(vtn.begin(), vtn.end(), '/', ' ');                istringstream ivtn(vtn);                if (vtn.find("  ") != string::npos) // 没有纹理数据,注意这里是2个空格                {                    ivtn >> vertex.vertIndex                                 >> vertex.normIndex;                    vertex.vertIndex--;     //使得下标从0开始                    vertex.normIndex--;                }                else                {                    ivtn >> vertex.vertIndex                           >> vertex.textIndex                          >> vertex.normIndex;                    //cout <<  vertex.vertIndex << "/" << vertex.textIndex << "/" << vertex.normIndex << " ";                    vertex.vertIndex--;                       vertex.textIndex--;                    vertex.normIndex--;                }                face.vertex.push_back(vertex);            }            vFace.push_back(face);            //cout << endl;        }        else if (line[0] == '#')            // 注释忽略        { }        else          {            // 其余内容 暂时不处理        }    }    return true;}void Mesh::drawMesh(){     if(vFace.empty())        return;    // 有纹理    if(vText.size() > 0)      {        for(int f = 0; f < vFace.size(); f++)  // 绘制每个面片        {            int n = vFace[f].vertex.size();    // 面的顶点数            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);            glBegin(GL_TRIANGLES);            for(int v = 0; v < n; v++)            {                int it = vFace[f].vertex[v].textIndex;                glTexCoord2f(vText[it].x, vText[it].y);                int in = vFace[f].vertex[v].normIndex;                  glNormal3f(vNorm[in].x, vNorm[in].y, vNorm[in].z);                int iv = vFace[f].vertex[v].vertIndex;                 glVertex3f(vVertex[iv].x, vVertex[iv].y, vVertex[iv].z);            }            glEnd();        }    }    // 没有纹理    else                      {        for(int f = 0; f < vFace.size(); f++)  // 绘制每个面片        {            int n = vFace[f].vertex.size();    // 面的顶点数            glBegin(GL_TRIANGLES);            for(int v = 0; v < n; v++)            {                int in = vFace[f].vertex[v].normIndex;                glNormal3f(vNorm[in].x, vNorm[in].y, vNorm[in].z);                int iv = vFace[f].vertex[v].vertIndex;                 glVertex3f(vVertex[iv].x, vVertex[iv].y, vVertex[iv].z);            }            glEnd();        }    }    //glFlush();}

main.cpp

#include "mesh.h"const int windowWidth = 800;const int windowHeight = 600;Mesh mesh;void myDisplay(){    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glEnable(GL_NORMALIZE);    glColor3f(1, 1, 1);    mesh.drawMesh();    glutSwapBuffers();    glutPostRedisplay();}   void myInit(){    glClearColor(0, 0, 0, 0);    glEnable(GL_NORMALIZE);    glEnable(GL_DEPTH_TEST);    glEnable(GL_TEXTURE_2D);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    gluPerspective(60.0, windowWidth/ windowHeight, 1.0, 21.0);    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();    gluLookAt(5, 6, 7, 0, 0, 0, 0, 1, 0);    mesh.readFile("1.obj");}int main(){    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);     glutInitWindowPosition(50, 50);     glutInitWindowSize(windowWidth, windowHeight);    glutCreateWindow("DEMO");     myInit();    glutDisplayFunc(myDisplay);     glutMainLoop();     return 0; }

1.obj

# Blender3D v249 OBJ File: untitled.blend# www.blender3d.orgmtllib cube.mtlv 1.000000 -1.000000 -1.000000v 1.000000 -1.000000 1.000000v -1.000000 -1.000000 1.000000v -1.000000 -1.000000 -1.000000v 1.000000 1.000000 -1.000000v 0.999999 1.000000 1.000001v -1.000000 1.000000 1.000000v -1.000000 1.000000 -1.000000vt 0.748573 0.750412vt 0.749279 0.501284vt 0.999110 0.501077vt 0.999455 0.750380vt 0.250471 0.500702vt 0.249682 0.749677vt 0.001085 0.750380vt 0.001517 0.499994vt 0.499422 0.500239vt 0.500149 0.750166vt 0.748355 0.998230vt 0.500193 0.998728vt 0.498993 0.250415vt 0.748953 0.250920vn 0.000000 0.000000 -1.000000vn -1.000000 -0.000000 -0.000000vn -0.000000 -0.000000 1.000000vn -0.000001 0.000000 1.000000vn 1.000000 -0.000000 0.000000vn 1.000000 0.000000 0.000001vn 0.000000 1.000000 -0.000000vn -0.000000 -1.000000 0.000000usemtl Material_ray.pngs offf 5/1/1 1/2/1 4/3/1f 5/1/1 4/3/1 8/4/1f 3/5/2 7/6/2 8/7/2f 3/5/2 8/7/2 4/8/2f 2/9/3 6/10/3 3/5/3f 6/10/4 7/6/4 3/5/4f 1/2/5 5/1/5 2/9/5f 5/1/6 6/10/6 2/9/6f 5/1/7 8/11/7 6/10/7f 8/11/7 7/12/7 6/10/7f 1/2/8 2/9/8 3/13/8f 1/2/8 3/13/8 4/14/8

这里写图片描述

不足:没有对纹理处理,比如没有纹理图片,缺乏相关操作等。

—————————–变一下样式———————————-
将drawMesh()修改一下(仍然没有对纹理进行处理)

void Mesh::drawMesh(){     if(vFace.empty())        return;    // 有纹理    if(vText.size() > 0)      {        for(int f = 0; f < vFace.size(); f++)  // 绘制每个面片        {            int n = vFace[f].vertex.size();    // 面的顶点数            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);            glBegin(GL_TRIANGLES);            glColor3f(1, 1, 1);            for(int v = 0; v < n; v++)            {                int it = vFace[f].vertex[v].textIndex;                glTexCoord2f(vText[it].x, vText[it].y);                int in = vFace[f].vertex[v].normIndex;                  glNormal3f(vNorm[in].x, vNorm[in].y, vNorm[in].z);                int iv = vFace[f].vertex[v].vertIndex;                 glVertex3f(vVertex[iv].x, vVertex[iv].y, vVertex[iv].z);            }            glEnd();            glBegin(GL_LINE_LOOP);            glColor3f(0, 0, 1);            for (int v = 0; v < n; v++)            {                int it = vFace[f].vertex[v].textIndex;                glTexCoord2f(vText[it].x, vText[it].y);                int in = vFace[f].vertex[v].normIndex;                glNormal3f(vNorm[in].x, vNorm[in].y, vNorm[in].z);                int iv = vFace[f].vertex[v].vertIndex;                glVertex3f(vVertex[iv].x, vVertex[iv].y, vVertex[iv].z);            }            glEnd();        }    }    // 没有纹理    else                      {        for(int f = 0; f < vFace.size(); f++)  // 绘制每个面片        {            int n = vFace[f].vertex.size();    // 面的顶点数            glBegin(GL_TRIANGLES);            for(int v = 0; v < n; v++)            {                int in = vFace[f].vertex[v].normIndex;                glNormal3f(vNorm[in].x, vNorm[in].y, vNorm[in].z);                int iv = vFace[f].vertex[v].vertIndex;                 glVertex3f(vVertex[iv].x, vVertex[iv].y, vVertex[iv].z);            }            glEnd();        }    }}

这里写图片描述

0 0