`
暴风雪
  • 浏览: 390776 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

[opengl]opengl加载maya的obj模型并显示

 
阅读更多

obj文件的理解请参考:http://foolog.net/?p=941

 

要注意一点,obj文件中面的保存,有的是按照三角形(也就是只有三个点),有的是按照空间四边形保存(包含四个点),这里是按照四个点来的,注释中已经给出。

 

#ifndef GLUT_DISABLE_ATEXIT_HACK
#define GLUT_DISABLE_ATEXIT_HACK
#endif #define GLEW_STATIC
#include <GL/glew.h>
#include <GL/wglew.h>
#include <GL/freeglut.h>
#include <vector>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> //for matrices
#include <glm/gtc/type_ptr.hpp>
//undefine if u want to use the default bending constraint of pbd
#include<sstream>
#include <fstream>
#include<iostream>
using namespace std;

GLfloat rtx = 0.0f, rty = 0.0f, rtz = 0.0;
GLfloat step = 0.1;
//float exp1 = 1e-3;
const int GRID_SIZE = 10;
GLint viewport[4];
GLdouble PP[16];

int v_num; //记录点的数量
int vn_num;//记录法线的数量
int vt_num;//
int f_num; //记录面的数量
GLfloat **vArr; //存放点的二维数组
GLfloat **vnArr;//存放法线的二维数组
int **fvArr; //存放面顶点的二维数组
int **fnArr; //存放面法线的二维数组

int readfile(string addrstr) //将文件内容读到数组中去
{
    int i;
    string s1;
    float f2,f3,f4;
    vArr=new GLfloat*[v_num];
    for (i=0; i<v_num; i++)
    {
        vArr[i]=new GLfloat[3];
    }
    vnArr=new GLfloat*[vn_num];
    for (i=0; i<vn_num; i++)
    {
        vnArr[i]=new GLfloat[3];
    }
    fvArr=new int*[f_num];
    fnArr=new int*[f_num];
    for (i=0; i<f_num; i++)
    {
        fvArr[i]=new int[4];
        fnArr[i]=new int[3];
    }
    ifstream infile(addrstr.c_str());
    string sline;//每一行
    int ii=0,jj=0,kk=0;

    while(getline(infile,sline))
    {
        if(sline[0]=='v')
        {
            if(sline[1]=='n')//vn
            {
                istringstream sin(sline);
                sin>>s1>>f2>>f3>>f4;
                vnArr[ii][0]=f2;
                vnArr[ii][1]=f3;
                vnArr[ii][2]=f4;
                ii++;
            }
            else if(sline[1] == 't'){}
            else//v
            {
                istringstream sin(sline);
                sin>>s1>>f2>>f3>>f4;
                vArr[jj][0]=f2;
                vArr[jj][1]=f3;
                vArr[jj][2]=f4;
                jj++;
            }
        }
        if (sline[0]=='f') //读取面
        {
            istringstream in(sline);
            GLfloat a;

            in>>s1;//去掉前缀f
            int i,k;
//点数改这里
            for(i=0; i<4; i++)
            {
                in>>s1;
//                cout<<s1<<endl;
                printf("%s\n",s1.c_str());
                //取得顶点索引和法线索引
                a=0;
                for(k=0; s1[k]!='/'; k++)
                {
                    a=a*10+(s1[k]-48);
                }
                fvArr[kk][i]=a;

                a=0;
                for(k=k+2; s1[k]; k++)
                {
                    a=a*10+(s1[k]-48);;
                }
                fnArr[kk][i]=a;
            }
            kk++;
        }
    }
    return 0;
}

void getLineNum(string addrstr){   //获取点数以及面数
//    cout<<addrstr.c_str()<<endl;
    v_num = vn_num = f_num = vt_num = 0;
    ifstream infile(addrstr.c_str());
    string sline;//每一行
    while(getline(infile, sline)){
//        cout<<sline<<endl;
            printf("%s\n",sline.c_str());
        if(sline[0]=='v'){
            if(sline[1] == 'n'){
                vn_num ++;
            }else if(sline[1] =='t'){ //vt
                vt_num ++;
            }else{
                v_num ++;
            }
        }else{
            if(sline[0] == 'f'){
                f_num ++;
            }
        }
    }
}

string s1;
GLfloat f2,f3,f4;

void DrawGrid()
{
	glBegin(GL_LINES);
	glColor3f(0.5f, 0.5f, 0.5f);
	for(int i=-GRID_SIZE;i<=GRID_SIZE;i++)
	{
		glVertex3f((float)i,0,(float)-GRID_SIZE);
		glVertex3f((float)i,0,(float)GRID_SIZE);

		glVertex3f((float)-GRID_SIZE,0,(float)i);
		glVertex3f((float)GRID_SIZE,0,(float)i);
	}
	glEnd();
}

void draw(void)
{
    cout<<f_num;
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(0,0,-10);
    glRotatef(15,1,0,0);
    DrawGrid();

    glBegin(GL_LINES);
    glColor3f(1, 1, 1);
    for(int i = 0; i < f_num; i++){
        int a0,a1,a2,a3;
        a0 = fvArr[i][0]-1;
        a1 = fvArr[i][1]-1;
        a2 = fvArr[i][2]-1;
        //点数改这里
        a3 = fvArr[i][3]-1;
            glVertex3f(vArr[a0][0],vArr[a0][1],vArr[a0][2]);
            glVertex3f(vArr[a1][0],vArr[a1][1],vArr[a1][2]);
            cout<<vArr[a0][0]<<" line "<<vArr[a1][0]<<endl;
            glVertex3f(vArr[a1][0],vArr[a1][1],vArr[a1][2]);
            glVertex3f(vArr[a2][0],vArr[a2][1],vArr[a2][2]);
            cout<<vArr[a1][0]<<" line "<<vArr[a2][0]<<endl;
            glVertex3f(vArr[a2][0],vArr[a2][1],vArr[a2][2]);
            //点数改这里
            glVertex3f(vArr[a3][0],vArr[a3][1],vArr[a3][2]);
            glVertex3f(vArr[a3][0],vArr[a3][1],vArr[a3][2]);
            cout<<vArr[a2][0]<<" line "<<vArr[a0][0]<<endl;
            glVertex3f(vArr[a0][0],vArr[a0][1],vArr[a0][2]);

    }
    glEnd();
    glutSwapBuffers();
}

void OnReshape(int nw, int nh) {
    glViewport(0,0,nw, nh);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60, (GLfloat)nw / (GLfloat)nh, 1.f, 100.0f);

    glGetIntegerv(GL_VIEWPORT, viewport);
    glGetDoublev(GL_PROJECTION_MATRIX, PP);

    glMatrixMode(GL_MODELVIEW);
}
//float step = 0.001;

int main(int argc, char * argv[])
{
    getLineNum("yifu.obj");
    readfile("yifu.obj");
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(1024, 1024);
    glutCreateWindow("Hello OpenGL");
//    init();
    glutDisplayFunc(draw);
//    glutIdleFunc(draw); //指定程序空闲时调用函数
    glutReshapeFunc(OnReshape); //指定窗口形状变化时的回调函数
    glEnable(GL_DEPTH_TEST);

    glutMainLoop();
    return 0;
}

 

0
0
分享到:
评论

相关推荐

    三维模型文件中的OBJ格式在OpenGL中的输入与处理.pdf

    在处理OBJ模型时,可以加载并应用对应的Mtl材质文件,以获取模型的材质属性,包括颜色、透明度、反射率等,从而实现更加精细的渲染效果。 总之,OBJ格式作为一种通用且易于处理的3D模型格式,在OpenGL中具有广泛的...

    三维模型(obj,gltf)

    `city.mtl` 文件就提供了`city.obj` 模型的材质信息,使3D渲染器能够正确显示模型的外观。 3. **gltf格式**: GL Transmission Format(gltf)是Khronos Group开发的一种开放标准的3D资产交换格式,旨在成为WebGL...

    三维模型文件中的OBJ格式在OpenGL中的输入与处理

    一篇详解OBJ格式以及实现读入的文章,可以参考参考(介绍了当今流行的三维作图工具Maya,阐述了Maya 生成的OBJ 三维格式,如何将OBJ 格式文件在OpenGL(Open Graphic Library)中进行输入和处理。重点介绍了OBJ 文件的...

    OpenGL-Learn18(加载外部模型)

    本教程“OpenGL-Learn18(加载外部模型)”聚焦于如何使用OpenGL加载和渲染外部3D模型,例如从.obj文件中加载圣诞熊模型(christmas_bear_obj)。 首先,我们要了解.obj文件格式。.obj是Wavefront公司创建的一种...

    三维OBJ模型

    对于提供的“三维模型.obj格式”文件,你可以使用各种3D建模软件(如Blender、3ds Max、Maya等)或编程库(如Assimp、OpenGL、Direct3D等)来打开、查看和编辑这个模型。通过研究这个模型,你可以更深入地理解OBJ...

    opengl内使用聚光灯对模型进行照明

    这些模型通常以OBJ、FBX或其他格式导出,并通过OpenGL加载。模型的几何信息(顶点、法线、纹理坐标)和材质属性是实现光照效果的关键。 5. **贴图技术**:在3D模型上应用贴图可以增强其视觉效果。常见的贴图类型有...

    opengl模型动画制作方法

    4. **模型导入OpenGL**:将处理好的模型以特定格式(如.md3、.3ds、.obj或.smd)导出后,可以通过OpenGL的API将模型数据加载进内存,准备渲染。这里特别提到了smd格式,它是Source引擎使用的动画格式,通过专门的...

    ActivePerl+obj2opengl for Mac

    obj2opengl脚本就承担了这个角色,它可以解析.obj文件,并将其转换为OpenGL可理解的数据结构,从而方便地在iOS设备上渲染3D模型。 使用obj2opengl,开发者可以避免手动处理复杂的3D模型数据,节省大量时间。只需...

    3D网格模型(obj格式)

    其中,obj格式是一种广泛使用的3D模型交换格式,它由Wavefront Technologies公司为他们的OpenGL编程接口开发。本篇文章将深入探讨obj格式的特点、结构以及它在不同场景中的应用。 1. **obj格式概述** - obj文件...

    LoadObj.cpp

    OpenGL加载Obj文件 obj文件是3D模型文件格式。由Alias|Wavefront公司为3D建模和动画软件"Advanced Visualizer"开发的一种标准,适合用于3D软件模型之间的互导,也可以通过Maya读写。

    opengl模拟CS地图

    在地图建模方面,开发者可能使用了某种3D建模软件(如Blender或Maya)来创建原始模型,然后导出为如OBJ或OBJ+MTL格式的文件,再在程序中读取并解析这些文件,将模型数据转换为OpenGL能理解的形式。纹理信息可能存储...

    Obj.rar_java obj

    总之,"Obj.rar_java obj"文件是一个关于使用Java 3D加载和显示OBJ模型的实例,涵盖了3D图形编程的核心概念,包括文件解析、几何构建、材质和纹理应用,以及最终的渲染。这对于希望在Java环境中进行3D图形开发的...

    meta编辑器基于opengl

    4. **文件支持**:可能支持多种3D格式的导入和导出,如OBJ、3DS、FBX等,方便与其他软件(如Blender、Maya等)进行数据交换。 5. **资源管理**:编辑器可能包含资源管理功能,如纹理、模型、动画的组织和管理,便于...

    Obj文件格式实验(ObjParser)

    Obj文件格式的主要优点在于它的简单性和通用性,使得它能被多种3D建模软件所支持,如Blender、Maya、3DS Max等。 Obj文件主要包括以下几部分: 1. **顶点(Vertices)**:Obj文件用`v`关键字定义顶点,每个顶点由...

    java弹球游戏源码-GLES2_Anima_LoadFrom_Obj:从obj文件中加载3d图形,并为3d图形赋予动画属性

    看到这个需求,直接React是用OpenGLES加载一个.obj(顶点数据)与.mtl(颜色材质信息)文件 就搞定了( .obj与.mtl文件由设计师用3dmax、Maya等工具导出)。 本以为是一个简单需求,但做起来发现困难点并不少: OpenGLES...

    效果超棒的Webgl模型-人体肺

    为了构建这个模型,开发者首先需要对人体肺部的解剖学有深入理解,然后使用建模软件(如Blender、Maya或3DS Max)创建3D模型,并将其导出为WebGL可读的格式,如OBJ或GLTF。模型可能包含多个部件,如左肺、右肺、...

    几何物体的表示——三角网格的表示与显示

    接下来,Obj文件格式是一种常见的3D模型文件格式,由Wavefront Technologies开发,常用于3D建模软件如Blender或Maya中导出模型。Obj文件包含顶点坐标、纹理坐标和面信息等,使用ASCII编码,易于阅读和编写。解析Obj...

    webgl载入模型webgl载入模型webgl载入模型

    接着,我们可以实例化GLTFLoader,并在load方法中传入模型文件URL,加载完成后,loader会调用回调函数,其中包含解析后的模型数据。 ```javascript var loader = new THREE.GLTFLoader(); loader.load('model.gltf'...

    OpenGL ES基于安卓开发的地月星系(Android源码)

    开发者可能使用专门的3D建模软件如Blender或Maya来设计模型,然后将其导出为OBJ、GLTF或FBX等格式,再在程序中加载并解析这些模型。此外,纹理映射则允许我们在3D模型表面添加色彩和细节,增强视觉效果,这通常涉及...

    动作捕捉ASF/AMC 的opengl 的多线程程序

    角色有蒙皮,你可以根据自己需要选择自己的蒙皮,但需要自己提供Obj格式的三维模型,为了使骨骼驱动皮肤,你还需要提供皮肤与骨骼绑定的权重数据,我提供了maya插件可以将你的模型和骨骼的权重数据在maya中导出,...

Global site tag (gtag.js) - Google Analytics