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& ...
随机推荐
- 第一章、 CLR的执行模型
1. 概述 本章主要是介绍从源代码到可执行程序的过程中,CLR所做的工作. 2. 名词解释 ① 公共语言运行时(Common Language Runtime, CLR),是一个可由多种语言使用的 运 ...
- CF782B The Meeting Place Cannot Be Changed
题意: The main road in Bytecity is a straight line from south to north. Conveniently, there are coordi ...
- Windows 2016 安装Sharepoint 2016 预装组件失败
Windows 2016 安装Sharepoint 2016 预装组件失败 日志如下: -- :: - Request for install time of Web 服务器(IIS)角色 -- :: ...
- iPhone4 offical AD
iPhone4 is so much more than just a new products.I mean this would have a lot of impact on the way i ...
- COGS 2111. [NOIP2015普及]扫雷游戏
★ 输入文件:2015mine.in 输出文件:2015mine.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] 扫雷游戏是一款十分经典的单机小游戏.在 n 行 ...
- Android(java)学习笔记176: 远程服务的应用场景(移动支付案例)
一. 移动支付: 用户需要在移动终端提交账号.密码以及金额等数据 到 远端服务器.然后远端服务器匹配这些信息,进行逻辑判断,进而完成交易,返回交易成功或失败的信息给移动终端.用户提交账号. ...
- 15分钟学会使用Git
http://blog.csdn.net/u013510614/article/details/50588446 主体思想 Git作为一个复杂的版本控制系统,命令之多,相信很多小白已经望而却步,有的尝 ...
- dropuser - 删除一个 PostgreSQL 用户帐户
SYNOPSIS dropuser [ option...] [ username] DESCRIPTION 描述 dropuser 删除一个现有 PostgreSQL 用户 和 该用户所有的数据库. ...
- const函数的使用
const知道吗?解释其作用. 1.const 修饰类的成员变量,表示成员常量,不能被修改. 2.const修饰函数承诺在本函数内部不会修改类内的数据成员,不会调用其它非 const 成员函数. 3. ...
- Android studio Github 断开连接
http://blog.csdn.net/agoodcoolman/article/details/50562301 使用软件:Android studio svn:Github 从github直接从 ...