·找了好几个程序,好像都达不到我的要求,去教程里看看吧!

在往上抛出了这问题,好几天才有人回答,我已经找到程序了

正好的他的分析对我分解程序很有用

这是一个难度比较高的

首先你要分析.off文件结构,哪些是存储模型信息的(模型矩阵,光照,材质,坐标等等信息)

和节点信息(包括点,可能有直线,三角形,四边形等等)

然后通过文件IO来读写文件,分析数据含义,并通过数据结构来分类存储各种信息

搭建OpenGL显示环境

根据数据绘制模型

绘制模型的渲染

(如果有对模型进行一些操作的话,工作量会更多)

PS:第一步是最繁琐的一步,第二步搭建环境比较轻松,第三步绘制那块也就写一些函数,不断调用就是了,第四步主要是对材质光照纹理方面的一些处理)

找到了一个程序:

感觉很不错~ 

好像cnblog无法放代码

那我就把那个程序放到csdn上吧

下载地址: http://download.csdn.net/detail/lhq186/7023821

开始分析程序: 注释写得很不错,看样子是外国人写的

(1)标准库函数

// Standard include files

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <assert.h>

#include<string>
#include<vector>
#include<iostream>
using namespace std;

  

(2)windows库函数

// Windows include files 

#ifdef _WIN32
#include <windows.h>
#endif

  

(3)openGL库函数

// OpenGL include files 

#include <GL/gl.h>
#include <GL/glu.h>
#define GLUT_DISABLE_ATEXIT_HACK
#include <GL/glut.h>

  

(4)type定义

////////////////////////////////////////////////////////////
// TYPE DEFINITIONS
////////////////////////////////////////////////////////////

typedef struct Vertex { //typedef,struct 结构体有点忘记了,要再写一篇博客复习一下,这里定义的是x,y,z坐标
  float x, y, z;
} Vertex;             

/*这里用了typedef

这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时

候,或许,在C++中,typedef的这种用途不是很大,但是理解了它,对掌握以前的旧代

码还是有帮助的,毕竟我们在项目中有可能会遇到较早些年代遗留下来的代码。

*/

typedef struct Face {
  Face(void) : nverts(0), verts(0) {};
  int nverts;
  Vertex **verts; //上面用typedef定义了Vertex为结构体,这里直接就拿来用了
  float normal[3];
} Face;

typedef struct Mesh {
  Mesh(void) : nverts(0), verts(0), nfaces(0), faces(0) {};
  int nverts;
  Vertex *verts;
  int nfaces;
  Face *faces;

 vector<Vertex>point;

} Mesh;

  

先睡觉,今晚和爸妈打电话迟了一点。。。

明早起来有重要事情
////////////////////////////////////////////////////////////
// GLOBAL VARIABLES
////////////////////////////////////////////////////////////

// Program arguments

 static char *filename = "cube.off";//这个是要输入的off文件名

// GLUT variables 

static int GLUTwindow = 0;
static int GLUTwindow_height = 800;
static int GLUTwindow_width = 800;
static int GLUTmouse[2] = { 0, 0 };
static int GLUTbutton[3] = { 0, 0, 0 };
static int GLUTarrows[4] = { 0, 0, 0, 0 };
static int GLUTmodifiers = 0;

// Display variables

static int scaling = 0;
static int translating = 0;
static int rotating = 0;
static float scale = 1.0;
static float center[3] = { 0.0, 0.0, 0.0 };
static float rotation[3] = { 0.0, 0.0, 0.0 };
static float translation[3] = { 0.0, 0.0, -4.0 };

// Mesh variables

static Mesh *mesh = NULL;

  

下面开始读入文件:

