openGL加载obj文件+绘制大脑表层+高亮染色
绘制大脑表层并高亮染色的工作是以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文件+绘制大脑表层+高亮染色的更多相关文章
- OpenGL 加载DDS文件(压缩纹理)
想必很多人都见过DDS这种文件,它是一个“图片文件”,如果你安装了某些看图软件,你可以直接双击打开它来进行预览. 那么,这种DDS文件和我们常见的TGA/PNG之类的文件有何不同呢? DDS和TGA/ ...
- 如何使用Three.js加载obj和mtl文件
OBJ和MTL是3D模型的几何模型文件和材料文件. 在最新的three.js版本(r78)中,以前的OBJMTLLoader类已废弃. 现在要加载OBJ和MTL文件,需要结合OBJLoader和MTL ...
- QCustomplot使用分享(八) 绘制图表-加载cvs文件
目录 一.概述 二.效果图 三.源码讲解 1.源码结构 2.头文件 3.移动游标 4.设置坐标轴矩形个数 5.添加图表数据 6.设置折线图类型 6.其他函数 四.测试方式 1.测试工程 2.测试文件 ...
- c#两种方式调用google地球,调用COM API以及调用GEPLUGIN 与js交互,加载kml文件,dae文件。将二维高德地图覆盖到到三维谷歌地球表面。
网络上资源很多不全面,自己在开发的时候走了不少弯路,在这里整理了最全面的google全套开发,COM交互,web端交互.封装好了各种模块功能. 直接就可以调用. 第一种方式:调用COMAPI实现调用g ...
- 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间
[源码下载] 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间 作者:webabcd 介绍速战速决 之 PHP 动态地创 ...
- SharpDX之Direct2D教程II——加载位图文件和保存位图文件
本系列文章目录: SharpDX之Direct2D教程I——简单示例和Color(颜色) 绘制位图是绘制操作的不可缺少的一部分.在Direct2D中绘制位图,必须先利用WIC组件将位图加载到内存中,再 ...
- JVM加载class文件的原理
当Java编译器编译好.class文件之后,我们需要使用JVM来运行这个class文件.那么最开始的工作就是要把字节码从磁盘输入到内存中,这个过程我们叫做[加载 ].加载完成之后,我们就可以进行一系列 ...
- UNITY_资源路径与加载外部文件
UNITY_资源路径与加载外部文件 https://www.tuicool.com/articles/qMNnmm6https://blog.csdn.net/appppppen/article/de ...
- 自定义ClassLoader加载class文件
package com.yd.wmsc.util; public class Test { public void say(){ System.out.println("Say Hello& ...
随机推荐
- 生成HTML表格的后台模板代码
有时候,我们需要在后台拼接生成前端的html表格,一般的做法就是各种string.StringBuilder的拼接(例子省略...),这样的话如果表头不同就没法做到代码的重用,增加代码的冗余,下面我分 ...
- 关于 a 标签 jquery的trigger("click"),无法触发问题。
这个问题的原因不是jquery的trigger("click"), 函数的问题, 而是 a标签之间要有其他子标签,要对这个子标签调用trigger("click" ...
- AJPFX关于学习java遇到的问题:对算法和数据结构不熟悉
为什么我先拿“数据结构和算法”说事捏?这玩意是写程序最最基本的东东.不管你使用 Java 还是其它的什么语言,都离不开它.而且这玩意是跨语言的,学好之后不管在哪门语言中都能用得上. 既然“数据结构和算 ...
- poj2677 Tour
题意: 双调欧几里得旅行商问题. 思路: dp.定义dp[i][j](i <= j)为从点j从右向左严格按照x坐标递减顺序走到点1,之后再从点1从左向右严格按照x坐标递增的顺序走到点i,并且在此 ...
- TabLayout.Tab(自定义)点击事件
TabLayout是官方design包中的一个布局控件,这里不介绍它的基本使用,只是解决Tab(自定义)点击事件. //获取Tab的数量 Int tabCount = tabLayout.getTab ...
- 阻止JEB 1.5频繁弹窗的办法
偶尔才用一次的JEB, 出现 “Controller没有响应或者无法访问, JEB即将终止.” 也懒得去逆了.直接用ProcessHacker找到对应的线程挂起即可.当然这只是临时的办法..我也只是临 ...
- php中的define()函数
<?php define("PI",3.1415926); //定义常量 $r=12;//定义圆半径 echo "半径为12的单位的圆的面积".PI*($ ...
- qt 设置阴影 不显示黑色边框
this->setAttribute(Qt::WA_TranslucentBackground);
- upupw nginx服务器 rewrite设置
最近开始尝试使用upupw的Nginx套件做开发,感觉还挺不错的,也遇到了一些问题,决定在这里记录一下,同时也希望可以帮助到一些人. 用习惯了Apache,改用Nginx之后会有些不适应,但是咬咬牙就 ...
- PHP一句话后门过狗姿势万千之传输层加工
既然木马已就绪,那么想要利用木马,必然有一个数据传输的过程,数据提交是必须的,数据返回一般也会有的,除非执行特殊命令. 当我们用普通菜刀连接后门时,数据时如何提交的,狗狗又是如何识别的,下面结合一个实 ...