小祥的BLOG

游戏开发
posts - 7, comments - 14, trackbacks - 0, articles - 0
  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2007年11月17日

新blog地址:http://xfxsworld.cnblogs.com/

posted @ 2007-11-17 15:02 小祥 阅读(234) | 评论 (0)编辑 收藏

2007年11月16日

今天初试了一下CEGUI的官方编辑器——CELayoutEditor,其过程真可谓“饱受挫折”。现简要写下其源码的编译过程,已使可能会用到的朋友少走些弯路

1.    要编译CELayoutEditor,自然需要先编译CEGUI的东东,有2种选择:
        1.1 安装SDK,这是下载地址:http://jaist.dl.sourceforge.net/sourceforge/crayzedsgui/CEGUI-SDK-0.5.0b-vc8.exe,不过并不推荐这种方法,因为SDK里的debug版dll似乎有问题。。。
        1.2 编译其源代码。下载地址:http://jaist.dl.sourceforge.net/sourceforge/crayzedsgui/CEGUI-0.5.0b.zip,另外还需要下载依赖文件包dependencies package ,下载地址是:http://jaist.dl.sourceforge.net/sourceforge/crayzedsgui/CEGUI-DEPS-0.5.0b-vc8.zip,然后将依赖文件解压进源代码文件夹就OK了。
                  1.2.1   先别急着找solution,有个地方需要注意。CEGUI默认的是OPENGL渲染,如果是用D3D的话还得改一个地方。进..\makefiles\premake文件夹找到config.lua文件,记事本打开。改成“OPENGL_RENDERER = false,DIRECTX9_RENDERER = true”,保存。
                  1.2.2    运行build_vs2005.bat文件,执行完毕后会生成CEGUI.sln文件,打开就可直接编译了
         1.3   建立环境变量:我的电脑\属性\高级\环境变量,然后在上面的用户变量区新建一个,变量名是CEGUI,变量值是CEGUI的解压目录。注意这步不能省


2    由于CELayoutEditor使用了wxWidgets,所以在编译CELayoutEditor之前还需要下载wxWidgets。目前最新版本是2.86,进入官方下载网页http://www.wxwidgets.org/downloads/ 选择WxAll下载。
        2.1 建立环境变量:我的电脑\属性\高级\环境变量,然后在上面的用户变量区新建一个,变量名是WXWIDGETS,变量值是wxWidgets的解压目录。
        2.2  进wxWidgets的解压目录找到wx.dsw,打开、“Yes To All”转换。转换完毕后先别编译,还需要改下。因为wxWidgets默认并不是OPENGL
Open $(WXWIDGETS)\include\wx\msw\setup.h and replace 

Code: 
#define wxUSE_GLCANVAS 0  
WITH Code: 
#define wxUSE_GLCANVAS 1 


7.2 Open $(WXWIDGETS)\include\wx\univ\setup.h and replace 

Code: 
#if defined(__WIN32__) 
   
#define wxUSE_GLCANVAS 1 
else    
    
#define wxUSE_GLCANVAS 0 

WITH 
Code: 
#define wxUSE_GLCANVAS 1 


           2.3    现在就可以开始编译了。注意要选择“Unicode Debug”和“'Unicode Release”方式

3          下载CELayoutEditor。我是用SVN接的,地址是 https://crayzedsgui.svn.sourceforge.net/svnroot/crayzedsgui/CELayoutEditor/trunk
            3.1    解压后打开工程,将Include和Lib路径改成自己的,其他的不用改
            3.2    建立环境变量:我的电脑\属性\高级\环境变量,然后在上面的用户变量区新建一个,变量名是CE_LAYOUT_EDITOR ,变量值是CELayoutEditor的解压目录。注意这步不能省
            3.3    终于可以开始编译了。。。

4          
            4.1    编译会出现一个错误,暂时我还没找到解决方法,仅仅是给错误的地方注释掉了。。。然后就编译成功了
            4.2    拷一些东西过来

TO $(CE_LAYOUT_EDITOR)\bin\debug (Debug configuration) 
- CEGUIBase_d.dll 
- CEGUIExpatParser_d.dll 
- CEGUIFalagardWRBase_d.dll 
- CEGUISILLYImageCodec_d.dll 
- CEGUITGAImageCodec_d.dll 
- OpenGLGUIRenderer_d.dll 
- SILLY_d.dll

TO $(CE_LAYOUT_EDITOR)\bin\release (Release configuration) 
- CEGUIBase.dll 
- CEGUIExpatParser.dll 
- CEGUIFalagardWRBase.dll 
- CEGUISILLYImageCodec.dll 
- CEGUITGAImageCodec.dll 
- OpenGLGUIRenderer.dll
- SILLY.dll

           4.3 SILLY.dll和SILLY_d.dll在依赖文件夹里

OK。。。到这里就完了,虽然这个工具的bug很多,不过不怕,编译它就是为了要改造它,呵呵。希望此文对你有所帮助