Mesh *
ReadOffFile(const char *filename)
{
  int i;

  // Open file
  FILE *fp;
  if (!(fp = fopen(filename, "r"))) {
    fprintf(stderr, "Unable to open file %s\n", filename);
    return 0;
  }

  // Allocate mesh structure
  Mesh *mesh = new Mesh();
  if (!mesh) {
    fprintf(stderr, "Unable to allocate memory for file %s\n", filename);
    fclose(fp);
    return 0;
  }

  // Read file
  int nverts = 0;
  int nfaces = 0;
  int nedges = 0;
  int line_count = 0;
  char buffer[1024];
  while (fgets(buffer, 1023, fp)) {
    // Increment line counter
    line_count++;

    // Skip white space
    char *bufferp = buffer;
    while (isspace(*bufferp)) bufferp++;

    // Skip blank lines and comments
    if (*bufferp == '#') continue;
    if (*bufferp == '\0') continue;

    // Check section
    if (nverts == 0) {
      // Read header
      if (!strstr(bufferp, "OFF")) {
        // Read mesh counts
        if ((sscanf(bufferp, "%d%d%d", &nverts, &nfaces, &nedges) != 3) || (nverts == 0)) {
          fprintf(stderr, "Syntax error reading header on line %d in file %s\n", line_count, filename);
          fclose(fp);
          return NULL;
        }

        // Allocate memory for mesh
        mesh->verts = new Vertex [nverts];
        assert(mesh->verts);
        mesh->faces = new Face [nfaces];
        assert(mesh->faces);
      }
    }
    else if (mesh->nverts < nverts) {
      // Read vertex coordinates
      Vertex& vert = mesh->verts[mesh->nverts++];
      if (sscanf(bufferp, "%f%f%f", &(vert.x), &(vert.y), &(vert.z)) != 3) {
        fprintf(stderr, "Syntax error with vertex coordinates on line %d in file %s\n", line_count, filename);
        fclose(fp);
        return NULL;
      }
    }
    else if (mesh->nfaces < nfaces) {
      // Get next face
      Face& face = mesh->faces[mesh->nfaces++];

      // Read number of vertices in face
      bufferp = strtok(bufferp, " \t");
      if (bufferp) face.nverts = atoi(bufferp);
      else {
        fprintf(stderr, "Syntax error with face on line %d in file %s\n", line_count, filename);
        fclose(fp);
        return NULL;
      }

      // Allocate memory for face vertices
      face.verts = new Vertex *[face.nverts];
      assert(face.verts);

      // Read vertex indices for face
      for (i = 0; i < face.nverts; i++) {
        bufferp = strtok(NULL, " \t");
        if (bufferp) face.verts[i] = &(mesh->verts[atoi(bufferp)]);
        else {
          fprintf(stderr, "Syntax error with face on line %d in file %s\n", line_count, filename);
          fclose(fp);
          return NULL;
        }
      }

      // Compute normal for face
      face.normal[0] = face.normal[1] = face.normal[2] = 0;
      Vertex *v1 = face.verts[face.nverts-1];
      for (i = 0; i < face.nverts; i++) {
        Vertex *v2 = face.verts[i];
        face.normal[0] += (v1->y - v2->y) * (v1->z + v2->z);
        face.normal[1] += (v1->z - v2->z) * (v1->x + v2->x);
        face.normal[2] += (v1->x - v2->x) * (v1->y + v2->y);
        v1 = v2;
      }

      // Normalize normal for face
      float squared_normal_length = 0.0;
      squared_normal_length += face.normal[0]*face.normal[0];
      squared_normal_length += face.normal[1]*face.normal[1];
      squared_normal_length += face.normal[2]*face.normal[2];
      float normal_length = sqrt(squared_normal_length);
      if (normal_length > 1.0E-6) {
        face.normal[0] /= normal_length;
        face.normal[1] /= normal_length;
        face.normal[2] /= normal_length;
      }
    }
    else {
      // Should never get here
      fprintf(stderr, "Found extra text starting at line %d in file %s\n", line_count, filename);
      break;
    }
  }

  // Check whether read all faces
  if (nfaces != mesh->nfaces) {
    fprintf(stderr, "Expected %d faces, but read only %d faces in file %s\n", nfaces, mesh->nfaces, filename);
  }

  // Close file
  fclose(fp);

  // Return mesh
  return mesh;
}

  

