软件光栅器一之向量,顶点,矩阵
来源:互联网 发布:分享淘宝链接怎么赚钱 编辑:程序博客网 时间:2024/06/02 12:41
最近我完成了一个3D软件光栅器,也就是用CPU运行的小型3D渲染引擎,下面我就分为几个章节分别说下我实现的思路
一,向量,顶点,矩阵的表示。
(1) 向量,顶点
通常我们的向量和顶点都是用(x,y,z)表示,但是在3D图形学里,我们用(x,y,z,w)表示,那么在3D图形学里顶点和向量有什么区别呢?
在3D图形学里,顶点(Vertex)用(x,y,z,1.0)表示,而向量用(x,y,z,0.0)表示,为什么会这样呢?其实原因很多,第四个参数的引入可以让我们实现仿射变换,可以让我们在透视投影变换后用第四个参数保存相机空间的Z值,反正好处非常多,详细内容可参见http://blog.csdn.net/popy007/article/details/1797121
或者《Introduction+to+3D+Game+Programming+with+DirectX+11》第三章。
(2) 矩阵
在3D图形学里,我们用到的矩阵为4x4矩阵,用C++的二维数组来表示为 float[4][4], 如下面图所示:二,向量,顶点,矩阵的定义:
(1) 向量,顶点
代码实现:
/*----------------一,向量和顶点--------------*/struct Vector{float x, y, z, w;};typedef Vector Point;//构造一个顶点Point BuildPoint(float x, float y, float z){Point mPoint;mPoint.x = x;mPoint.y = y;mPoint.z = z;mPoint.w = 1.0f;return mPoint;}//构造一个向量Vector BuildVector(float x, float y, float z){Vector mVector;mVector.x = x;mVector.y = y;mVector.z = z;mVector.w = 0.0f;return mVector;}
(2) 矩阵
代码实现:
/*------------------二,矩阵-------------------*/struct Matrix{float ma[4][4];};
三,向量,顶点,矩阵的运算
(1) 向量点乘:
假设有两个向量Vector1 (x1,y1,z1,0) 和Vector2 (x2,y2,z2,0),公式如下:
代码实现:
//向量点乘(包括点和向量)float VectorDotProduct(const Vector* v1, const Vector* v2){float sum;sum = v1->x*v2->x + v1->y*v2->y + v1->z*v2->z + v1->w*v2->w;return sum;}
(2) 向量叉乘:
假设有两个向量Vector1 (x1,y1,z1,0) 和Vector2 (x2,y2,z2,0),公式如下:
代码实现:
//向量叉乘Vector VectorCrossProduct(const Vector* v1, const Vector* v2){Vector crossVector;float x1, y1, z1, x2, y2, z2;x1 = v1->x;y1 = v1->y;z1 = v1->z;x2 = v2->x;y2 = v2->y;z2 = v2->z;crossVector.w = 0.0f;crossVector.x = y1*z2 - z1*y2;crossVector.y = z1*x2 - x1*z2;crossVector.z = x1*y2 - y1*x2;return crossVector;}
(3) 向量规格化:
假设有存在一个向量Vector(x1,y1,z1,0),规格化后变为(x2,y2,z2,0),则x2*x2+y2*y2+z2*z2=1, 公式如下:
代码实现:
//向量规格化void VectorNormalize(Vector* v){float length =(float)sqrt(v->x*v->x + v->y*v->y + v->z*v->z);v->x = v->x / length;v->y = v->y / length;v->z = v->z / length;}
(4) 向量相减:
假设有两个向量Vector1 (x1,y1,z1,0) 和Vector2 (x2,y2,z2,0),公式如下:
//向量相减,左减去右Vector VectorSubtract(const Vector* v1, const Vector* v2){Vector vec;vec.x = v1->x - v2->x;vec.y= v1->y - v2->y;vec.z = v1->z - v2->z;vec.w = 0.0f;return vec;}
(5) 向量或者点乘以矩阵:
假设有一个向量或者顶点为(x,y,z,w),则顶点或者向量乘以矩阵的运算公式为
如果为顶点,也就是(x,y,z,1), 则运算公式为:
代码实现:
//向量进行矩阵变换, 对于不改变内容的函数形参加个constvoid VectorTransform(Vector* PointPtr, const Matrix* MaPtr){if (PointPtr == nullptr || MaPtr == nullptr){return;}else{//不能在中途改变点的值在用改变的点的值去计算,所以先保存顶点的XYZW值先float x = PointPtr->x;float y = PointPtr->y;float z = PointPtr->z;float w = PointPtr->w;//具体乘法,XPointPtr->x = x*MaPtr->ma[0][0] + y*MaPtr->ma[1][0] + z*MaPtr->ma[2][0] + w*MaPtr->ma[3][0];//具体乘法,YPointPtr->y = x*MaPtr->ma[0][1] + y*MaPtr->ma[1][1] + z*MaPtr->ma[2][1] + w*MaPtr->ma[3][1];//具体乘法,ZPointPtr->z = x*MaPtr->ma[0][2] + y*MaPtr->ma[1][2] + z*MaPtr->ma[2][2] + w*MaPtr->ma[3][2];//具体乘法,WPointPtr->w = x*MaPtr->ma[0][3] + y*MaPtr->ma[1][3] + z*MaPtr->ma[2][3] + w*MaPtr->ma[3][3];}}
(6) 矩阵乘以矩阵:
假设有两个矩阵A和B,A*B得到C矩阵
代码实现:
//矩阵乘法Matrix MatrixMultiply(const Matrix* ma1, const Matrix* ma2){Matrix matrix;//清除为0ZeroMemory(&matrix, sizeof(matrix));//矩阵乘法for (int i = 0; i < 4; ++i){for (int j = 0; j < 4; ++j){for (int k = 0; k < 4; ++k){matrix.ma[i][j] += ma1->ma[i][k] * ma2->ma[k][j];}}}return matrix;}
0 0
- 软件光栅器一之向量,顶点,矩阵
- 软件光栅器三之世界矩阵,相机变换矩阵,透视投影矩阵,透视除法,视口变换矩阵
- 软件光栅化渲染器(一)
- 软件光栅化渲染器一
- OpenCV矩阵运算之顶点法向量计算
- 顶点法向量的矩阵变换
- 软件光栅器六之透视纹理映射
- 软件光栅器的设计思想
- 软件光栅化渲染器(二)
- 软件光栅化渲染器(三)
- 软件光栅化渲染器(四)
- 软件光栅化渲染器(五)
- 软件光栅化渲染器(六)
- 软件光栅化渲染器(七)
- 软件光栅化渲染器(八)
- 软件光栅化渲染器(九)
- 软件光栅化渲染器(十)
- 软件光栅化渲染器二
- kali Linux渗透测试介绍
- ubuntu下安装eclipse IDE for C/C++
- csdn的第一次博客
- NIO
- JavaScript中this的用法
- 软件光栅器一之向量,顶点,矩阵
- Machine Learning Week One
- HDU 5988 Coding Contest 最小费用流变形
- Android学习 (二十) 在fragment里用Intent跳转到其他Activity
- 两有序链表合并为一个--递归与非递归两种方式
- 全排列acc pascal程序加题解
- 最新十款数据恢复软件介绍【免费】
- 三层架构
- DOM文档对象模型——学习总结