level 0
看看这里吧,三维编码黑洞教程:http://glpro.go.nease.net/art/3dhole.gl
2005年05月28日 02点05分
2
level 0
但是我们不要忘记变换中间用到的坐标系,例如: ·世界坐标系:相对于3D世界的原点三维坐标系。 ·对齐(视点)坐标系:世界坐标系的变换,观察者的位置在世界坐标系的原点。 下面是坐标的基本结构: // 二维坐标 typedef struct { short x, y; } _2D; // 三维坐标 typedef struct { float x, y, z; } _3D; 这里,我们定义了称为顶点的坐标结构。因为“顶点”一词指两个或两个以上菱形边的交点。我们的顶点可以简单地认为是描述不同系统的矢量。 // 不同的坐标系的坐标 typedef struct { _3D Local; _3D World; _3D Aligned; } Vertex_t; 2.2 实现矩阵系统 我们需要存储我们的矩阵在4x4浮点数矩阵中。所以当我们需要做变换是我们定义如下矩阵: float matrix[4][4]; 然后我们定义一些函数来拷贝临时矩阵到全局矩阵: void MAT_Copy(float source[4][4], float dest[4][4]) { int i,j; for(i=0; i<4; i++) for(j=0; j<4; j++) dest[i][j]=source[i][j]; } 很简单。现在我们来写两个矩阵相乘的函数。同时可以理解上面的一些有关矩阵相乘的公式代码如下: void MAT_Mult(float mat1[4][4], float mat2[4][4], float dest[4][4]) { // mat1 — 矩阵1 // mat2 — 矩阵2 // dest — 相乘后的新矩阵 int i,j; for(i=0; i<4; i++) for(j=0; j<4; j++) dest[i][j] = mat1[i][0]*mat2[0][j]+ mat1[i][1]*mat2[1][j]+ mat1[i][2]*mat2[2][j]+ mat1[i][3]*mat2[3][j]; } 现在你明白了吗?现在我们设计矢量与矩阵相乘的公式。 void VEC_MultMatrix(_3D *Source,float mat[4][4],_3D *Dest) { // Source — 源矢量(坐标) // mat — 变换矩阵 // Dest — 目标矩阵(坐标) Dest->x = Source->x*mat[0][0]+ Source->y*mat[1][0]+ Source->z*mat[2][0]+ mat[3][0]; Dest->y = Source->x*mat[0][1]+ Source->y*mat[1][1]+ Source->z*mat[2][1]+ mat[3][1]; Dest->z = Source->x*mat[0][2]+ Source->y*mat[1][2]+ Source->z*mat[2][2]+ mat[3][2]; } 我们已经得到了矩阵变换函数,不错吧。注意:这里的矩阵变换与我们学过的矩阵变换不同。一般的,Y = TX,T为变换矩阵,这里为Y = XT,是由于矩阵T为4x4矩阵。 2.3 实现三角法系统 几乎每一个C编译器都带有有三角函数的数学库,但是我们需要简单的三角函数时,不是每次都使用它们。正弦和余弦的计算是阶乘和除法的大量运算。为提高计算速度,我们建立自己的三角函数表。首先决定你需要的角度的个数,然后在这些地方用下面的值代替: float SinTable[256], CosTable[256]; 然后使用宏定义,它会把每一个角度变成正值,并对于大于360度的角度进行周期变换,然后返回需要的值。如果需要的角度数是2的幂次,那么我们可以使用“&”代替“%”,它使程序运行更快。例如256。所以在程序中尽量选取2的幂次。 // 三角法系统 #define SIN(x) SinTable[ABS((int)x&255)] #define COS(x) CosTable[ABS((int)x&255)] 一旦我们已经定义了需要的东西,建立初始化函数,并且在程序中调用宏。
2005年06月20日 00点06分
5
level 0
void M3D_Init() { int d; for(d=0; d<256; d++) { SinTable[d]=sin(d*PI/128.0); CosTable[d]=cos(d*PI/128.0); } } 2.4 建立变换矩阵 下面使用C编写的变换矩阵代码。 float mat1[4][4], mat2[4][4]; // 定义单位阵 void MAT_Identity(float mat[4][4]) { mat[0][0]=1; mat[0][1]=0; mat[0][2]=0; mat[0][3]=0; mat[1][0]=0; mat[1][1]=1; mat[1][2]=0; mat[1][3]=0; mat[2][0]=0; mat[2][1]=0; mat[2][2]=1; mat[2][3]=0; mat[3][0]=0; mat[3][1]=0; mat[3][2]=0; mat[3][3]=1; } // tx,ty.tz — 平移参数 // matrix — 源矩阵和目标矩阵 // 矩阵平移函数 void TR_Translate(float matrix[4][4],float tx,float ty,float tz) { float tmat[4][4]; tmat[0][0]=1; tmat[0][1]=0; tmat[0][2]=0; tmat[0][3]=0; tmat[1][0]=0; tmat[1][1]=1; tmat[1][2]=0; tmat[1][3]=0; tmat[2][0]=0; tmat[2][1]=0; tmat[2][2]=1; tmat[2][3]=0; tmat[3][0]=tx; tmat[3][1]=ty; tmat[3][2]=tz; tmat[3][3]=1; MAT_Mult(matrix,tmat,mat1); MAT_Copy(mat1,matrix); } // 矩阵缩放 void TR_Scale(float matrix[4][4],float sx,float sy, float sz) { float smat[4][4]; smat[0][0]=sx; smat[0][1]=0; smat[0][2]=0; smat[0][3]=0; smat[1][0]=0; smat[1][1]=sy; smat[1][2]=0; smat[1][3]=0; smat[2][0]=0; smat[2][1]=0; smat[2][2]=sz;smat[2][3]=0; smat[3][0]=0; smat[3][1]=0; smat[3][2]=0; smat[3][3]=1; MAT_Mult(matrix,smat,mat1); MAT_Copy(mat1,matrix); } // ax — 绕X轴旋转的角度 // ay — 绕Y轴旋转的角度 // az — 绕Z轴旋转的角度 // 矩阵旋转 void TR_Rotate(float matrix[4][4],int ax,int ay,int az) { float xmat[4][4], ymat[4][4], zmat[4][4]; xmat[0][0]=1; xmat[0][1]=0; xmat[0][2]=0; xmat[0][3]=0; xmat[1][0]=0; xmat[1][1]=COS(ax); xmat[1][2]=SIN(ax); xmat[1][3]=0; xmat[2][0]=0; xmat[2][1]=-SIN(ax); xmat[2][2]=COS(ax); xmat[2][3]=0; xmat[3][0]=0; xmat[3][1]=0; xmat[3][2]=0; xmat[3][3]=1; ymat[0][0]=COS(ay); ymat[0][1]=0; ymat[0][2]=-SIN(ay); ymat[0][3]=0; ymat[1][0]=0; ymat[1][1]=1; ymat[1][2]=0; ymat[1][3]=0; ymat[2][0]=SIN(ay); ymat[2][1]=0; ymat[2][2]=COS(ay); ymat[2][3]=0; ymat[3][0]=0; ymat[3][1]=0; ymat[3][2]=0; ymat[3][3]=1; zmat[0][0]=COS(az); zmat[0][1]=SIN(az); zmat[0][2]=0; zmat[0][3]=0; zmat[1][0]=-SIN(az); zmat[1][1]=COS(az); zmat[1][2]=0; zmat[1][3]=0; zmat[2][0]=0; zmat[2][1]=0; zmat[2][2]=1; zmat[2][3]=0; zmat[3][0]=0; zmat[3][1]=0; zmat[3][2]=0; zmat[3][3]=1; MAT_Mult(matrix,ymat,mat1); MAT_Mult(mat1,xmat,mat2); MAT_Mult(mat2,zmat,matrix); } 2.5 如何建立透视 如何建立对象的立体视觉,即显示器上的一些事物看起来离我们很近,而另外一些事物离我们很远。透视问题一直是困绕我们的一个问题。有许多方法被使用。我们使用的3D世界到2D屏幕的投影公式:
2005年06月20日 00点06分
6
level 0
#define MIN(a,b) ((a
b)?(a):(b)) #define MaxPoint(a,b) ((a.y > b.y) ? a : b) #define MinPoint(a,b) ((b.y > a.y) ? a : b) 然后我们定义三个宏来区别三个点: #define MaxPoint3(a,b,c) MaxPoint(MaxPoint(a,b),MaxPoint(b,c)) #define MidPoint3(a,b,c) MaxPoint(MinPoint(a,b),MinPoint(a,c)) #define MinPoint3(a,b,c) MinPoint(MinPoint(a,b),MinPoint(b,c)) 你也许注意到MidPoint3宏不总是正常地工作,取决于三个点排列的顺序。例如,a
2005年06月20日 00点06分
8
level 1
很详细,也很混乱,简单来说几话就可以解决了,设置顶点缓存,设置索引缓存,设置纹理,还应当设置灯光,材质,以及三大矩阵等,恩,不罗嗦了
2006年12月26日 12点12分
14
level 0
下一个directx sdk ,上面就有一些例子。。。
2008年08月11日 14点08分
16