zoukankan      html  css  js  c++  java
  • openGL加载obj文件+绘制大脑表层+高亮染色

    绘制大脑表层并高亮染色的工作是以openGL加载obj文件为基础的,这里是我们用到的原始程序:只能加载一个obj文件的demo

    然而,一个完整的大脑表层是由很多分区组成的,因此我们的程序需要支持两个功能:

    • 同时加载多个obj文件。
    • 每个大脑分区obj文件保持其相对位置。

    明白了需求后,我们就可以开始修改代码了~

    glmUnitize函数的作用是单位化,也就是把模型通过平移和缩放变换限制到3维坐标系中点为中心的一个单位正方体区域内。所以控制obj显示位置是在glmUnitize()函数中,源代码如下:

     1 /* public functions */
     2 
     3 /* glmUnitize: "unitize" a model by translating it to the origin and
     4  * scaling it to fit in a unit cube around the origin.  Returns the
     5  * scalefactor used.
     6  *
     7  * model - properly initialized GLMmodel structure 
     8  */
     9   GLfloat
    10 glmUnitize(GLMmodel* model, GLfloat center[3])
    11 {
    12   GLuint  i;
    13   GLfloat maxx, minx, maxy, miny, maxz, minz;
    14   GLfloat cx, cy, cz, w, h, d;
    15   GLfloat scale;
    16 
    17   assert(model);
    18   assert(model->vertices);
    19 
    20   /* get the max/mins */
    21   maxx = minx = model->vertices[3 + X];
    22   maxy = miny = model->vertices[3 + Y];
    23   maxz = minz = model->vertices[3 + Z];
    24   for (i = 1; i <= model->numvertices; i++) {
    25     if (maxx < model->vertices[3 * i + X])
    26       maxx = model->vertices[3 * i + X];
    27     if (minx > model->vertices[3 * i + X])
    28       minx = model->vertices[3 * i + X];
    29 
    30     if (maxy < model->vertices[3 * i + Y])
    31       maxy = model->vertices[3 * i + Y];
    32     if (miny > model->vertices[3 * i + Y])
    33       miny = model->vertices[3 * i + Y];
    34 
    35     if (maxz < model->vertices[3 * i + Z])
    36       maxz = model->vertices[3 * i + Z];
    37     if (minz > model->vertices[3 * i + Z])
    38       minz = model->vertices[3 * i + Z];
    39   }
    40 
    41   /* calculate model width, height, and depth */
    42   w = _glmAbs(maxx) + _glmAbs(minx);
    43   h = _glmAbs(maxy) + _glmAbs(miny);
    44   d = _glmAbs(maxz) + _glmAbs(minz);
    45 
    46   /* calculate center of the model */
    47   cx = (maxx + minx) / 2.0;
    48   cy = (maxy + miny) / 2.0;
    49   cz = (maxz + minz) / 2.0;
    50 
    51   /* calculate unitizing scale factor */
    52   scale = 2.0 / _glmMax(_glmMax(w, h), d);
    53 
    54   /* translate around center then scale */
    55   for (i = 1; i <= model->numvertices; i++) {
    56     model->vertices[3 * i + X] -= cx;
    57     model->vertices[3 * i + Y] -= cy;
    58     model->vertices[3 * i + Z] -= cz;
    59     model->vertices[3 * i + X] *= scale;
    60     model->vertices[3 * i + Y] *= scale;
    61     model->vertices[3 * i + Z] *= scale;
    62   }
    63 
    64   center[0] = cx;
    65   center[1] = cy;
    66   center[2] = cz;
    67   return scale;
    68 }
    glmUnitize

    这里我们要修改两个内容:

    • 删除改变位置的代码
    • 改变缩放比例,各个obj文件的缩放因子需要保持一致。

    这是修改后的代码:

     1 /* public functions */
     2 
     3 /* glmUnitize: "unitize" a model by translating it to the origin and
     4  * scaling it to fit in a unit cube around the origin.  Returns the
     5  * scalefactor used.
     6  *
     7  * model - properly initialized GLMmodel structure 
     8  */
     9   GLfloat
    10 glmUnitize(GLMmodel* model, GLfloat center[3])
    11 {
    12   GLuint  i;
    13   GLfloat maxx, minx, maxy, miny, maxz, minz;
    14   GLfloat cx, cy, cz, w, h, d;
    15   GLfloat scale;
    16 
    17   assert(model);
    18   assert(model->vertices);
    19 
    20   /* get the max/mins */
    21   maxx = minx = model->vertices[3 + X];
    22   maxy = miny = model->vertices[3 + Y];
    23   maxz = minz = model->vertices[3 + Z];
    24   for (i = 1; i <= model->numvertices; i++) {
    25     if (maxx < model->vertices[3 * i + X])
    26       maxx = model->vertices[3 * i + X];
    27     if (minx > model->vertices[3 * i + X])
    28       minx = model->vertices[3 * i + X];
    29 
    30     if (maxy < model->vertices[3 * i + Y])
    31       maxy = model->vertices[3 * i + Y];
    32     if (miny > model->vertices[3 * i + Y])
    33       miny = model->vertices[3 * i + Y];
    34 
    35     if (maxz < model->vertices[3 * i + Z])
    36       maxz = model->vertices[3 * i + Z];
    37     if (minz > model->vertices[3 * i + Z])
    38       minz = model->vertices[3 * i + Z];
    39   }
    40 
    41   /* calculate model width, height, and depth */
    42   w = _glmAbs(maxx) + _glmAbs(minx);
    43   h = _glmAbs(maxy) + _glmAbs(miny);
    44   d = _glmAbs(maxz) + _glmAbs(minz);
    45 
    46   /* calculate center of the model */
    47   cx = (maxx + minx) / 2.0;
    48   cy = (maxy + miny) / 2.0;
    49   cz = (maxz + minz) / 2.0;
    50 
    51   /* calculate unitizing scale factor */
    52   //scale = 2.0 / _glmMax(_glmMax(w, h), d);
    53   scale = 0.01;
    54   /* translate around center then scale */
    55   for (i = 1; i <= model->numvertices; i++) {
    56    /* model->vertices[3 * i + X] -= cx;
    57     model->vertices[3 * i + Y] -= cy;
    58     model->vertices[3 * i + Z] -= cz;*/
    59     model->vertices[3 * i + X] *= scale;
    60     model->vertices[3 * i + Y] *= scale;
    61     model->vertices[3 * i + Z] *= scale;
    62   }
    63 
    64   center[0] = cx;
    65   center[1] = cy;
    66   center[2] = cz;
    67   return scale;
    68 }
    View Code

    现在我们要解决同时加载多个obj文件的问题。

    • pModel改为pModel数组,全局变量cnt记录当前加载到哪个obj文件。
    • 遍历obj文件夹下的所有obj文件,并依次加载。

     核心代码如下:

     1                 case 'o':
     2         case 'O':
     3         {
     4             string path="C:\test";
     5             _finddata_t file_info;
     6             string current_path = path + "/*.obj";
     7             int handle = _findfirst(current_path.c_str(), &file_info);
     8             do
     9             {
    10                 
    11                 string rt = "C:\test\";
    12                 string fn= rt + file_info.name;
    13                 memset(FileName, '', sizeof(FileName));
    14                 for (int i = 0; i < fn.length(); i++)
    15                 {
    16                     FileName[i] = fn[i];
    17                 }
    18                 if (pModel[cnt] == NULL)
    19                 {
    20                     pModel[cnt] = glmReadOBJ(FileName);
    21                     // Generate normal for the model
    22                     glmFacetNormals(pModel[cnt]);
    23                     // Scale the model to fit the screen
    24                     glmUnitize(pModel[cnt], modelCenter);
    25                     // Init the modelview matrix as an identity matrix
    26                     glMatrixMode(GL_MODELVIEW);
    27                     glLoadIdentity();
    28                     glGetDoublev(GL_MODELVIEW_MATRIX, pModelViewMatrix);
    29                     cnt++;
    30                 //    break;
    31                 }
    32 
    33             } while (!_findnext(handle, &file_info));
    34 
    35             _findclose(handle);
    36         }
    37 
    38         break;
    View Code
     1 void display()
     2 {
     3     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
     4     glMatrixMode(GL_MODELVIEW);
     5     glLoadIdentity();
     6     glTranslated( 0.0, 0.0, -5.0 );
     7     glMultMatrixd( pModelViewMatrix );
     8     for (int i = 0; i < cnt; i++)
     9     {
    10         if (pModel[i] != NULL)
    11         {
    12             glmDraw(pModel[i], GLM_FLAT);
    13         }
    14     }
    15     glutSwapBuffers();
    16 }
    Display

    现在我们要给加载的多个obj文件随机染色。

     1 void Color()
     2 {
     3     srand(unsigned(time(0)));
     4     for (int i = 0; i < maxn; i++)
     5     {
     6         
     7         rr[i] = random(0.0, 0.7);
     8         gg[i] = random(0.0, 0.7);
     9         bb[i] = random(0.0, 0.7);
    10         cout << rr[i] << " " << gg[i] << " " << bb[i] << endl;
    11     }
    12 }
    View Code
     1 /// Display the Object
     2 void display()
     3 {
     4     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
     5     
     6     glMatrixMode(GL_MODELVIEW);
     7     glLoadIdentity();
     8 
     9     glTranslated( 0.0, 0.0, -5.0 );
    10     glMultMatrixd( pModelViewMatrix );
    11     
    12     glEnable(GL_COLOR_MATERIAL);
    13     //glColorMaterial(GL_FRONT, GL_DIFFUSE);
    14     
    15     for (int i = 0; i < cnt; i++)
    16     {
    17         if (pModel[i] != NULL)
    18         {
    19             glColor3f(rr[i],gg[i],bb[i]);
    20             glmDraw(pModel[i], GLM_FLAT|GLM_COLOR);
    21         }
    22     }
    23     glDisable(GL_COLOR_MATERIAL); 
    24     glutSwapBuffers();
    25 }
    View Code

    到此为止吗,我们就完成了openGL加载obj文件+绘制大脑表层+高亮染色。点击下载:openGLhighlight.zip

  • 相关阅读:
    vue this,$set方法
    表格的拖拽排序功能---应用splice方法
    ES6方法的特性总结
    template functional
    scrollTop, offsetTop, pageYOffset, scrollY 的区别
    Sass @mixin 与 @include
    关于Vue中props的详解
    前端开发工具宝典
    前端js开发常用的60种工具方法
    element ui table表格里面插槽的使用方法
  • 原文地址:https://www.cnblogs.com/itcsl/p/6838156.html
Copyright © 2011-2022 走看看