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

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

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

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

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

 /* public functions */

 /* glmUnitize: "unitize" a model by translating it to the origin and
* scaling it to fit in a unit cube around the origin. Returns the
* scalefactor used.
*
* model - properly initialized GLMmodel structure
*/
GLfloat
glmUnitize(GLMmodel* model, GLfloat center[3])
{
GLuint i;
GLfloat maxx, minx, maxy, miny, maxz, minz;
GLfloat cx, cy, cz, w, h, d;
GLfloat scale; assert(model);
assert(model->vertices); /* get the max/mins */
maxx = minx = model->vertices[3 + X];
maxy = miny = model->vertices[3 + Y];
maxz = minz = model->vertices[3 + Z];
for (i = 1; i <= model->numvertices; i++) {
if (maxx < model->vertices[3 * i + X])
maxx = model->vertices[3 * i + X];
if (minx > model->vertices[3 * i + X])
minx = model->vertices[3 * i + X]; if (maxy < model->vertices[3 * i + Y])
maxy = model->vertices[3 * i + Y];
if (miny > model->vertices[3 * i + Y])
miny = model->vertices[3 * i + Y]; if (maxz < model->vertices[3 * i + Z])
maxz = model->vertices[3 * i + Z];
if (minz > model->vertices[3 * i + Z])
minz = model->vertices[3 * i + Z];
} /* calculate model width, height, and depth */
w = _glmAbs(maxx) + _glmAbs(minx);
h = _glmAbs(maxy) + _glmAbs(miny);
d = _glmAbs(maxz) + _glmAbs(minz); /* calculate center of the model */
cx = (maxx + minx) / 2.0;
cy = (maxy + miny) / 2.0;
cz = (maxz + minz) / 2.0; /* calculate unitizing scale factor */
scale = 2.0 / _glmMax(_glmMax(w, h), d); /* translate around center then scale */
for (i = 1; i <= model->numvertices; i++) {
model->vertices[3 * i + X] -= cx;
model->vertices[3 * i + Y] -= cy;
model->vertices[3 * i + Z] -= cz;
model->vertices[3 * i + X] *= scale;
model->vertices[3 * i + Y] *= scale;
model->vertices[3 * i + Z] *= scale;
} center[0] = cx;
center[1] = cy;
center[2] = cz;
return scale;
}

glmUnitize

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

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

这是修改后的代码:

 /* public functions */

 /* glmUnitize: "unitize" a model by translating it to the origin and
* scaling it to fit in a unit cube around the origin. Returns the
* scalefactor used.
*
* model - properly initialized GLMmodel structure
*/
GLfloat
glmUnitize(GLMmodel* model, GLfloat center[])
{
GLuint i;
GLfloat maxx, minx, maxy, miny, maxz, minz;
GLfloat cx, cy, cz, w, h, d;
GLfloat scale; assert(model);
assert(model->vertices); /* get the max/mins */
maxx = minx = model->vertices[ + X];
maxy = miny = model->vertices[ + Y];
maxz = minz = model->vertices[ + Z];
for (i = ; i <= model->numvertices; i++) {
if (maxx < model->vertices[ * i + X])
maxx = model->vertices[ * i + X];
if (minx > model->vertices[ * i + X])
minx = model->vertices[ * i + X]; if (maxy < model->vertices[ * i + Y])
maxy = model->vertices[ * i + Y];
if (miny > model->vertices[ * i + Y])
miny = model->vertices[ * i + Y]; if (maxz < model->vertices[ * i + Z])
maxz = model->vertices[ * i + Z];
if (minz > model->vertices[ * i + Z])
minz = model->vertices[ * i + Z];
} /* calculate model width, height, and depth */
w = _glmAbs(maxx) + _glmAbs(minx);
h = _glmAbs(maxy) + _glmAbs(miny);
d = _glmAbs(maxz) + _glmAbs(minz); /* calculate center of the model */
cx = (maxx + minx) / 2.0;
cy = (maxy + miny) / 2.0;
cz = (maxz + minz) / 2.0; /* calculate unitizing scale factor */
//scale = 2.0 / _glmMax(_glmMax(w, h), d);
scale = 0.01;
/* translate around center then scale */
for (i = ; i <= model->numvertices; i++) {
/* model->vertices[3 * i + X] -= cx;
model->vertices[3 * i + Y] -= cy;
model->vertices[3 * i + Z] -= cz;*/
model->vertices[ * i + X] *= scale;
model->vertices[ * i + Y] *= scale;
model->vertices[ * i + Z] *= scale;
} center[] = cx;
center[] = cy;
center[] = cz;
return scale;
}

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

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

