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 }

现在我们要解决同时加载多个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 }

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 }

 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

时间: 2024-10-17 17:34:50

openGL加载obj文件+绘制大脑表层+高亮染色的相关文章

OpenGL 加载DDS文件(压缩纹理)

想必很多人都见过DDS这种文件,它是一个"图片文件",如果你安装了某些看图软件,你可以直接双击打开它来进行预览. 那么,这种DDS文件和我们常见的TGA/PNG之类的文件有何不同呢? DDS和TGA/PNG/JPG之类的"图片文件" 一样,支持"压缩",减少磁盘空间占用(把文件变小). 通常我们要加载一个TGA或者PNG文件到OpenGL的时候,都要先把文件数据还原成RGB格式的像素数据,然后用glTexImage2D把像素数据传到显存.这个过程

OpenGL学习脚印:模型加载初步-加载obj模型(load obj model)

写在前面 前面介绍了光照基础内容,以及材质和lighting maps,和光源类型,我们对使用光照增强场景真实感有了一定了解.但是到目前为止,我们通过在程序中指定的立方体数据,绘制立方体,看起来还是很乏味.本节开始介绍模型加载,通过加载丰富的模型,能够丰富我们的场景,变得好玩.本节的示例代码均可以在我的github下载. 加载模型可以使用比较好的库,例如obj模型加载的库,Assimp加载库.本节作为入门篇,我们一开始不使用这些库加载很酷的模型,而是熟悉下模型以及模型加载的概念,然后我们封装一个

JVM加载class文件的原理

当Java编译器编译好.class文件之后,我们需要使用JVM来运行这个class文件.那么最开始的工作就是要把字节码从磁盘输入到内存中,这个过程我们叫做[加载 ].加载完成之后,我们就可以进行一系列的运行前准备工作了,比如: 为类静态变量开辟空间,将常量池存放在方法区内存中并实现常量池地址解析,初始化类静态变量等等.这篇文章我们要好好谈谈JVM是如何加载class文件的? 1.JVM加载类的过程       当我们使用命令来执行某一个Java程序(比如Test.class)的时候:java T

PHP 中加载类文件的几种方法

PHP 中加载类文件,常用require语句或者include语句.二者的区别是:require语句包含的文件如果有语法错误或者不存在该文件,则会提示错误"fatal error",并且终止程序运行:include语句在同样的情况下,则是提示警告"warning",并且程序继续运行. PHP 加载类文件还可以用require_once或者include_once,他们与require语句或者include语句的区别在于:包含文件时会检查是否已有同样的文件被包含,若是

利用DexClassLoader动态加载dex文件

Java中也有类加载器ClassLoader,其作用是动态装载Class文件,当我们从网络下载Class文件,或者在编译时不参与而在运行时动态调用时就需要用类加载器.由于Android对class文件进行了重新打包和优化,最终APK文件中包含的是dex文件,加载这种文件就需要用到DexClassLoader. DexClassLoader(dexPath, optimizedDirectory, libraryPath, parent) dexPath:目标类所在的APK或者jar包,/.../

Spring boot 国际化自动加载资源文件问题

Spring boot 国际化自动加载资源文件问题 最近在做基于Spring boot配置的项目.中间遇到一个国际化资源加载的问题,正常来说只要在application.properties文件中定义正确的资源文件路径,Spring boot就启动时就会自动加载资源. spring.messages.basename=i18n/message 但是我的项目修改后获取消息时系统报错,找不到对应语言的资源配置.于是试图找到原因.Google好久都没找到,简直好像就我一个人遇到这鬼问题一样??.只好自

实现异步加载js文件及加载完成后回调

模块化工具类实现方式 基于AMD.CMD模式的JS模块化管理工具越来越流行,这些工具通常只需在页面中加载对应的工具JS,其他JS文件都是异步加载的,比如RequireJS就可以象下面这样做. 首先在页面加载 <script data-main="scripts/main.js" src="scripts/require.js"></script> 然后工具会自动识别data-main属性值,并加载对应的JS文件,在main.js可以加载更多模

加载nib文件的过程

当加载nib文件时,存储在nib文件中的任何对象都会被重新创建.这意味着会在后台执行alloc和init方法.所以,当应用程序启动时,会分配并初始化一个AppController实例.在执行init方法期间,所有IBOutlet实例变量都为nil.只有创建了nib文件中的所有对象,所有连接才算完成. 一旦建立了所有连接,会向创建的每个对象发送消息awakeFromNib.一个非常常见的错误是试图在init方法中使用IBoutlet执行一些操作.由于所有实例变量都为nil,发送给他们的所有消息不执

Android动态加载XML文件及控件来简单实现QQ好友印象的功能

在android开发中,我们常常会遇到界面布局控件不确定的情况.由于某些功能的原因或者为了体现某些app的特色等这些原因会导致我们在实现界面布局时需要动态去加载一些控件,那么下面就来介绍一下如何用动态加载控件来简单实现QQ中好友印象的功能,其中也会提到如何来动态加载一个XML的配置文件. 那么要实现好友印象的功能,我们需要通过以下这几个步骤: 1.界面一开始需要加载一个EditText和Button控件,用于填写好友印象和添加好友印象: 2.需要新建一个arrays.xml,在xml文件中添加上