手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>程序设计>C/C++>列表

VC .NETOpenGL编程快速入门

来源:互联网 作者:西部数码 时间:2008-04-09
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

static float fRadius = 0;
fRadius = 0.01f;
if ( fRadius > M_PI * 2 )
{
 fRadius = 0;
}
gluLookAt( cosf( fRadius ) * 30, sinf( fRadius ) * 30, 15.0,
 0.0, 0.0, 0.0,
 0.0, 0.0, 1.0 );
}

void SetProjMatrix( WORD wWidth, WORD wHeight )
{
glViewport( 0, 0, wWidth, wHeight );
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );
gluPerspective( 45.0, (double)wWidth / (double)wHeight, 1.0, 1000.0 );
}

void OnIdle( void )
{
SetModalMatrix();
OnDraw();
}
  现在程序可以运行了,告诉我你看到了什么?应该是一个旋转的平面四边形。你什么也没有看到?请仔细复查你上面写的程序,看是不是每一句都和我一样。如果你仍然得不到解决,可以发短消息给我来争取获得帮助的机会。但请注意,我并不会对每一个愚蠢的问题都做出答复,比如请不要问我为什么你的窗体创建不出来或VC.net在哪里下载。
  当然,刚才说过我们是要绘制一个立方盒,我当然没有忘记,只是在这之前想让更多的读者熟悉一下OpenGL的绘图机制。其它方盒很简单,我们应该有这样一组数据,并把它做为全局变量。每个顶点用X、Y、Z三维short值来表示,一个八个顶点,你可以跟据这些数据在纸上手画一个正方体出来吗?

short nSrcBox[ 3 * 8 ] = {
 5, 5, 0,  5, 5, 10,
 5,-5, 0,  5, -5, 10,
 -5,-5,0,  -5, -5, 10,
 -5, 5, 0, -5, 5, 10,
};

  在绘制时我们可以一个三角形一个三角形的画,也可以像上一个例子一样,一个四边形一个四边形的画,但为了后面我们要讲述的一些东东,先看三角形画吧。每一个面由两个三角形组成,一共六个面,十二个三角形。如果给上面的八个顶点编号为0-7,那么我们可以按照这样的顺序来画:

0, 4, 6, 0, 2, 4, 0, 6, 7, 0, 7, 1, 0, 3, 2, 0, 1, 3, 5, 2, 3, 5, 4, 2, 5, 6, 4, 5, 7, 6,  5, 1, 7, 5, 3, 1,

  这里需要注意的是右手定则,在OpenGL中按照绘制一个三角形三维顶点的顺序,用右手正正握这个三角形,大姆指竖起的方向就是这个面的正方向。其实你已经在不知不觉中了解了什么是索引数组,就是上面那一堆数字,我们把他们保存起来,做为全局变量:

BYTE byIndex[36] ={
0, 4, 6, 0, 2, 4,
0, 6, 7, 0, 7, 1,
0, 3, 2, 0, 1, 3,
5, 2, 3, 5, 4, 2,
5, 6, 4, 5, 7, 6,
5, 1, 7, 5, 3, 1,
};

  好了,现在是万事具体只欠东风了,怎么画呢?也许你会想到和上面的程序一样调用一个个的glVertex来绘制这些顶点,是的,你是正确的,但这样太慢而且太复杂了,算算你一共要写多少个glVertex呢?幸好OpenGL为我们提供了一个方便绘图机制:数组绘制。在初始化代码的最下面加上这样的语句来指定顶点数组:

glEnableClientState( GL_VERTEX_ARRAY ); // 启用顶点数组
glVertexPointer( 3, GL_SHORT, 0, nSrcBox ); // 设置顶点数组地址
  然后在OnDraw的Clear和Swap之间加上这一句话就足够了:

// 后两个参数指定索引数组值的类型和数组地址
glDrawElements( GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, byIndex );
  你应该可以看到一个旋转的立方体了,但它仍然是混沌一片,看不清棱角,这是由于你没有指定光线反射的方向,下面我们将再引入一个概念“法向量”。在现实生活中,人眼看到物体是由于物体对光线的反射,如果物体不反射光,或着不向人的眼睛方向反射,人眼将认为这个物体是没有光照的。先不说漫反射,每一个镜面反射的物体的入射角和射出角都是相等的,因而镜面反射物体的法向量因该是垂直于平面的。由于光的粒子性,漫反射物体我们可以认为是由无限多个镜面反射物体所组成的一种复杂物体。根据这些理论,OpenGL在绘制三维物体时将按照给定的顶点法向量值来计算这个面的明暗亮度。计算法向量要用到一个数学基础知识,可能对于一些人来说有些晦涩难懂,不过没有关系,这里有现成的函数,你直接调用就可以计算了:

// 归一化函数,没什么可说的
template <typename Type>
HRESULT ReduceToUnit( Type *pVector )
{
double dLength = sqrt( (double)pVector[0] * (double)pVector[0]
 (double)pVector[1] * (double)pVector[1]
 (double)pVector[2] * (double)pVector[2] );

if ( FLOATEQUAL( dLength, 0.0, 1e-8 ) )
{
 dLength = 1.0;
}
pVector[0] /= (Type)dLength;
pVector[1] /= (Type)dLength;
pVector[2] /= (Type)dLength;
return S_OK;
}

// 第一个参数用9个double表示一个三角型,三角型的法向量将由第二个参数传出。
template <typename T1, typename T2>
HRESULT CalcNormal( const T1 *pVertical, T2 *pNormal )
{
T1 d1[3], d2[3];
d1[0] = pVertical[0] - pVertical[3];
d1[1] = pVertical[1] - pVertical[4];
d1[2] = pVertical[2] - pVertical[5];
d2[0] = pVertical[3] - pVertical[6];
d2[1] = pVertical[4] - pVertical[7];
d2[2] = pVertical[5] - pVertical[8];
pNormal[0] = (T2)( d1[1] * d2[2] - d1[2] * d2[1] );
pNormal[1] = (T2)( d1[2] * d2[0] - d1[0] * d2[2] );
pNormal[2] = (T2)( d1[0] * d2[1] - d1[1] * d2[0] );
return ReduceToUnit( pNormal );
}
  问题又出现了,一个顶点可以属于不同的面,但是法向量确只有一个,给个顶点赋任何一个面的法向量都将导致显示不正常,那么我们该怎么办呢?只好按照索引将这些顶点“拆开”。

for ( int i = 0; i < 36; i )
{
// nTempBox是一个临时数组变量,用于保存拆开后的数据。
MoveMemory( &nTempBox[ i * 3 ], &nSrcBox[ byIndex[i] * 3 ], sizeof(nTempBox[0]) * 3 );

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

热点关注
IDC资讯 虚拟主机 域名注册 托管租用 vps主机 智能建站
网站运营 建站经验 策划盈利 搜索优化 网站推广 免费资源
网站联盟 联盟新闻 联盟介绍 联盟点评 网赚技巧
行业资讯 业界动态 搜索引擎 网络游戏 门户动态 电子商务 广告传媒
网络编程 Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术 Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷 Internet Explorer
网页制作 FrontPages Dreamweaver Javascript css photoshop fireworks Flash
程序设计 Java技术 C/C++ VB delphi
网络知识 网络协议 网络安全 网络管理 组网方案 Cisco技术
操作系统 Win2000 WinXP Win2003 Mac OS Linux FreeBSD
返回首页 |关于我们 | 联系我们 | 付款方式 | 创业联盟 | 价格总览 | 资讯中心 | 友情链接 | 网站地图 | 招贤纳士 | RSS