用户接口代码:
////////////////////////////////////////////////////////////
// GLUT USER INTERFACE CODE
////////////////////////////////////////////////////////////

void GLUTRedraw(void)
{
  // Setup viewing transformation
  glLoadIdentity();
  glScalef(scale, scale, scale);
  glTranslatef(translation[0], translation[1], 0.0);

  // Set projection transformation
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(45.0, (GLfloat) GLUTwindow_width /(GLfloat) GLUTwindow_height, 0.1, 100.0);

  // Set camera transformation
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glTranslatef(translation[0], translation[1], translation[2]);
  glScalef(scale, scale, scale);
  glRotatef(rotation[0], 1.0, 0.0, 0.0);
  glRotatef(rotation[1], 0.0, 1.0, 0.0);
  glRotatef(rotation[2], 0.0, 0.0, 1.0);
  glTranslatef(-center[0], -center[1], -center[2]);

  // Clear window
  glClearColor(1.0, 1.0, 1.0, 1.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  // Set lights
  static GLfloat light0_position[] = { 3.0, 4.0, 5.0, 0.0 };
  glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
  static GLfloat light1_position[] = { -3.0, -2.0, -3.0, 0.0 };
  glLightfv(GL_LIGHT1, GL_POSITION, light1_position);

  // Set material
  static GLfloat material[] = { 1.0, 0.5, 0.5, 1.0 };
  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, material); 

  // Draw faces
  for (int i = 0; i < mesh->nfaces; i++) {
    Face& face = mesh->faces[i];
    glBegin(GL_POLYGON);
    glNormal3fv(face.normal);
    for (int j = 0; j < face.nverts; j++) {
      Vertex *vert = face.verts[j];
      glVertex3f(vert->x, vert->y, vert->z);
    }
    glEnd();
  }

  // Swap buffers
  glutSwapBuffers();
}    

void GLUTStop(void)
{
  // Destroy window
  glutDestroyWindow(GLUTwindow);

  // Exit
  exit(0);
}

void GLUTResize(int w, int h)
{
  // Resize window
  glViewport(0, 0, w, h);

  // Remember window size
  GLUTwindow_width = w;
  GLUTwindow_height = h;

  // Redraw
  glutPostRedisplay();
}

void GLUTMotion(int x, int y)
{
  // Invert y coordinate
  y = GLUTwindow_height - y;

  // Process mouse motion event
  if (rotating) {
    // Rotate model
    rotation[0] += -0.5 * (y - GLUTmouse[1]);
    rotation[2] += 0.5 * (x - GLUTmouse[0]);
  }
  else if (scaling) {
    // Scale window
    scale *= exp(2.0 * (float) (x - GLUTmouse[0]) / (float) GLUTwindow_width);
  }
  else if (translating) {
    // Translate window
    translation[0] += 2.0 * (float) (x - GLUTmouse[0]) / (float) GLUTwindow_width;
    translation[1] += 2.0 * (float) (y - GLUTmouse[1]) / (float) GLUTwindow_height;
  }

  // Remember mouse position
  GLUTmouse[0] = x;
  GLUTmouse[1] = y;
}

void GLUTMouse(int button, int state, int x, int y)
{
  // Invert y coordinate
  y = GLUTwindow_height - y;

  // Process mouse button event
  rotating = (button == GLUT_LEFT_BUTTON);
  scaling = (button == GLUT_MIDDLE_BUTTON);
  translating = (button == GLUT_RIGHT_BUTTON);
  if (rotating || scaling || translating) glutIdleFunc(GLUTRedraw);
  else glutIdleFunc(0);

  // Remember button state
  int b = (button == GLUT_LEFT_BUTTON) ? 0 : ((button == GLUT_MIDDLE_BUTTON) ? 1 : 2);
  GLUTbutton[b] = (state == GLUT_DOWN) ? 1 : 0;

  // Remember modifiers
  GLUTmodifiers = glutGetModifiers();

   // Remember mouse position
  GLUTmouse[0] = x;
  GLUTmouse[1] = y;
}

