尝试用C++写一个简单的小模型案例Billiard,来模拟图形绘制和数学渲染。基于MicroSoft的Win10和VS2017开发,如果有时间,我会继续完善。同时因为规模小,暂时就命名为Billiard。
成品完整代码见百度网盘 terryzhk:
-----------------------------------------------------------------------------------------------
首先,我们自己搭建一个数学库,以供我们后续使用,整个数学库的结构如下:
Vector:用来定义向量以及各种相关运算。
Matrix:用来定义矩阵以及各种相关运算。
MathUtil:用来构造数学工具,实现插值,仿射变换等。
LoadBitmap:我们使用Gdiplus.dll这个库来读取图片像素颜色信息。
Texture2D:把我们的2D图片进行纹理寻址,从而显示出来。
Vertex:自己定义一个简单的顶点着色器。
Math:包含我们的数学库以供方便使用。
1 Matrix.h
定义矩阵。
初始化,置0,相等,加法,减法,乘法,除法。
#pragma once
#include <cmath>
class MMatrix
{
public:
union
{
float m[4][4];
struct
{
float _11; float _12; float _13; float _14;
float _21; float _22; float _23; float _24;
float _31; float _32; float _33; float _34;
float _41; float _42; float _43; float _44;
};
};
public:
MMatrix() = default;
MMatrix(float a1,float a2,float a3,float a4,
float b1,float b2,float b3,float b4,
float c1,float c2,float c3,float c4,
float d1,float d2,float d3,float d4)
{
_11 = a1; _12 = a2; _13 = a3; _14 = a4;
_21 = b1; _22 = b2; _23 = b3; _24 = b4;
_31 = c1; _32 = c2; _33 = c3; _34 = c4;
_41 = d1; _42 = d2; _43 = d3; _44 = d4;
}
MMatrix(const MMatrix& rhs)
{
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
m[i][j] = rhs.m[i][j];
}
MMatrix& operator= (const MMatrix& rhs)
{
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
m[i][j] = rhs.m[i][j];
return *this;
}
public:
// identify a matrix
void Identity();
// get a 0 matrix
void SetZero();
// =
bool operator== (const MMatrix& rhs) const;
// +
MMatrix operator+ (const MMatrix& rhs) const;
// -
MMatrix operator- (const MMatrix& rhs) const;
// *
MMatrix operator* (const MMatrix& rhs) const;
};
1.2 Matrix.cpp
矩阵运算。
矩阵相等,加法,减法,乘法。
#include "MMatrix.h"
void MMatrix::Identity()
{
_11 = 1.f; _12 = 0.f; _13 = 0.f; _14 = 0.f;
_21 = 0.f; _22 = 1.f; _23 = 0.f; _24 = 0.f;
_31 = 0.f; _32 = 0.f; _33 = 1.f; _34 = 0.f;
_41 = 0.f; _42 = 0.f; _43 = 0.f; _44 = 1.f;
}
void MMatrix::SetZero()
{
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
m[i][j] = 0.0f;
}
// M1 == M2 / left hand side = right hand side
bool MMatrix::operator==(const MMatrix& rhs) const
{
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
if (abs(m[i][j] - rhs.m[i][j]) >= 0.000001f)
return false;
return true;
}
//M1 = M2 + M3
MMatrix MMatrix::operator+(const MMatrix& rhs) const
{
MMatrix matrix;
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
matrix.m[i][j] = m[i][j] + rhs.m[i][j];
return matrix;
}
//M1 = M2 - M3
MMatrix MMatrix::operator-(const MMatrix& rhs) const
{
MMatrix matrix;
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
matrix.m[i][j] = m[i][j] - rhs.m[i][j];
return matrix;
}
//M1 = M2 * M3
MMatrix MMatrix::operator*(const MMatrix& rhs) const
{
MMatrix matrix;
for (int i = 0; i < 4; ++i)
for(int j = 0; j < 4; ++j)
{
matrix.m[j][i] = (m[j][0] * rhs.m[0][i]) +
(m[j][1] * rhs.m[1][i]) +
(m[j][2] * rhs.m[2][i]) +
(m[j][3] * rhs.m[3][i]);
}
return matrix;
}
2.1 Vector.h
定义向量。
向量求模长,归一化,点乘,叉乘,与矩阵,向量,数字运算。
自定义三维向量结构,二维向量结构。
#pragma once
#include <cmath>
#include "MMatrix.h"
class MVector
{
public:
float x;
float y;
float z;
float w; //homogeneous coordinates,0->vector, 1->dot
public:
MVector() = default;
MVector(float x1, float y1, float z1, float w1 = 0) :x(x1), y(y1), z(z1), w(w1) {}
MVector(const MVector& rhs) :x(rhs.x), y(rhs.y), z(rhs.z), w(rhs.w) {}
MVector& operator= (const MVector& rhs)
{
if (this == &rhs)
return *this;
x = rhs.x;
y = rhs.y;
z = rhs.z;
w = rhs.w;
return *this;
}
public:
// length of the vector
float Length() const;
// normalize a vector
MVector Normalize();
// dot product
float Dot(MVector v) const;
// cross product
MVector Cross(MVector rhs) const;
// vector1 == vector2
bool operator==(const MVector& rhs) const;
// vertor * matrix
MVector operator* (const MMatrix& rhs) const;
// verctor * vector
MVector operator* (const MVector& rhs) const;
// vector * float
MVector operator*(float factor) const;
// +
MVector operator+ (const MVector& rhs) const;
// -
MVector operator- (const MVector& rhs) const;
// negate
MVector operator-() const;
};
class MFLOAT3
{
public:
float x;
float y;
float z;
public:
MFLOAT3() = default;
MFLOAT3(float r,float b,float g):x(r),y(b),z(g){}
MFLOAT3(const MFLOAT3& rhs) :x(rhs.x), y(rhs.y), z(rhs.z) {}
MFLOAT3& operator= (const MFLOAT3& rhs)
{
if (this == &rhs)
return *this;
x = rhs.x;
y = rhs.y;
z = rhs.z;
return *this;
}
};
// to show texture
class MFLOAT2
{
public:
float u;
float v;
public:
MFLOAT2() = default;
MFLOAT2(float x, float y) :u(x), v(y) {}
MFLOAT2(const MFLOAT2& rhs):u(rhs.u),v(rhs.v){}
MFLOAT2& operator= (const MFLOAT2& rhs)
{
if (this == &rhs)
return *this;
u = rhs.u;
v = rhs.v;
return *this;
}
};
2.2 Vector.cpp
向量运算很简单。
向量各种基础运算。
3.1 MathUtil.h
各种常用数学计算,如插值,转置,仿射变换等。
#pragma once
#include "MVector.h"
#include "MMatrix.h"
#include "Vertex.h"
#include <windows.h>
#include <cmath>
#include <vector>
namespace MathUtil
{
extern const float PI;
//线性插值 t位于[0,1]
float Lerp(float x1, float x2, float t);
//矢量插值
MVector Lerp(const MVector& v1, const MVector& v2, float t);
//ZCFLOAT2 插值
MFLOAT2 Lerp(const MFLOAT2& v1, const MFLOAT2& v2, float t);
//ZCFLOAT3插值
MFLOAT3 Lerp(const MFLOAT3& v1, const MFLOAT3& v2, float t);
//VertexOut插值
VertexOut Lerp(const VertexOut& v1, const VertexOut& v2, float t);
//clamp
float Clamp(float x, float min, float max);
//角度转弧度
inline float MConvertToRadians(float fDegrees) { return fDegrees * (PI / 180.0f); }
//向量长度
float Length(const MVector& v);
//单位矩阵
MMatrix MMatrixIdentity();
//矩阵转置
MMatrix MMatrixTranspose(const MMatrix& mat);
//矩阵对应行列式
float MMatrixDet(const MMatrix& mat);
//伴随矩阵中的每一项 3*3矩阵对应的行列式值
float MMatrixAdjElem(
float a1, float a2, float a3,
float b1, float b2, float b3,
float c1, float c2, float c3);
//伴随矩阵 代数余子式组成的矩阵的转置
MMatrix MMatrixAdj(const MMatrix& mat);
//逆矩阵 = 伴随矩阵/(行列式值的绝对值)
MMatrix MMatrixInverse(const MMatrix& mat);
//缩放矩阵
MMatrix MMatrixScaling(float scaleX, float scaleY, float scaleZ);
//平移矩阵
MMatrix MMatrixTranslate(float offsetX, float offsetY, float offsetZ);
//绕x轴旋转矩阵
MMatrix MMatrixRotationX(float angle);
//绕y轴旋转矩阵
MMatrix MMatrixRotationY(float angle);
//绕z轴旋转矩阵
MMatrix MMatrixRotationZ(float angle);
//获取视角矩阵
MMatrix MMatrixLookAtLH(MVector eyePos, MVector lookAt, MVector up);
//获取投影矩阵 同dx中的XMMatrixPerspectiveFovLH
// 观察角 宽高比 近裁剪平面 远裁剪平面
MMatrix MMatrixPerspectiveFovLH(float fovAngleY, float aspectRatio, float nearZ, float farZ);
//投影出来的坐标到屏幕坐标变换矩阵
MMatrix MMatrixScreenTransform(int clientWidth, int clientHeight);
//颜色ZCVector(r,b,g,a)转化为UINT
UINT ColorToUINT(const MVector& color);
//求入射向量关于法线的反射向量
MVector Reflect(const MVector& vin, const MVector& normal);
}
3.2 MathUtil.cpp
插值:通过因子t使离散值逼近。
仿射变换:矩阵的基础运算。
#include "MathUtil.h"
const float MathUtil::PI = 3.1415926f;
//线性插值 t位于[0,1]
inline float MathUtil::Lerp(float x1, float x2, float t)
{
return x1 + (x2 - x1)*t;
}
//矢量插值
MVector MathUtil::Lerp(const MVector& v1, const MVector& v2, float t)
{
return MVector(
Lerp(v1.x, v2.x, t),
Lerp(v1.y, v2.y, t),
Lerp(v1.z, v2.z, t),
v1.w
);
}
//ZCFLOAT2 插值
MFLOAT2 MathUtil::Lerp(const MFLOAT2& v1, const MFLOAT2& v2, float t)
{
return MFLOAT2(
Lerp(v1.u, v2.u, t),
Lerp(v1.v, v2.v, t)
);
}
//ZCFLOAT3 插值
MFLOAT3 MathUtil::Lerp(const MFLOAT3& v1, const MFLOAT3& v2, float t)
{
return MFLOAT3(
Lerp(v1.x, v2.x, t),
Lerp(v1.y, v2.y, t),
Lerp(v1.z, v2.z, t)
);
}
//VertexOut 插值
VertexOut MathUtil::Lerp(const VertexOut& v1, const VertexOut& v2, float t)
{
return VertexOut(
Lerp(v1.posTrans, v2.posTrans, t),
Lerp(v1.posH, v2.posH, t),
Lerp(v1.tex, v2.tex, t),
Lerp(v1.normal, v2.normal, t),
Lerp(v1.color, v2.color, t),
Lerp(v1.oneDivZ, v2.oneDivZ, t)
);
}
//clamp
float MathUtil::Clamp(float x, float min, float max)
{
if (x <= min)
return min;
else if (x >= max)
return max;
return x;
}
//向量长度
float MathUtil::Length(const MVector& v)
{
return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
}
//单位矩阵
MMatrix MathUtil::MMatrixIdentity()
{
return MMatrix(1.f, 0.f, 0.f, 0.f,
0.f, 1.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, 0.f, 0.f, 1.f);
}
//矩阵转置
MMatrix MathUtil::MMatrixTranspose(const MMatrix& mat)
{
return MMatrix(mat._11, mat._21, mat._31, mat._41,
mat._12, mat._22, mat._32, mat._42,
mat._13, mat._23, mat._33, mat._43,
mat._14, mat._24, mat._34, mat._44);
}
//矩阵对应行列式
/************************************************************************/
/* a11a22a33a44 - a11a22a34a43 - a11a23a32a44 + a11a23a34a42
+ a11a24a32a43 - a11a24a33a42 - a12a21a33a44 + a12a21a34a43
+ a12a23a31a44 - a12a23a34a41 - a12a24a31a43 + a12a24a33a41
+ a13a21a32a44 - a13a21a34a42 - a13a22a31a44 + a13a22a34a41
+ a13a24a31a42 - a13a24a32a41 - a14a21a32a43 + a14a21a33a42
+ a14a22a31a43 - a14a22a33a41 - a14a23a31a42 + a14a23a32a41 */
/************************************************************************/
float MathUtil::MMatrixDet(const MMatrix& mat)
{
float result =
mat._11*mat._22*mat._33*mat._44 - mat._11*mat._22*mat._34*mat._43 -
mat._11*mat._23*mat._32*mat._44 + mat._11*mat._23*mat._34*mat._42 +
mat._11*mat._24*mat._32*mat._43 - mat._11*mat._24*mat._33*mat._42 -
mat._12*mat._21*mat._33*mat._44 + mat._12*mat._21*mat._34*mat._43 +
mat._12*mat._23*mat._31*mat._44 - mat._12*mat._23*mat._34*mat._41 -
mat._12*mat._24*mat._31*mat._43 + mat._12*mat._24*mat._33*mat._41 +
mat._13*mat._21*mat._32*mat._44 - mat._13*mat._21*mat._34*mat._42 -
mat._13*mat._22*mat._31*mat._44 + mat._13*mat._22*mat._34*mat._41 +
mat._13*mat._24*mat._31*mat._42 - mat._13*mat._24*mat._32*mat._41 -
mat._14*mat._21*mat._32*mat._43 + mat._14*mat._21*mat._33*mat._42 +
mat._14*mat._22*mat._31*mat._43 - mat._14*mat._22*mat._33*mat._41 -
mat._14*mat._23*mat._31*mat._42 + mat._14*mat._23*mat._32*mat._41;
return result;
}
//伴随矩阵中的每一项 3*3矩阵对应的行列式值
float MathUtil::MMatrixAdjElem(
float a1, float a2, float a3,
float b1, float b2, float b3,
float c1, float c2, float c3)
{
return a1*(b2*c3 - c2*b3) - a2*(b1*c3 - c1*b3) + a3*(b1*c2 - c1*b2);
}
//伴随矩阵 代数余子式组成的矩阵的转置
MMatrix MathUtil::MMatrixAdj(const MMatrix& mat)
{
float a1 = MMatrixAdjElem(mat._22, mat._23, mat._24, mat._32, mat._33, mat._34, mat._42, mat._43, mat._44);
float a2 = MMatrixAdjElem(mat._21, mat._23, mat._24, mat._31, mat._33, mat._34, mat._41, mat._43, mat._44);
...//简单的数学计算,此处可见源码。
MMatrix result(
a1, -a2, a3, -a4,
-b1, b2, -b3, b4,
c1, -c2, c3, -c4,
-d1, d2, -d3, d4
);
return MMatrixTranspose(result);
}
//逆矩阵 = 伴随矩阵/(行列式值的绝对值)
MMatrix MathUtil::MMatrixInverse(const MMatrix& mat)
{
float det = abs(MMatrixDet(mat));
MMatrix adj = MMatrixAdj(mat);
MMatrix inverse;
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
{
inverse.m[i][j] = adj.m[i][j] / det;
}
return inverse;
}
//缩放矩阵
MMatrix MathUtil::MMatrixScaling(float scaleX, float scaleY, float scaleZ)
{
return MMatrix(
scaleX, 0, 0, 0,
0, scaleY, 0, 0,
0, 0, scaleZ, 0,
0, 0, 0, 1
);
}
//平移矩阵
MMatrix MathUtil::MMatrixTranslate(float offsetX, float offsetY, float offsetZ)
{
return MMatrix(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
offsetX, offsetY, offsetZ, 1
);
}
//绕x轴旋转矩阵
MMatrix MathUtil::MMatrixRotationX(float angle)
{
return MMatrix(
1, 0, 0, 0,
0, cos(angle), sin(angle), 0,
0, -sin(angle), cos(angle), 0,
0, 0, 0, 1
);
}
//绕y轴旋转矩阵
MMatrix MathUtil::MMatrixRotationY(float angle)
{
return MMatrix(
cos(angle), 0, -sin(angle), 0,
0, 1, 0, 0,
sin(angle), 0, cos(angle), 0,
0, 0, 0, 1
);
}
//绕z轴旋转矩阵
MMatrix MathUtil::MMatrixRotationZ(float angle)
{
return MMatrix(
cos(angle), sin(angle), 0, 0,
-sin(angle), cos(angle), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
}
//获取视角矩阵
MMatrix MathUtil::MMatrixLookAtLH(MVector eyePos, MVector lookAt, MVector up)
{
MVector zaxis = lookAt - eyePos;
zaxis.Normalize();
MVector xaxis = up.Cross(zaxis).Normalize();
MVector yaxis = zaxis.Cross(xaxis);
return MMatrix(
xaxis.x, yaxis.x, zaxis.x, 0,
xaxis.y, yaxis.y, zaxis.y, 0,
xaxis.z, yaxis.z, zaxis.z, 0,
-xaxis.Dot(eyePos), -yaxis.Dot(eyePos), -zaxis.Dot(eyePos), 1
);
}
//获取投影矩阵 同dx中的XMMatrixPerspectiveFovLH
// 观察角 宽高比 近裁剪平面 远裁剪平面
MMatrix MathUtil::MMatrixPerspectiveFovLH(float fovAngleY, float aspectRatio, float nearZ, float farZ)
{
MMatrix mat;
mat.SetZero();
// tan(fovAngleY*0.5f)
float height = cos(fovAngleY*0.5f) / sin(fovAngleY*0.5f);
mat._11 = height / aspectRatio;
mat._22 = height;
mat._33 = farZ / (farZ - nearZ);
mat._34 = 1.f;
mat._43 = (nearZ * farZ) / (nearZ - farZ);
return mat;
}
MMatrix MathUtil::MMatrixScreenTransform(int clientWidth, int clientHeight)
{
return MMatrix(
clientWidth / 2, 0, 0, 0,
0, clientHeight / 2, 0, 0,
0, 0, 1, 0,
clientWidth / 2, clientHeight / 2, 0, 1
);
}
//颜色ZCFloat3(r,b,g,a)转化为UINT
UINT MathUtil::ColorToUINT(const MVector& color)
{
BYTE red = 255 * color.x/* color.w*/;
BYTE green = 255 * color.y/* color.w*/;
BYTE blue = 255 * color.z /* color.w*/;
return (UINT)((BYTE)blue | (WORD)((BYTE)green << 8) | (DWORD)((BYTE)red << 16));
}
//求反射向量
MVector MathUtil::Reflect(const MVector& I, const MVector& N)
{
//公式 R = I - 2(I·N)N
float tmp = 2.f * I.Dot(N);
return I - (N * tmp);
}
4.1 Texture2D.h
读取图片,深拷贝。
#pragma once
#include <windows.h>
#include "MVector.h"
class Texture2D
{
public:
Texture2D() = default;
Texture2D(UINT width,UINT height);
~Texture2D();
Texture2D(const Texture2D& rhs) :m_width(rhs.m_width), m_height(rhs.m_height)
{
// deep copy
m_pixelBuffer = new MVector*[m_width];
for (int i = 0; i < m_width; ++i)
{
m_pixelBuffer[i] = new MVector[m_height];
}
for (int i = 0; i < m_width; ++i)
{
for (int j = 0; j < m_height; ++j)
{
m_pixelBuffer[i][j] = rhs.m_pixelBuffer[i][j];
}
}
}
Texture2D& operator=(const Texture2D& rhs)
{
if (this == &rhs)
return *this;
m_width = rhs.m_width;
m_height = rhs.m_height;
m_pixelBuffer = new MVector*[m_width];
for (int i = 0; i < m_width; ++i)
{
m_pixelBuffer[i] = new MVector[m_height];
}
for (int i = 0; i < m_width; ++i)
{
for (int j = 0; j < m_height; ++j)
{
m_pixelBuffer[i][j] = rhs.m_pixelBuffer[i][j];
}
}
return *this;
}
public:
MVector Sample(const MFLOAT2& tex);
public:
UINT m_width;
UINT m_height;
MVector** m_pixelBuffer;
};
4.2 Texture.cpp
纹理寻址,左手坐标系。
#include "Texture2D.h"
Texture2D::Texture2D(UINT width, UINT height)
{
m_width = width;
m_height = height;
m_pixelBuffer = new MVector*[width];
for (int i = 0; i < width; ++i)
{
m_pixelBuffer[i] = new MVector[height];
}
}
Texture2D::~Texture2D()
{
if (m_pixelBuffer)
{
for (int i = 0; i < m_width; ++i)
{
delete[] m_pixelBuffer[i];
}
}
}
MVector Texture2D::Sample(const MFLOAT2& tex)
{
//纹理寻址采用d3d中的wrap方式 当坐标大于1时,通过去掉整数部分,根据得到的小数部分来得到纹理值;
//坐标小于0,则加上一个最小正数,让坐标大于0。
if (tex.u >= 0 && tex.u <= 1 && tex.v >= 0 && tex.v <= 1)
{
UINT x = tex.u * (m_width - 1);
UINT y = tex.v * (m_height - 1);
return m_pixelBuffer[x][y];
}
else
{
float u, v;
if (tex.u > 1)
u = tex.u - static_cast<int>(tex.u);
else if (tex.u < 0)
u = (static_cast<int>(-tex.u) + 1) + tex.u;
if (tex.v > 1)
v = tex.v - static_cast<int>(tex.v);
else if (tex.v < 0)
v = (static_cast<int>(-tex.v) + 1) + tex.v;
UINT x = u * (m_width - 1);
UINT y = v * (m_height - 1);
return m_pixelBuffer[x][y];
}
}
5.1 LoadBitmap.cpp
加载位图,取得像素颜色。
#include "LoadBitmap.h"
#include <windows.h>
#include <gdiplus.h>
#include <iostream>
#include <fstream>
#include <sstream>
#pragma comment(lib, "gdiplus.lib")
using namespace std;
using namespace Gdiplus;
Texture2D MathUtil::LoadBitmapToColorArray(wstring filePath)
{
GdiplusStartupInput gdiplusstartupinput;
ULONG_PTR gdiplustoken;
GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, nullptr);
Bitmap* bmp = new Bitmap(filePath.c_str());
if (!bmp)
{
MessageBox(nullptr, "error", "picture path is null!", MB_OK);
delete bmp;
GdiplusShutdown(gdiplustoken);
return Texture2D(0,0);
}
else
{
UINT height = bmp->GetHeight();
UINT width = bmp->GetWidth();
//初始化Texture2D
Texture2D texture(width, height);
Color color;
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
{
bmp->GetPixel(x, y, &color);
texture.m_pixelBuffer[x][height - 1 - y] = MVector(
color.GetRed() / 255.f,
color.GetGreen() / 255.f,
color.GetBlue() / 255.f,
1.f
);
}
delete bmp;
GdiplusShutdown(gdiplustoken);
return texture;
}
}
6.1 Vertex.h
自定义的定点着色器,含有位置,法线,贴图等信息。
自定义结构:VertexIn经过vertex shader后输出VertexOut。
#pragma once
#include "MVector.h"
//info of a vertex
class VertexIn
{
public:
// position
MVector pos;
// color
MVector color;
// texture
MFLOAT2 tex;
// normal
MVector normal;
VertexIn() = default;
VertexIn(MVector pos, MVector color, MFLOAT2 tex, MVector normal)
:pos(pos), color(color), tex(tex), normal(normal) {}
VertexIn(const VertexIn& rhs):pos(rhs.pos),color(rhs.color),tex(rhs.tex),normal(rhs.normal){}
};
// VertexIn -> vertex shader -> VertexOut
class VertexOut
{
public:
// pos -> world transformation -> posTrans
MVector posTrans;
// pos -> projection transformation -> posH
MVector posH;
// texture
MFLOAT2 tex;
// normal
MVector normal;
// color
MVector color;
// 1/z depth testing
float oneDivZ;
VertexOut() = default;
VertexOut(MVector posT, MVector posH, MFLOAT2 tex, MVector normal, MVector color, float oneDivZ)
:posTrans(posT), posH(posH), tex(tex), normal(normal), color(color), oneDivZ(oneDivZ) {}
VertexOut(const VertexOut& rhs) :posTrans(rhs.posTrans), posH(rhs.posH), tex(rhs.tex), normal(rhs.normal),
color(rhs.color),oneDivZ(rhs.oneDivZ){}
VertexOut& operator= (const VertexOut& rhs)
{
if (this == &rhs)
return *this;
this->normal = rhs.normal;
this->posH = rhs.posH;
this->posTrans = rhs.posTrans;
this->tex = rhs.tex;
this->color = rhs.color;
this->oneDivZ = rhs.oneDivZ;
return *this;
}
};
暂时先把可能用到的各部分数学结构写好,方便我们以后使用。
有的朋友可能会有疑问,数学工具浩若烟海,为啥要重新造轮子呢?
我们当然知道使用Mathmatica,Matlab,Maple,Telax等软件的方便了……
如果能用上述软件运行出结果何乐不为?
但是科学模拟和数学试验有时就需要科学工作者和数学家去DIY。
重新造好轮子就是逼不得已和饶有趣味的事了。
- vs2017宇宙最伟大IDE用Console等调试汇总
- c++Win32起始鼠标作图181101
- 用迭代法找(两圆的)交点-精确计算迭代并改进-数值周期1810
- 精度-比例关系181110P2点
- 用迭代法求找两圆交点-精度计算181111A
- 月亮型-大小圆-上下圆算法181121
- 用c++的数学计算及图形绘制总结之1/共4-181101
- 用c++做数学计算及图形绘制总结之2/4-181102
- 用c++做数学计算及图形绘制总结之3/4-181103
- 用c++做数学计算及图形绘制总结4/4-181104
- 用c++的移位代替乘除运算181105
- 重构billiard2圆相交-非递归181101-非预料内图形-原因分析181201
- 重构月亮型billiard202圆相交-非递归181102-非预料内图形-原因分析181202
- 重构月亮型billiard202圆相交-非递归181102b-非预料内图形-原因分析181202b
- 单椭圆(非递归)18圣诞后-ok版181225