核心代码如下:

                 case 'o':
case 'O':
{
string path="C:\\test";
_finddata_t file_info;
string current_path = path + "/*.obj";
int handle = _findfirst(current_path.c_str(), &file_info);
do
{ string rt = "C:\\test\\";
string fn= rt + file_info.name;
memset(FileName, '\0', sizeof(FileName));
for (int i = ; i < fn.length(); i++)
{
FileName[i] = fn[i];
}
if (pModel[cnt] == NULL)
{
pModel[cnt] = glmReadOBJ(FileName);
// Generate normal for the model
glmFacetNormals(pModel[cnt]);
// Scale the model to fit the screen
glmUnitize(pModel[cnt], modelCenter);
// Init the modelview matrix as an identity matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glGetDoublev(GL_MODELVIEW_MATRIX, pModelViewMatrix);
cnt++;
// break;
} } while (!_findnext(handle, &file_info)); _findclose(handle);
} break;
 void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated( 0.0, 0.0, -5.0 );
glMultMatrixd( pModelViewMatrix );
for (int i = ; i < cnt; i++)
{
if (pModel[i] != NULL)
{
glmDraw(pModel[i], GLM_FLAT);
}
}
glutSwapBuffers();
}

Display

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

 void Color()
{
srand(unsigned(time()));
for (int i = ; i < maxn; i++)
{ rr[i] = random(0.0, 0.7);
gg[i] = random(0.0, 0.7);
bb[i] = random(0.0, 0.7);
cout << rr[i] << " " << gg[i] << " " << bb[i] << endl;
}
}
 /// Display the Object
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glTranslated( 0.0, 0.0, -5.0 );
glMultMatrixd( pModelViewMatrix ); glEnable(GL_COLOR_MATERIAL);
//glColorMaterial(GL_FRONT, GL_DIFFUSE); for (int i = ; i < cnt; i++)
{
if (pModel[i] != NULL)
{
glColor3f(rr[i],gg[i],bb[i]);
glmDraw(pModel[i], GLM_FLAT|GLM_COLOR);
}
}
glDisable(GL_COLOR_MATERIAL);
glutSwapBuffers();
}

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

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

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

    想必很多人都见过DDS这种文件,它是一个“图片文件”,如果你安装了某些看图软件,你可以直接双击打开它来进行预览. 那么,这种DDS文件和我们常见的TGA/PNG之类的文件有何不同呢? DDS和TGA/ ...

  2. 如何使用Three.js加载obj和mtl文件

    OBJ和MTL是3D模型的几何模型文件和材料文件. 在最新的three.js版本(r78)中,以前的OBJMTLLoader类已废弃. 现在要加载OBJ和MTL文件,需要结合OBJLoader和MTL ...

  3. QCustomplot使用分享(八) 绘制图表-加载cvs文件

    目录 一.概述 二.效果图 三.源码讲解 1.源码结构 2.头文件 3.移动游标 4.设置坐标轴矩形个数 5.添加图表数据 6.设置折线图类型 6.其他函数 四.测试方式 1.测试工程 2.测试文件 ...

  4. c#两种方式调用google地球,调用COM API以及调用GEPLUGIN 与js交互,加载kml文件,dae文件。将二维高德地图覆盖到到三维谷歌地球表面。

    网络上资源很多不全面,自己在开发的时候走了不少弯路,在这里整理了最全面的google全套开发,COM交互,web端交互.封装好了各种模块功能. 直接就可以调用. 第一种方式:调用COMAPI实现调用g ...

  5. 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间

    [源码下载] 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间 作者:webabcd 介绍速战速决 之 PHP 动态地创 ...

  6. SharpDX之Direct2D教程II——加载位图文件和保存位图文件

    本系列文章目录: SharpDX之Direct2D教程I——简单示例和Color(颜色) 绘制位图是绘制操作的不可缺少的一部分.在Direct2D中绘制位图,必须先利用WIC组件将位图加载到内存中,再 ...

  7. JVM加载class文件的原理

    当Java编译器编译好.class文件之后,我们需要使用JVM来运行这个class文件.那么最开始的工作就是要把字节码从磁盘输入到内存中,这个过程我们叫做[加载 ].加载完成之后,我们就可以进行一系列 ...

  8. UNITY_资源路径与加载外部文件

    UNITY_资源路径与加载外部文件 https://www.tuicool.com/articles/qMNnmm6https://blog.csdn.net/appppppen/article/de ...

  9. 自定义ClassLoader加载class文件

    package com.yd.wmsc.util; public class Test { public void say(){ System.out.println("Say Hello& ...

随机推荐

  1. Ionic开发-如何在ion-content形成上下结构 上面固定下层可滚动

    在一个系统设计中,一般有些需要固定位置,便利操作.现在我要做一个上下两层,需要固定上方,下方拉刷新数据. 页面: <ion-content scroll="false"> ...

  2. 【学习笔记】深入理解js原型和闭包(7)——原型的灵活性

    在Java和C#中,你可以简单的理解class是一个模子,对象就是被这个模子压出来的一批一批月饼(中秋节刚过完).压个啥样,就得是个啥样,不能随便动,动一动就坏了. 而在javascript中,就没有 ...

  3. Java入门小知识

    软件开发什么是软件?  一系列按照特定顺序组织的计算机数据和指令的集合什么是开发?  制作软件 人机交互  软件的出现实现了人与计算机之间的更好的交互交互方式   图形化界面:这种方式简单直观,使用者 ...

  4. 原生js的容易忽略的相似点(二)

    1.new Object 和字面量 {}测试; <script type="text/javascript"> //1.new出来对象 console.log(obj, ...

  5. 洛谷 P2580 于是他错误的点名开始了

    题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人. 他会一边搓炉石一边点名以至于有一天他连续点到了某个同学两次,然后正好被路过的校长发现了然后就是一顿欧拉欧拉欧拉(详情请见已结束比赛CON900). ...

  6. SQLite – HAVING 子句

    SQLite – HAVING子句 HAVING使您能够指定过滤条件哪一组结果出现在最终的结果. WHERE子句的地方条件选定的列, 在有HAVING 子句的地方 就有GROUP BY子句包含的条件组 ...

  7. mysql 增删查改

    非关系型数据库关系型数据库Oracle mysql sqlserver db2 Postgresql Sqlite access sqlserver 微软db2 ibm================ ...

  8. docker 新手入门(docker的安装)

    docker的安装(在centos7下面) 1. 卸载在liunx下,先看有没有安装docker,docker version,如果有的话,可以先移除 yum remove ........ 可以使用 ...

  9. zipkin 服务追踪

    服务追踪,就是对请求接口的追踪并保存. 在测试的过程中我们会发现,有时候,程序刚刚启动后,刷新几次,并不能看到任何数据,原因就是我们的spring-cloud-sleuth收集信息是有一定的比率的,默 ...

  10. echo - 显示一行文本

    SYNOPSIS(总览) echo[OPTION]... [STRING]... DESCRIPTION(描述) 允许在标准输出上显示STRING(s). -n 不输出行尾的换行符. -e 允许对下面 ...