void GLUTSpecial(int key, int x, int y)
{
  // Invert y coordinate
  y = GLUTwindow_height - y;

  // Process keyboard button event 

  // Remember mouse position
  GLUTmouse[0] = x;
  GLUTmouse[1] = y;

  // Remember modifiers
  GLUTmodifiers = glutGetModifiers();

  // Redraw
  glutPostRedisplay();
}

void GLUTKeyboard(unsigned char key, int x, int y)
{
  // Process keyboard button event
  switch (key) {
  case 'Q':
  case 'q':
    GLUTStop();
    break;

  case 27: // ESCAPE
    GLUTStop();
    break;
  }

  // Remember mouse position
  GLUTmouse[0] = x;
  GLUTmouse[1] = GLUTwindow_height - y;

  // Remember modifiers
  GLUTmodifiers = glutGetModifiers();
}

void GLUTInit(int *argc, char **argv)
{
  // Open window
  glutInit(argc, argv);
  glutInitWindowPosition(100, 100);
  glutInitWindowSize(GLUTwindow_width, GLUTwindow_height);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // | GLUT_STENCIL
  GLUTwindow = glutCreateWindow("OpenGL Viewer");

  // Initialize GLUT callback functions
  glutReshapeFunc(GLUTResize);
  glutDisplayFunc(GLUTRedraw);
  glutKeyboardFunc(GLUTKeyboard);
  glutSpecialFunc(GLUTSpecial);
  glutMouseFunc(GLUTMouse);
  glutMotionFunc(GLUTMotion);
  glutIdleFunc(0);

  // Initialize lights
  static GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
  static GLfloat light0_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
  glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
  glEnable(GL_LIGHT0);
  static GLfloat light1_diffuse[] = { 0.5, 0.5, 0.5, 1.0 };
  glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
  glEnable(GL_LIGHT1);
  glEnable(GL_NORMALIZE);
  glEnable(GL_LIGHTING);

  // Initialize graphics modes
  glEnable(GL_DEPTH_TEST);
}

void GLUTMainLoop(void)
{
  // Compute bounding box
  float bbox[2][3] = { { 1.0E30F, 1.0E30F, 1.0E30F }, { -1.0E30F, -1.0E30F, -1.0E30F } };
  for (int i = 0; i < mesh->nverts; i++) {
    Vertex& vert = mesh->verts[i];
    if (vert.x < bbox[0][0]) bbox[0][0] = vert.x;
    else if (vert.x > bbox[1][0]) bbox[1][0] = vert.x;
    if (vert.y < bbox[0][1]) bbox[0][1] = vert.y;
    else if (vert.y > bbox[1][1]) bbox[1][1] = vert.y;
    if (vert.z < bbox[0][2]) bbox[0][2] = vert.z;
    else if (vert.z > bbox[1][2]) bbox[1][2] = vert.z;
  }

  // Setup initial viewing scale
  float dx = bbox[1][0] - bbox[0][0];
  float dy = bbox[1][1] - bbox[0][1];
  float dz = bbox[1][2] - bbox[0][2];
  scale = 2.0 / sqrt(dx*dx + dy*dy + dz*dz);

  // Setup initial viewing center
  center[0] = 0.5 * (bbox[1][0] + bbox[0][0]);
  center[1] = 0.5 * (bbox[1][1] + bbox[0][1]);
  center[2] = 0.5 * (bbox[1][2] + bbox[0][2]);

  // Run main loop -- never returns
  glutMainLoop();
}

  

