嘗試用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