OpenGL中不设置模型,投影,视口,所绘制的几何图形的坐标只能是-1到1(X轴向右,Y轴向上,Z轴垂直屏幕)。
产生目标场景的过程类似于用照相机进行拍照:
(1)把照相机固定在三角架上,并让他对准场景
从不同位置观察场景(视图变换)
(2)对场景进行安排,使各个物体在照片中的位置是我们所希望的
移动,旋转或者放大缩小场景中的物体(模型变换)
(3)选择照相机镜头,并调整放大倍数(调焦)
显示物体时,可以选择物体是如何投影到屏幕上(投影变换)
(4)确定照片的大小,放大照片还是缩小照片
把图形画下来,是要占据整个屏幕还是屏幕的一部分(视口变换)
三大变换:(都是通过操作矩阵来实现的)
1、模型视图变换
在进行模型视图变换之前,应先设置当前操作的矩阵为"模型视图矩阵",通过设置glMatrixMode( GL_MODELVIEW),在进行变换
之前把当前矩阵设置为单位矩阵glLoadIdentity();如果不进行单位化,所有的后续操作都是在当前矩阵的前提下进行的。
2、投影变换
投影变换即定义一个可视空间,可视空间以外的物体不会被绘制到屏幕上(从现在起,坐标不在是-1.0到1.0了)
OpenGL支持两种投影,透视投影和正投影,通过设置glMatrixMode( GL_PROJECTION )来操作投影矩阵。
透视投影的主要函数
1、glFrustum()
2、glPerspective( GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far)
创建一个表示对称透视视图平截头体的矩阵,并把它与当前矩阵相乘。fovy是YZ平面上视野的角度,范围【0,180】。aspect是这个平截头体的纵横比,也就是宽度除于高度。near和far值分别是观察点与近侧裁剪平面以及远侧裁剪平面的距离(沿Z轴负方向)这两个值都是正的。
正投影的主要函数
1、glOrtho( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far)
创建一个平行视景体(就是一个长方体空间区域)。实际上这个函数的操作是创建一个正射投影矩阵,并且用这个矩阵乘以当前矩阵。其中近裁剪平面是一个矩形,矩形左下角点三维空间坐标是(left,bottom,-near),右上角点是(right,top,-near);远裁剪平面也是一个矩形,左下角点空间坐标是(left,bottom,-far),右上角点是(right,top,-far)。注意,near和far都是正值。只有在视景体里的物体才能显示出来,我感觉你最后两个参数取得有点问题,而且你改成0,0后,视景体深度没有了,整个视景体都被压成个平面了,当然就显示不正确了。
2、glOrtho2D( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
创建一个表示把二维坐标投影到屏幕上的矩阵,并把当前矩阵与它相乘,裁剪区域为矩形。
把像素绘制到屏幕上glViewport()定义视口,前两个参数最左下方,后两个参数宽度和高度。
3、视口变换
在窗口中定义一个像素矩形,最终的图像将映射到这个矩形中。
glViewport( Glint x, Glint y, GLsizei width, GLsizei height );XY指定了视口的左下角,WH指定了视口的高度和宽度。在默认情况下,视口的初始值是(0,0,winwidth,winheight)。
视口的纵横比一般和视景体的纵横比相同。当窗口的大小发生变化时,并不会自动影响视口,应用程序应该检测窗口大小改变事件。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/longge7685/archive/2010/01/31/5274467.aspx
关于模型转换的基础知识
1.模型转换与视点转换: glTranslate{fd}(TYPE x, TYPE y, TYPE z )、 glRotate{fd}( TYPE angle, TYPE x, TYPE y, TYPE z )、
glScale{fd}(TYPE x, TYPE y, TYPE z )
这三个函数分别对模型进行平移,旋转,缩放。我们可以想象一下,视点转换和模型转换可以使用相同的函数进行,比如,在用相机拍摄物体时,我们可以保持物体的位置不动,而将相机移离物体,这就相当于视点转换;也可以保持相机的位置不动,将物体移离相机,这就相当于模型转换。
模型转换和视点转换共同构成模型视景矩阵。
2.矩阵堆栈操作:glPushMatrix(),glPopMatrix()
说明,OpenGL中有两个最基本的矩阵,模型视景矩阵和投影矩阵,它们都有相应的矩阵堆栈,这些矩阵的当前值就是在矩阵堆栈中的最顶层元素。对于转换操作,发出转换命令后生成的新的当前矩阵就存储在矩阵堆栈中,因此,我们可以利用矩阵堆栈存储当前值,并在需要的时候将当前值弹出堆栈。
举例来说,我们现在需要绘制一个自行车,设置自行车的两个轮子相对于坐标原点是对称的。我们可以这样绘制:将坐标系原点移动到前车轮中心,然后进行绘制,完成后,计算前车轮中心到后车轮中心的距离,并将坐标系原点移动到后车轮中心,再绘制后车轮。显然,这种绘制顺序是不科学的,如果需要绘制更多的对称物体,那么这种计算量会非常大,而且容易产生错误。
这种问题,我们使用矩阵堆栈可以很容易得到解决。在绘制前车轮之前,将当前矩阵保存在矩阵堆栈中,然后将坐标原点移动到前车轮中心,绘制前车轮,绘制结束后,将保存的当前矩阵弹出矩阵堆栈,这时堆栈顶部的矩阵仍为原坐标系,下一步只需相对于原坐标系移动相应距离到后车轮进行绘制,这样,所有物体的位置都是相对于原坐标系进行设置,程序计算量得到缩减,而且不容易出错误。
转自:http://blog.csdn.net/soilwork/archive/2009/01/08/3731645.aspx
与玩游戏相比,写游戏要复杂上千万倍,除了需要掌握通用的编程技巧以外,还要有相当的图形学,物理,数学基础,特别是在国内,由于相关资料的缺乏,更是让初学者无从下手。下面总结了一些入门方法和比较容易入手的资料。
首先你要精通一门高级语言,比如C++或者C#,其次,要有良好的英文阅读能力。对游戏开发者来说英文阅读能力是最重要也是最基本的工具之一,因为你遇到的大部分资源都将是英文的,不要总等着别人为你翻译。慢慢尝试着阅读英文资料,你会发现其实也并没有那么难:)
刚开始,你要做的就是选择一门图形API,一般就是DirectX或者OpenGL之间选一个。如果考虑到跨平台,那么OGL是首选. 如果只在ms的平台,则DX是首选。我对OGL并不是很了解,所以下面大部门资料都是和DX相关的。
当然,作为准备工作之一,你首先要到DirectX Develop Center下载最新版的DirectX SDK。
入门书籍非常重要,推荐<<Introduction to 3D Game Programming with DirectX 9.0>>(好像去年出了中文版)也就是传说中的龙书,这可以说是最好的DX入门教材,Frank Luna从浅入深,讨论了DX的方方面面。另外再配上<< Advanced 3D Game Programming With DirectX 9.0>>,书名虽然是advanced,但实际上没有多少advanced级别的内容。看完这两本书,你基本上已经对DirectX比较熟悉了。如果你希望学习XNA,也是一样的,毕竟XNA是以DX为基础。
不要一开始就看图形学的书,这个时候你对图形编程还没有一个基本的感性认识,因此八成看的云里雾里。不要以网上的教程和论坛提问作为主要学习途径,找一本好书,系统学习,效率才最高。不要马上看SDK里的例子,很多图形学的基本原理仅仅通过读代码是不会明白的。某些年代太过久远的书就不要看了,比如《windows游戏编程大师技巧》(总看到有人在找这本书)。有人说基本的思想总是不变的,可惜对于现代GPU来说,很多早期的技术和优化技巧早就过时了。图形编程是发展的非常快的技术,看看GPU的发展速度,1~2年就是一代产品的革新。
好了,入门之后,是你巩固和拓展视野的阶段。现在看计算机图形学就比较合适了。吐血推荐<<Real-Time-Rendering>>,这本书算得上是所有图形程序员的必读书籍和参考手册了。最近刚出了第三版(更新:已经有电子版了)。可惜国内只有第二版,稍微有点老,如果实在找不到第三版,还是值得一读。国内其他所有以图形学命名的书都有一个共同点:枯燥,过时。只需看看其中二维三维变换和曲线曲面表示的部分即可。如果这个时候发现你当年数学没有学好,那么有三本数学书是为游戏程序员量身定制的:<<3D Math Primer for Graphics and Game Development>>, <<Mathematics for 3D Game Programming and Computer Graphics>>和<<Essential Mathematics Guide 2nd Edition>>,第一本书有中文版,最后一本则是08年才出的新书。
其实入门之后,就没有固定的学习路线了,最好根据你感兴趣的方向来学习。
Shader方面:《Cg_tutorial》和《The Complete Effect and HLSL Guide》都是不错的入门材料,当然还有SDK文档。<<Shaders for Game Programmers and Artists>>有大量入门的例子。<<Advanced Lighting And Materials With Shaders>>详细介绍了各种光照模型和技术。<<GPU Gems>> 1~3册肯定是必读的,虽然有1,2有中文版,但某些翻译并不是很理想,强烈建议直接看英文版。ShaderX系列也是很经典的系列,每年出版一本,包含了最新的实时渲染技术,如今已经出了第6册了。不过网络上只能找到1~3册。1,2册大部分shader都是用asm写的,不过看懂原理,转换为HLSL也并不难。另外Nvidia SDK和ATI SDK也是学习shader的重要资源。最后还有刚出的<< Programming Vertex, Geometry, and Pixel Shaders>>
地形:<<Real Time 3D Terrain Engines Using C++ And DX9>>非常全面的讨论了关于地形渲染的各种技术,至少应该把第5~9章都浏览一遍。之后便可以 到virtual terrain查阅近期的地形渲染技术。
模型导入和动画:<<Advanced Animation with DirectX>>,仅此一本足以。
物理:<<Game Physics>>和<<Game Physics Engine Development>>都不错。<<Real-time Collision Detection>>是碰撞检测方面最好的书,可惜目前还没有电子版。
LOD:<<Level of Detail for 3D Graphics>>
Ray tracing:<< Physical-Based Rendering - From Theory to Implementation>>
引擎设计:说实话,这方面还没有特别好的书,大概越是核心的内容,越少有人愿意写吧。<<3D Game Engine Architecture Engineering Real-Time Applications with Wild Magic>>只有第三章值得一读。<<3D Game Engine Programming>>可以选部分感兴趣的章节看看,不过总的来说,讲的比较浅。更新:<<3D Game Engine Design, Second Edition>>出了影印版本,强烈推荐。最近发现<<Pro OGRE 3D Programming>>也很不错,200多页短小精干,但是可以让读者快速了解一个既有引擎的设计和构架。
AI:<<Programming Game AI by Example>>非常不错,好像还有中文版,备选<<Artificial Intelligence for Games>>。当然<<AI Programming Wisdom>>系列也是必读作品,不过目前网络上只有1~2册。
网络:%##@%...(本人是网络白痴 +_+........)
综合:<<Game Programming Gems>>系列,不过由于内容涉及的过于广泛,文章质量参差不齐,选择性阅读就可以了。历年GDC, Gamefest t,Siggraph等大型会议的paper也是应该关注的。
至于那些“All in one”或者n天较你写出个FPS游戏的书就不要读了,这类书的通病是什么都说了,结果什么也没说清楚。
除了书以外,再推荐一些不错的网络资源:
www.GameDev.net 除了大量教程以外,论坛里多年累计下来的内容保罗万象。好好利用论坛搜索,你会发不管你多厉害,那里总有一些比你强大的人在很久以前就遇到了和你同样的问题,并且给出了解决方案。
Nvidia和ATI的开发者中心
creators.xna.com XNA官方网站
www.gamasutra.com 与GameDev类似
www.beyond3d.com 这里的除了讨论软件以外,还能看到对硬件构架的分析
www.ziggyware.com 最好的XNA教程网站
www.gameres.com 国内唯一比较专业的游戏编程网站,可惜和GameDev相比就显得太寒碜了-_-#
当然,不要忘了收集各大论坛里牛人们的blog:)
最后,仅仅靠看书是不够的,多写多练才是王道。
转自:http://fotoone.spaces.live.com/blog/cns!68DE430B0B5562FB!901.entry
和WQ谈起有关游戏开发和Direct3D编程的事,因为他是入门者,所以,我给他提了点入门级的学习建议。
1. 浏览一下DirectX SDK中Direct3D 10教程
DirectX SDK肯定是要好好研究和学习的。目前DirectX的最新版本是v10,v11不久将大驾光临。SDK的最新版本是March 2009 DirectX SDK。在DirectX SDK中,主要学习Direct3D 10的内容。SDK中有一个Direct3D系列教程,可以把这个系列教程的文档看看,编译和运行教程中的所有程序,得到一点3D编程的感觉,这个时候不需要对其中涉及的概念原理有很深的了解。
2. 了解下游戏引擎
但是,在深入学习Direct3D之前,建议看看Jake Simpson的Game Engine Anatomy 101系列文章,是用来讲解游戏引擎的,中文翻译是游戏引擎剖析。在看完后,会对游戏引擎有较全面的了解,大致会知道在一个游戏引擎中,图形渲染起什么作用,Direct3D在游戏引擎中是干嘛的,处在一个什么位置。
3. 了解Direct3D graphics pipeline一般原理和组成(固定功能流水线和可编程流水线)
学习Direct3D,就是要掌握Direct3D graphics pipeline。在了解了游戏引擎之后,阅读一下ExtremeTech 3D Pipeline Tutorial 或者Real-Time rendering第三版的第二章(The Graphics Rendering Pipeline),它们都是讲述实时Direct3D graphics pipeline的一般原理的。我个人感觉前一篇文章内容要多点,也稍微难懂点。 当然,最好2篇文章都看看,可以相互参照进行阅读。
BTW,Real-Time rendering是一本很好的图形学的书,要成为图形学专业人士的话,可以认真研究,现在最新版是第三版,唉,想起我以前的买的三本图形学教材都过时了,计算机图形学可真是发展太快了!
4. 学习Direct3D graphics pipeline
这几篇文章看过后,再花功夫好好研究DirectX SDK中的DirectX Documentation for C++,特别要明白Direct3D graphics pipeline的各个阶段。这个阶段也可以找本DirectX入门书看看,网上有人推荐Introduction To Direct3D9,有中文版,我没看过,但这本书是讲Direct3D 9,而非Direct3D 10和Direct3D 11,由于架构上的变化(Direct3D 10抛弃了固定功能的vertex和pixel处理),和Shader Model变更(抛弃了老版本的Shader Model,只支持全新的Shader Model 4),以及Shader编程语言的变化(不再支持汇编,只支持HLSL),Direct3D 9和Direct3D 10有很大的区别,所以不推荐入门者浪费青春去学习Direct3D 9,而应该直接学习Direct3D 10和Direct3D 11。
在阅读DirectX Documentation for C++的时候,也阅读Real-Time rendering第三版的第三章(The Graphics Processing Unit),在这个学习阶段,我强烈推荐看Programming Vertex, Geometry, and Pixel Shaders。
另外,可以参考一下Richard Thomson的Direct3D Graphics Pipeline资料,主要看看其中的Direct3D Graphics Pipeline Poster,这张图类似Direct3D API迷宫的导航图,我个人感觉在学习和掌握Direct3D API方面,很有价值。 同样,要注意的是Richard Thomson的Direct3D Graphics Pipeline Poster针对的是Direct3D 9.0版本,此图不反映最新的Direct3D流水线,但此图依然对理解Direct3D 10/11 pipeline有参考价值,比如:Direct3D 9 Graphics Pipeline Poster图中的Vertex Assembly以上部分可以理解为Direct3D 10/11 pipeline中的Input-Assembler Stage(IAS),同样,Vertex Assembly到Primitive Assembly的之间的部分理解为Direct3D 10/11 pipeline中的Vertex Shader Stage(VSS),Primitive Assembly到Rasterization and Component Interpolation之间的部分理解为Rasterizer Stage(RS),Rasterization and Component Interpolation和Fog Blend之间的部分理解为Pixel Shader Stage(PSS),Fog Blend以下的部分则理解为Output-Merger Stage(OMS)。另外,Direct3D 9中的一些处理阶段,比如Alpha Test,在Direct3D 10没有单独实现,需要编写Pixel Shader实现,所以,Direct3D 10/11 pipeline中不会出现Alpha Test处理阶段。
BTW, 写到这,我突然想,我是不是该把Richard Thomson的Direct3D 9 Graphics Pipeline Poster的图改写一下,发布一张Direct3D 10/11 Graphics Pipeline Poster? 恩,不过,我想Richard Thomson自己会做这个工作的!
最新版本的March 2009 DirectX SDK主要包括的是Direct3D 10&9 Graphics Pipeline的内容,有关最新Direct3D 11 Graphics Pipeline的内容,可以看看Introduction to the Direct3D 11 Graphics Pipeline中的PPT,或者阅读一下March 2009 DirectX SDK中的Direct3D 11 Technical Preview,不过现在看不看都没有什么关系,毕竟Direct3D 11还不知道何时正式登场。
5. 根据自己的兴趣,挑选几个Direct3D Samples进行研究
理解了Direct3D图形流水线之后,可以根据兴趣学习图形学中的不同方面的知识,比如,对动画、阴影感兴趣,就可以重点研究Direct3D Samples中的动画、阴影的例子。研究代码的同时,也学习动画、阴影原理,这样学起来,得心应手。
6. 学习Direct3D的方法总结
在我看来,学习,应该首先建立系统框架图,就好比去游乐园玩,有导航图一样,学习的时候,才不会迷失在错综复杂的技术细节之中。然后,再像玩拼图游戏一样,把系统的各个知识面拼缀到这个系统框架图中,形成完整的知识系统图。
这种方法用在Direct3D的学习上,可以认为是:先理解游戏引擎这个系统框架图,然后,明了3D 图形子系统在游戏引擎中的位置。接着,在理解3D图形子系统(Direct3D)这个子系统框架图的基础上,明了Direct3D流水线,进一步针对Direct3D流水线包含的各个阶段(Stage),深入学习Direct3D API。在学习中,遇到函数、结构、常量可以自动地发现这些东西在Direct3D流水线中的哪个阶段被用到。按照这种方式进行学习,可以比较方便地把各个知识点有条理地拼缀起来,极大地提高学习效果。
-----
注:某日在网上看到一篇游戏程序员养成计划,写得细致全面,强烈推荐。地形渲染还有一本书《Focus On 3D Terrain 》,我建议学习地形渲染看这本书比较容易上手。本书网上有中文翻译(我建议别看,翻译得差)。所有书籍,都推荐直接看英文版的。
WinCapture: www.wincapture.com
WinCapture The most popular screen capture, video screen recording and image editing utility for Windows, with more than 9 million downloads.
Capture anything you see on your computer screen - images and text.
Easily record activity on your computer screen, audio and webcam video.
Edit your screen captures and images with drawing tools, annotations and stunning visual effects.
//获得SIM中联系人信息。
LPARAM DoShowSimContact(HWND hWnd, WORD idItem, HWND hwndCtl, WORD wNotifyCode)
{
MessageBox(NULL, TEXT("start show sim contact"),TEXT("info"),MB_YESNO);
HSIM lphSim;
HRESULT hr = SimInitialize(0, NULL, 0, &lphSim);
if(FAILED(hr))
{
MessageBox(NULL, TEXT("initialize failure!"),TEXT("error"),MB_YESNO);
return 0 ;
}
DWORD dwUsed,dwTotal;
hr = SimGetPhonebookStatus(lphSim, SIM_PBSTORAGE_SIM, &dwUsed, &dwTotal);
TCHAR buf[20];
swprintf(buf, TEXT("dwUsed = %d"), dwUsed);
MessageBox(NULL, buf ,TEXT("dwUsed"),MB_YESNO);
for(int i=0; i<dwUsed; i++)
{
//对结构初始话以下
SIMPHONEBOOKENTRY phoneent;
memset(&phoneent,0,sizeof(phoneent));
phoneent.cbSize = sizeof(phoneent);
if (SUCCEEDED(SimReadPhonebookEntry(lphSim, SIM_PBSTORAGE_SIM, i+1, &phoneent)))
{
TCHAR name[32];
TCHAR phone[32];
MessageBox(NULL, phoneent.lpszText ,TEXT("info1"),MB_YESNO);
wcsncpy(name, phoneent.lpszText,31); // 姓名
wcsncpy(phone, phoneent.lpszAddress,31); // 电话
_tcscat(name, phone);
MessageBox(NULL, name ,TEXT("info"),MB_YESNO);
}
}
//最后别忘了清理
SimDeinitialize(lphSim);
lphSim = NULL;
return 0;
}
//获得Outlook联系人信息
BOOL GetOutlookContacts(IPOutlookItemCollection * pItemCol)
{
BSTR bstrFirstName;
BSTR bstrLastName;
BSTR bstrPhoneNumber;
BSTR bstrContactInfo;
IContact * pContact = NULL;
int cItems = 0;
pItemCol->get_Count(&cItems);
for (int i = 1; i <= cItems; i++)
{
if (SUCCEEDED(pItemCol->Item (i, reinterpret_cast<IDispatch**>(&pContact))))
{
// grab properties
pContact->get_FirstName(&bstrFirstName);
pContact->get_LastName(&bstrLastName);
pContact->get_HomeTelephoneNumber(&bstrPhoneNumber);
// allocate a buffer for all the properties plus a comma, space. newline, and terminating null
bstrContactInfo = SysAllocStringByteLen(NULL, SysStringByteLen(bstrFirstName) +
SysStringByteLen(bstrLastName) +
SysStringByteLen(bstrPhoneNumber) +
(4*sizeof(OLECHAR)));
// copy the strings into one
_tcscpy(bstrContactInfo, bstrLastName);
_tcscat(bstrContactInfo, _T(", "));
_tcscat(bstrContactInfo, bstrFirstName);
_tcscat(bstrContactInfo, _T("\n"));
_tcscat(bstrContactInfo, bstrPhoneNumber);
// add it to the listview
AddToList(bstrContactInfo);
// clean up
SysFreeString(bstrFirstName);
SysFreeString(bstrLastName);
SysFreeString(bstrPhoneNumber);
SysFreeString(bstrContactInfo);
pContact->Release();
}
}
if(!AddSIMContactsFolderText())
{
MessageBox(NULL, TEXT("add sim failure!"),TEXT("error"),MB_YESNO);
}
return TRUE;
}