然后是程序参数
////////////////////////////////////////////////////////////
// PROGRAM ARGUMENT PARSING
////////////////////////////////////////////////////////////

int
ParseArgs(int argc, char **argv)
{
  // Innocent until proven guilty
  int print_usage = 0;

  // Parse arguments
  argc--; argv++;
  while (argc > 0) {
    if ((*argv)[0] == '-') {
      if (!strcmp(*argv, "-help")) { print_usage = 1; }
      else { fprintf(stderr, "Invalid program argument: %s", *argv); exit(1); }
      argv++; argc--;
    }
    else {
      if (!filename) filename = *argv;
      else { fprintf(stderr, "Invalid program argument: %s", *argv); exit(1); }
      argv++; argc--;
    }
  }

  // Check filename
  if (!filename || print_usage) {
    printf("Usage: offviewer <filename>\n");
    return 0;
  }

  // Return OK status
  return 1;
}

  

然后是main函数:
////////////////////////////////////////////////////////////
// MAIN
////////////////////////////////////////////////////////////

int
main(int argc, char **argv)
{
  // Initialize GLUT
  GLUTInit(&argc, argv);

  // Parse program arguments
  if (!ParseArgs(argc, argv)) exit(1);

  // Read file
  mesh = ReadOffFile(filename);
  if (!mesh) exit(1);

  // Run GLUT interface
  GLUTMainLoop();

  // Return success
  return 0;
}

实验截图:

以Bunny x.off为例:

off文件的数据为:

OFF
35923 71840 0
0.376693 0.313043 0.662166
0.370623 0.312993 0.661554
0.376698 0.304674 0.662131
0.382736 0.304669 0.661921
0.382742 0.313029 0.662116
0.376684 0.3213 0.66079
0.370691 0.304684 0.661884
0.376715 0.296271 0.661259
0.382727 0.321291 0.660709
0.388765 0.312958 0.661275
0.382748 0.29619 0.660595
0.388742 0.304615 0.661146
0.364677 0.3129 0.660455
0.364584 0.304566 0.660839
0.370703 0.296296 0.661091
0.370611 0.321297 0.660337
0.394831 0.312835 0.659867
0.388744 0.321222 0.660456
0.376732 0.28765 0.658428

。。。。。。。。。。。。。。

这个程序还有很多不懂的地方,还是c++基础薄弱啊!!!!!!!!!!!!1

操!!!!!!

以后要慢慢看,最近一大堆事,烦!  赶紧往下面学习吧!   ---------------2014.3.13 17:22