开启画面



运行界面

posted @ 2007-11-16 20:37 小祥 阅读(1804) | 评论 (7)编辑 收藏

2007年11月15日

刚刚接触CEGUI,在原D3D程序上画了一个小窗口后,发现渲染效果于以前的大相径庭,查看了源代码后发现,原来CEGUI在渲染后并没有恢复到默认的渲染状态,于是改之,再编译、运行、一切正常。。。

下面是恢复其渲染状态的代码,与初始化渲染状态函数initPerFrameStates()对应

 1 void  DirectX9Renderer::UnitFrameStates()
 2 {
 3      //  setup vertex stream
 4
 5     d_device -> SetFVF(NULL);
 6
 7      //  set device states
 8     d_device -> SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
 9      d_device -> SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
10     d_device -> SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
11     d_device -> SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
12     d_device -> SetRenderState(D3DRS_FOGENABLE, FALSE);
13     d_device -> SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
14
15
16      //  setup texture addressing settings/*
17     d_device -> SetSamplerState(  0 , D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
18      d_device -> SetSamplerState(  0 , D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
19
20      //  setup colour calculations
21     d_device -> SetTextureStageState( 0 , D3DTSS_COLORARG1, D3DTA_TEXTURE);
22      d_device -> SetTextureStageState( 0 , D3DTSS_COLORARG2, D3DTA_CURRENT);
23      d_device -> SetTextureStageState( 0 , D3DTSS_COLOROP, D3DTOP_SELECTARG1);
24
25      //  setup alpha calculations
26     d_device -> SetTextureStageState( 0 , D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
27      d_device -> SetTextureStageState( 0 , D3DTSS_ALPHAARG2, D3DTA_CURRENT);
28      d_device -> SetTextureStageState( 0 , D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
29
30      //  setup filtering
31     d_device -> SetSamplerState( 0 , D3DSAMP_MINFILTER, D3DTEXF_POINT);
32      d_device -> SetSamplerState( 0 , D3DSAMP_MAGFILTER, D3DTEXF_POINT);
33
34      //  disable texture stages we do not need.
35     d_device -> SetTextureStageState( 1 , D3DTSS_COLOROP, D3DTOP_DISABLE);
36
37      //  setup scene alpha blending
38     d_device -> SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
39      d_device -> SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
40      d_device -> SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
42 }

另外CEGUI有2种渲染模式:立即渲染和缓冲渲染。所以在这2种渲染模式结束后都需要调用上面的代码以恢复渲染状态

posted @ 2007-11-15 20:22 小祥 阅读(1597) | 评论 (4)编辑 收藏

Direct3D计算Alpha混合的颜色公式:
Color = ( SrcRGB * SrcK ) + ( DestRGB * DestK )
 
SrcRGB表示源颜色值,即将要绘制的颜色值。SrcK表示源混合系数,通常赋值为D3DBLEND_SRCALPHA,即当前绘制像素的Alpha值
DestRGB表示目标颜色值,即当前缓冲区中的颜色值。DestK表示目标系数,通常赋值为D3DBLEND_INVSRCALPHA,即1减去当前绘制像素的Alpha值
 
则Direct3D计算Alpha混合的颜色公式可表示为
Color = ( SrcRGB * SrcAlpha ) + ( DestRGB * ( 1 - SrcAlpha ) )
 
混合步骤
 
Alpha混合默认关闭,所以首先需要开启它
Device -> SetRenderState( D3DRS_ALPHABLENDENABLE, true );
 
然后设置Alpha混合系数
Device -> SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
Device -> SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
 
还要指定资源(材质或Alpha通道)
Alpha通道可用DirectX自带的纹理工具创建,为DDS文件
 
DEMO演示图片:
alphablend.jpg

posted @ 2007-11-15 19:40 小祥 阅读(1544) | 评论 (2)编辑 收藏

地形一般是用网格再从高度图里读取每个顶点的高度来生成。若进一步,想实现摄像机在地形上行走的效果,就需要算出地形上任意一点的高度。总结了3个方法:
 
一:
《Introduction to 3D Game Programming With Directx 9.0》这本书里介绍的,利用向量来算。
11.jpg
 

 1 float  Terrain::GetHeight( float  x,  float  z)
 2 {
 3    //  Translate on xz-plane by the transformation that takes
 4   //  the terrain START point to the origin.
 5  x  =  (( float )_width  /   2.0f +  x;
 6  z  =  (( float )_depth  /   2.0f -  z;
 7   //  Scale down by the transformation that makes the 
 8   //  cellspacing equal to one.  This is given by 
 9   //  1 / cellspacing since; cellspacing * 1 / cellspacing = 1.
10  x  /=  ( float )_CellSpacing;
11  z  /=  ( float )_CellSpacing;
12   //  From now on, we will interpret our positive z-axis as
13   //  going in the 'down' direction, rather than the 'up' direction.
14   //  This allows to extract the row and column simply by 'flooring'
15   //  x and z:
16   float  col  =  ::floorf(x);
17   float  row  =  ::floorf(z);
18   //  get the heights of the quad we're in:
19   //  
20      //   A   B
21      //   *---*
22      //     | / |
23      //   *---*  
24      //   C   D
25   float  A  =  GetHeightMapEntry(row,   col);
26   float  B  =  GetHeightMapEntry(row,   col + 1 );
27   float  C  =  GetHeightMapEntry(row + 1 , col);
28   float  D  =  GetHeightMapEntry(row + 1 , col + 1 );
29   //
30   //  Find the triangle we are in:
31   //
32   //  Translate by the transformation that takes the upper-left
33   //  corner of the cell we are in to the origin.  Recall that our 
34   //  cellspacing was nomalized to 1.  Thus we have a unit square
35   //  at the origin of our +x -> 'right' and +z -> 'down' system.
36   float  dx  =  x  -  col;
37   float  dz  =  z  -  row;
38   //  Note the below compuations of u and v are unneccessary, we really
39   //  only need the height, but we compute the entire vector to emphasis
40   //  the books discussion.
41   float  height  =   0.0f ;
42   if (dz  <   1.0f   -  dx)   //  upper triangle ABC
43   {
44    float  uy  =  B  -  A;  //  A->B
45    float  vy  =  C  -  A;  //  A->C
46    //  Linearly interpolate on each vector.  The height is the vertex
47    //  height the vectors u and v originate from {A}, plus the heights
48    //  found by interpolating on each vector u and v.
49   height  =  A  +  Lerp( 0.0f , uy, dx)  +  Lerp( 0.0f , vy, dz);
50  }

51   else   //  lower triangle DCB
52   {
53    float  uy  =  C  -  D;  //  D->C
54    float  vy  =  B  -  D;  //  D->B
55    //  Linearly interpolate on each vector.  The height is the vertex
56    //  height the vectors u and v originate from {D}, plus the heights
57    //  found by interpolating on each vector u and v.
58   height  =  D  +  Lerp( 0.0f , uy,  1.0f   -  dx)  +  Lerp( 0.0f , vy,  1.0f   -  dz);
59  }

60   return  height;
61 }

62
 
用到的2个函数

1float Terrain::Lerp(float a, float b, float t)     //一个插值函数
2{
3 return (a - (a*t) + (b*t));
4}

5
6int Terrain::GetHeightMapEntry(int row, int col)         //读取高度函数
7{
8 return _heightmap[row * _numVertsPerRow + col];   // 高度图数据存在_heightmap里
9}

 
二:
先计算出摄像机所在三角形的平面方程,然后带入摄像机的X,Z坐标,即可得高度Y
具体实现过程见http://creatorchen1984.spaces.live.com/ 《获取地形上某一点高度》,写的十分详细
 
三:
网上找的一个方法
假设你的地形为terrain[][];用下面的函数求出地形上点(x,z);的y值,将人物的高度加上这个y值即可.
 1float GetHeight(GLfloat x, GLfloat z)
 2
 3float h=0;
 4float Xb,Yb;
 5int Xa,Ya;
 6Xa=(int)x;
 7Ya=(int)z;
 8Xb=x-Xa;
 9Yb=z-Ya;
10float a=terrain[Xa][Ya].y;
11float b=terrain[Xa+1][Ya].y;
12float c=terrain[Xa][Ya+1].y;
13float d=terrain[Xa+1][Ya+1].y;
14h=(a*(1-Xb)+b*Xb)*(1-Yb)+(c*(1-Xb)+d*Xb)*Yb;
15return h;
16}
 
17

posted @ 2007-11-15 19:26 小祥 阅读(954) | 评论 (0)编辑 收藏

     摘要: 这是一篇我所见过的关于指针的最好的入门级文章,它可使初学者在很短的时间内掌握复杂的指针操作。虽然,现在的Java、C#等语言已经取消了指针,但作为一个C++程序员,指针的直接操作内存,在数据操作方面有着速度快,节约内存等优点,仍是很多C++程序员的最爱。指针就像是一把良剑,就看你怎么去应用它! 什么是指针?  其实指针就像是其它变量一样,所不同的是一般的变量包含的是实际的真实的数据,而指针是一个指...  阅读全文

posted @ 2007-11-15 19:19 小祥 阅读(457) | 评论 (0)编辑 收藏

     摘要: 本文大部分内容翻译自Gil Gribb和Klaus Hartmann合写的《Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix》这篇文章,有兴趣的朋友可以搜索看下原文,里面DirectX下和OpenGL下的实现过程都说的很清楚,这里只说DirectX部分。 这里介绍的算法,可以直接从世界、观...  阅读全文

posted @ 2007-11-15 18:40 小祥 阅读(970) | 评论 (1)编辑 收藏