openGL加载obj文件+绘制大脑表层+高亮染色
Posted shulin~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
这里我们要修改两个内容:
- 删除改变位置的代码
- 改变缩放比例,各个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 }
现在我们要解决同时加载多个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;
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 }
现在我们要给加载的多个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 }
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 }
到此为止吗,我们就完成了openGL加载obj文件+绘制大脑表层+高亮染色。点击下载:openGLhighlight.zip
以上是关于openGL加载obj文件+绘制大脑表层+高亮染色的主要内容,如果未能解决你的问题,请参考以下文章
了解现代 OpenGL 中的代码绘制 .obj 并设置不同的位置