(4)用opengl读入off文件生成可执行文件把模型显示出来(未完待续)的更多相关文章

  1. Spring MVC-从零开始-文件上传(未完待续)

    Spring MVC-从零开始-文件上传(未完待续)

  2. js获取上传文件内容(未完待续)

    js 获取上传文件的字节数及内容 <div> 上传文件 : <input type="file" name = "file" id = &qu ...

  3. linux下 C++ 读取mat文件 MATLAB extern cyphon scipy 未完待续

    1.使用Matlab的C扩展,需要用户安装matlab. g++ -L/media/exsoftware/MATLAB/R2013b/bin/glnxa64 -Wl,-rpath,/media/exs ...

  4. gcc 编译 连接 生成可执行文件

    gcc c语言编译器 g++ c++编译器 gcc a.c  生成默认的a.out 可执行文件  ./a.out  来执行 gcc -c a.c 编译生成 a.o 目标文件 可以检查语法错误 gcc ...

  5. 1.预处理,生成预编译文件(.文件): Gcc –E hello.c –o hello.i 2.编译,生成汇编代码(.s文件): Gcc –S hello.i –o hello.s 3.汇编,生成目标文件(.o文件): Gcc –c hello.s –o hello.o 4.链接,生成可执行文件: linux笔记

    1 动态查看日志 tail -f filename tail -1000f filename 2 解压当前目录内容为xxx.zip  zip -r xxx.zip ./* 3 查看内存使用情况 fre ...

  6. labview生成可执行文件

    labview生成可执行文件可以分为两种情况. 第一种,是电脑中有labview软件开发环境的情况 第二种,是电脑中没有安装labview软件开发环境 下面是一个简单的labview代码: 程序解释: ...

  7. labview如何生成可执行文件

    labview生成可执行文件可以分为两种情况. 第一种,是电脑中有labview软件开发环境的情况 第二种,是电脑中没有安装labview软件开发环境 下面是一个简单的labview代码: 程序解释: ...

  8. python生成可执行文件保护源码

    工作中由于需要防止源代泄漏,需要将源代码隐藏,找到两种方法: 1.使用python生成的pyc文件. 这种方法的优点就是pyc文件生成很容易,缺点则是很容易通过工具得到源码,并且python版本不一致 ...

  9. ProtoBuffer由.proto文件生成.cc/.h

    ProtoBuffer由.proto文件生成.cc/.h 一:编译源码下载地址:http://code.google.com/p/protobuf/downloads/list 下载后,根据编译说明进 ...

随机推荐

  1. 实体框架 (EF) 入门 => 一、我该用哪个工作流?

    入门的参考资料:http://msdn.microsoft.com/zh-cn/data/ee712907 本篇的参考资料:http://msdn.microsoft.com/zh-cn/data/j ...

  2. pb中sql语句用to_char查询出来数据,居然无法检索出数据,oracle数据库,这是什么原因?

    /*这样dw_modified总是无法检索出正确的结果*/ ') into :is_recoder_old_sn from emra03 where szybh01 = :as_pat_id and ...

  3. [SSH服务]——一个SSH无密码登陆实验

    实验拓扑图 实验描述 机房内有两台服务器: (1)B服务器10.0.10.158,充当Web服务器,有普通用户user_00 (2)C服务器10.0.10.191,充当Mysql服务器,有普通用户us ...

  4. Android L Camera2 API 使用实例程序汇总

    在网上发现几个使用Camera API2开发的实例程序,总结一下方便后续参考: 1.Camera2 Basic : https://github.com/googlesamples/android-C ...

  5. heap size eclipse 堆内存

    可以根据eclipse 或 myeclipse heapstats 使用情况调整堆内存大小,heap size 设置,-vmargs-Xms256-Xmx1024 ,其中Xms表示初始值,Xmx表示最 ...

  6. 结队开发项目—NABC模型

    特点:可以避免食堂的用餐高峰,从而使使用者节约时间 need:很多学生中午下课在食堂吃饭会遭遇用餐高峰,使用这款软件,可以提前订饭,按时送达,从而避免食堂的用餐高峰期. approach:学生可以提前 ...

  7. Android开发随笔3

    昨天: 创建了工程hello world 了解了工程下的文件 对R.java和一些重要的文件有了了解 添加控件对layout文件夹下的文件有了了解 对apk的安装有所了解 对/data和/system ...

  8. 使用高德地图SDK获取定位信息

    使用高德地图SDK获取定位信息 第一步: 在高德官网下载SDK,如我这里需要获取定位信息,故仅下载"定位功能" 第二步: 注册成为开发者,并创建应用获取相应的key.其中,在使用A ...

  9. python代码风格指南:pep8 中文翻译

    摘要 本文给出主Python版本标准库的编码约定.CPython的C代码风格参见​PEP7.本文和​PEP 257 文档字符串标准改编自Guido最初的<Python Style Guide&g ...

  10. Linux 硬盘分区、分区、删除分区、格式化、挂载、卸载

    Linux 虽然一直都有在玩,但是对硬盘操作确实不是很熟悉今天有空,就整理了下. 1,创建分区 先查看下是否有磁盘没有分区 fdisk -l 其中第一个框和第二个框,是已经分好区的磁盘,第三个硬盘没有 ...