Win32 OpenGL编程(6) 踏入3D世界
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
讨论新闻组及文件
提要
OpenGL本身就是为高性能3D图像处理而设计的,也多用于虚拟现实(VR),3D游戏等领域,本节正式开始接触3D领域,不再在2D的小世界中混了。(其实2D也是很大的领域了,当年不都是2D嘛?-_-!)本文主要以三角锥为例,从绘制一个3D坐标轴到绘制三角锥的线框模型到三角锥的实体模型,讲解在3D世界中我们绘制图形需要理解的事情,其实,单纯考虑3D图形还是很简单的,不就是多了一个Z坐标嘛。
3D坐标轴
不同一般的流程,我们从一个3D的坐标轴开始进入3D的世界,主要是为了将来与3D的线框模型做对比用的。
3D与以前学过的2D最大的不同就是我们需要考虑物体Z轴的坐标,而不再是假设任何物体的Z轴都是0.0,首先看我们绘制一个3D空间的坐标轴的情况,为了形象,我将其旋转了一定的角度。以下是源代码:
void
DrawCoordinate()
{
static
GLfloat fCoorDatas[] = { 0.0, 0.0, 0.0, // Origin
1.0, 0.0, 0.0, // X Dir
0.0, 1.0, 0.0, // Y Dir
0.0, 0.0, 1.0}; // Z Dir
static
GLubyte ubyIndices[] = { 0, 1, // X Axis
0, 2, // Y Axis
0, 3}; // Z Axis
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, fCoorDatas);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_BYTE, ubyIndices);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_BYTE, ubyIndices+2);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_BYTE, ubyIndices+4);
}
//这里进行所有的绘图工作
void
SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT); // 清空颜色缓冲区
glColor3f(1.0, 0.0, 0.0);
glPushMatrix();
glRotatef(30, 1.0, -1.0, 0.0);
DrawCoordinate();
glPopMatrix();
glFlush();
}
为节省篇幅仅贴出关键片段,完整源代码见我博客源代码的2009-10-21/gl3DCoordinate/目录,获取方式见文章最后关于获取博客完整源代码的说明。
与以前代码的主要不同是我们开始考虑Z轴坐标了,这里以(0.0, 0.0, 1.0)来表示Z轴的方向,假如不经过旋转,Z轴是正对着我们的,投影到屏幕上是一个点,我们看不到,所以这里做了一点旋转,将Z轴调整到左下方,这样的角度符合我们平时习惯绘制的3D坐标。具体的实现工程利用了顶点数组,顶点数组的相关知识参看本OpenGL系列文章5,(以下简称XO5)效果如下图:
这样的3D坐标图中会看到Z轴实际上没有伸出窗口以外,而是被截断了,具体的原因在以后说视景体裁剪的时候会说明,但是现在可以理解为在OpenGL中,整个3D空间的Z轴也不是无限的,而是与窗口大小一样,形成一个3D的立方体空间,如同2D平面中超出窗口的部分会看不见,超出Z轴空间的部分也会看不见,此处的Z轴被截断就是如此。并且,我们可以通过源码定位的Z轴正方向(0.0, 0.0, 1.0)和图形中的现实看出来,在OpenGL的3D坐标系中,Z轴的正方向是指向屏幕外的,这点在XO3中讲过了,我们在这里通过坐标轴的图再次理解一下。理解了3D坐标系,那么所有的3D图形也就是如同2D图形一样的定坐标而已了。
三角锥(即四面体或金字塔形)线框模型
下面我们开始在上述3D坐标体系中绘制一个三角锥,这里还是先用线框模型来绘制。其实没有任何3D知识,仅仅靠凭空想象也能定下一个这样简单的三角锥的空间坐标,以下如是,其实没有什么技术难度,仅仅加入Z轴考虑,下列程序将三角锥不停的围绕其自身的Z轴自转,为了形象,同时绘制上面讲的三维立体坐标轴。格式有点混乱,是因为Live Writer的Code Snippet自动format不太好用-_-!完整源代码的排版是缩进较为对齐的。
void
DrawWirePyramid(GLfloat adSize)
{
static
GLfloat fPyramidDatas[] = { 0.0, 1.0, 0.0, // 三角锥上顶点
-1.0, 0.0, 1.0, // 底面左前顶点
1.0, 0.0, 1.0, // 底面右前下顶点
0.0, 0.0, -1.0}; // 底面后下顶点
GLfloat fPyramidSizeDatas[sizeof
(fPyramidDatas)/sizeof
(GLfloat)] = {0};
// 计算大小
for
( int
i = 0; i < 12; ++i)
{
fPyramidSizeDatas[i] = fPyramidDatas[i] * adSize;
}
static
GLubyte ubyIndices[] = { 0, 1, // 以下为三条侧边
0, 2,
0, 3,
1, 2, // 以下为三条底边
2, 3,
3, 1};
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, fPyramidSizeDatas);
for
(int
i = 0; i < 6; ++i)
{
glDrawElements(GL_LINES, 2, GL_UNSIGNED_BYTE, ubyIndices+i*2);
}
}
//这里进行所有的绘图工作
void
SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glPushMatrix();
DrawCoordinate();
DrawWirePyramid(0.5);
glPopMatrix();
glRotatef(1.0, 0.0, 1.0, 0.0);
glFlush();
}
为节省篇幅仅贴出关键片段,完整源代码见我博客源代码的2009-10-21/glWirePyramid 目录,获取方式见文章最后关于获取博客完整源代码的说明。
显示效果如下图所示。
三角锥
以上讲到3D图形都是以线框模型来演示的,主要是为了可以纯粹的考虑3D坐标的问题,下面我们开始加入颜色,看看真正的立体模型是怎么样的^^在上述例子中加入颜色实在再简单不过了,因为已经使用了顶点数组,我们只需要再启用一下颜色的数组就好了。
如下例所示:
void
DrawSmoothColorPyramid(GLfloat adSize)
{
static
GLfloat fPyramidDatas[] = { 0.0, 1.0, 0.0, // 三角锥上顶点
-1.0, 0.0, 1.0, // 底面左前顶点
1.0, 0.0, 1.0, // 底面右前下顶点
0.0, 0.0, -1.0}; // 底面后下顶点
GLfloat fPyramidSizeDatas[sizeof
(fPyramidDatas)/sizeof
(GLfloat)] = {0};
// 计算大小
for
( int
i = 0; i < 12; ++i)
{
fPyramidSizeDatas[i] = fPyramidDatas[i] * adSize;
}
static
GLfloat fPyramidColors[] = { 0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0};
static
GLubyte ubyIndices[] = { 0, 1, 2, // 正面
0, 1, 3, // 左侧面
0, 2, 3, // 右侧面
1, 2, 3}; // 底面
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, fPyramidSizeDatas);
glColorPointer(3, GL_FLOAT, 0, fPyramidColors);
for
(int
i = 0; i < 4; ++i)
{
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, ubyIndices+i*3);
}
}
//这里进行所有的绘图工作
void
SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glPushMatrix();
DrawSmoothColorPyramid(0.5);
glPopMatrix();
glRotatef(1.0, 0.0, 1.0, 0.0);
glFlush();
}
为节省篇幅仅贴出关键片段,完整源代码见我博客源代码的2009-10-21/glSmoothColorPyramid/目录,获取方式见文章最后关于获取博客完整源代码的说明。
注意此例与上例中的区别,因为要显示完整的立体模型,就不能再用GL_LINES去画线了,我们需要使用GL_TRIANGLES来绘制三角形平面,一个三角锥其实不过就是一个四面体嘛。画上4个面,一切就OK。运行效果如下图:
小结
其实看完全文会发现,3D的世界也没有什么难的地方,无非就是多了一个Z轴需要考虑嘛,将整个屏幕想象成一个有前面空间,后面空间的立方体,然后想象出3D模型的坐标,一切也就简单了,本文主要讲的是三角锥,因为它是最简单的,大家可以试试立方体以增加难度,体会3D的坐标系统。
参考资料
1. 《OpenGL Reference Manual
》,OpenGL参考手册
2. 《OpenGL
编程指南》(《OpenGL Programming Guide
》),Dave Shreiner,Mason Woo,Jackie Neider,Tom Davis
著,徐波译,机械工业出版社
3. 《Nehe OpenGL Tutorials》,Nehe著,在http://nehe.gamedev.net/
上可以找到教程及相关的代码下载,(有PDF版本教程下载)Nehe自己还做了一个面向对象的框架,作为演示程序来说,这样的框架非常合适。也有中文版
,各取所需吧。
4. 《OpenGL入门学习》 ,eastcowboy著,这是我在网上找到的一个比较好的教程,较为完善,而且非常通俗。这是第一篇的地址:http://bbs.pfan.cn/post-184355.html
本系列下一篇《Win32 OpenGL编程(7) 3D视图变换——真3D的关键
》
本OpenGL系列其他文章
1.
《 Win32 OpenGL 编程(1)Win32下的OpenGL编程必须步骤
》
2. 《Win32 OpenGL编程(2) 寻找缺失的OpenGL函数
》
3. 《Win32 OpenGL编程(3) 基本图元(点,直线,多边形)的绘制
》
4. 《Win32 OpenGL编程(4) 2D图形基础(颜色及坐标体系进阶知识)
》
5. 《Win32 OpenGL编程(5)顶点数组详细介绍
》
完整源代码获取说明
由于篇幅限制,本文一般仅贴出代码的主要关心的部分,代码带工程(或者makefile)完整版(如果有的话)都能用Mercurial在Google Code中下载。文章以博文发表的日期分目录存放,请直接使用Mercurial克隆下库:
https://blog-sample-code.jtianling.googlecode.com/hg/
Mercurial使用方法见《分布式的,新一代版本控制系统Mercurial的介绍及简要入门
》
要是仅仅想浏览全部代码也可以直接到google code上去看,在下面的地址:
http://code.google.com/p/jtianling/source/browse?repo=blog-sample-code
原创文章作者保留版权 转载请注明原作者 并给出链接
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
分享到:
相关推荐
这个"win32 OpenGL的例子"提供了一组基于Win32 API编写的示例,帮助开发者了解如何在Windows环境下使用OpenGL 1.0进行图形渲染。Win32 API是Windows操作系统的核心组件,它提供了丰富的功能,包括窗口管理、事件处理...
在项目的属性页中,导航到"Configuration Properties" > "Linker" > "Input",在"Additional Dependencies"下添加以下库:`opengl32.lib`, `glu32.lib`, `glaux.lib`(可选,用于辅助功能), `glext.lib`(用于扩展...
当我们谈论“OpenGL Win32”,我们实际上是在讨论如何在Windows平台上利用OpenGL进行图形编程。 OpenGL是一种跨语言、跨平台的编程接口,用于渲染2D、3D矢量图形。它由Khronos Group维护,该组织负责更新和扩展标准...
《Win32 OpenGL 3D 炮打飞机程序详解》 在计算机图形学的世界里,OpenGL是一个重要的图形库,它允许程序员创建复杂的3D图形应用程序。本篇将深入探讨"Win32 OpenGL 3D 炮打飞机程序"这一主题,带你走进3D游戏开发的...
"WIN32 OpenGL 缩放图形"这个主题涉及到如何在Win32应用程序中使用OpenGL来改变图形的大小,实现缩放效果。 在OpenGL中,缩放通常是通过矩阵变换来实现的。在3D空间中,图形由顶点定义,而顶点的位置可以通过将它们...
微软在 Visual C++ 5 中已提供了三个 OpenGL 的函数库(glu32.lib, glau.lib,OpenGL32.lib),可以使我们方便地编程,简单、快速地生成美观、漂亮的图形。 生成 OpenGL 程序的基本步骤和条件: 1. 设置窗口像素格式...
"OpenGL 编程精粹" 本资源总结了OpenGL编程相关的知识点,包括OpenGL的原理、算法、系统、光源、光照模型、物体材质、明暗处理、深度测试等基本方法,并通过实验报告,介绍了使用OpenGL编程模拟太阳、地球、月亮三...
OpenGL,全称Open Graphics Library,是一个跨语言、跨平台的编程接口,用于渲染2D、3D矢量图形。它被广泛应用于游戏开发、科学可视化、虚拟现实等领域。OpenGL提供了丰富的函数集,允许开发者创建复杂的几何形状、...
WIN32 opengl三角形绘制。VS2012
【3D赛车游戏源码】基于OpenGL和Win32 API的3D赛车游戏是一个学习图形编程和游戏开发的宝贵资源。对于初学者来说,通过分析和理解这些源代码,可以深入掌握3D图形渲染和游戏逻辑的核心概念。 1. **OpenGL**:OpenGL...
这个"基于win32框架生成OpenGL窗口源代码"的示例,为初学者提供了在Windows环境下搭建OpenGL编程环境的基础。 首先,我们需要理解Win32 API的核心概念。Win32 API是Windows操作系统提供的函数库,包含了创建和管理...
"win32 opengl画线"这个主题涉及到了在Microsoft Windows环境下,利用OpenGL库来创建和显示简单的线条。OpenGL是一个跨语言、跨平台的编程接口,用于生成2D和3D图像。在Visual Studio 2012这样的IDE中,我们可以配置...
第6章混合、抗锯齿、雾和多边形偏移 第7章显示列表 第8章绘制像素、位图、字体和图像 第9章纹理贴图 第10章帧缓冲区 第11章分格化和二次方程表面 第12章求值器和NURBS 第13章选择和反馈 第14章OpenGL高级技巧 第15章...
OpenGL(Open Graphics Library)是一种用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API)。它使用一种特殊的状态机架构来定义和实现高性能的交互式图形应用。自1992年首次发布以来,OpenGL已经成为...
OpenGL编程指南第9版、超级宝典第7版、计算机图形原则和实践第3版以及OpenGL领悟(OpenGL Insights)这四本书是计算机图形学领域的经典之作,尤其对于使用OpenGL进行图形编程的开发者来说,它们提供了丰富的知识和深入...
总的来说,OpenGL Win32 AppWizard 是一个强大的工具,它降低了在VC环境下开发OpenGL应用的门槛,让开发者可以更专注于图形编程本身,而不是花费大量时间在环境配置上。通过阅读和实践,你可以快速掌握OpenGL编程的...
OpenGL编程指南(第九版英文)是一本深入探讨OpenGL图形编程技术的专业书籍,旨在为开发者提供全面的理论知识和实践指导。OpenGL是计算机图形学领域广泛使用的API,它允许程序员创建复杂的3D图形和视觉效果。第九版...
5. **GLUT的安装**:包含四个步骤:解压GLUT文件,将头文件glut.h放入包含目录,将库文件glut.lib和glut32.lib放入静态库目录,最后将glut.dll和glut32.dll放入系统目录的System32子目录。 6. **OpenGL基本概念**:...
OpenGL编程指南 第8版 高清 中文 完整版,PDF格式的。是目前网络上最清晰的完整版本。这本书是学习OpenGl的必备资料,非常好的书。 由Khronos小组编写的官方指南,OpenGL领域的权威著作,素有“OpenGL红宝书”美誉...
OpenGL编程进阶 OpenGL编程进阶 OpenGL编程进阶 OpenGL编程进阶