1. 程式人生 > >openGL加載obj文件+繪制大腦表層+高亮染色

openGL加載obj文件+繪制大腦表層+高亮染色

ear ces matrix swa clas cout initial 改變 model b

繪制大腦表層並高亮染色的工作是以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, \0, 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

openGL加載obj文件+繪制大腦表層+高亮染色