日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ZBufeer算法

發布時間:2023/12/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ZBufeer算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ZBuffer是像空間消隱算法,首先在三維空間中記住物體的深度信息,將物體投影到二維平面后,用一個全局的緩沖器存儲每個像素對應的Z值,這樣只繪制距離相機最近的表面。

關鍵是要有一個緩沖器,然后是計算每個像素對應的Z值,這個Z值是在相機坐標系下的距離。
坐標轉換

bool CCamera::getZbufferPoint(CPoint3D& ScreenPoint, CPoint3D& localPoint, double screenHeight, double screenWidth) {arma::Mat<double> point3DMat({ localPoint.x,localPoint.y,localPoint.z,1 });arma::Mat<double> point3DMatTemp = point3DMat * localRotateMat * ModelMat * CameraMat;arma::Mat<double> point2DMat = point3DMatTemp * perspectiveMat;CPoint2D viewPoint(point2DMat(0), point2DMat(1));CPoint2D ScreenPoint2D;if (viewToScreen(ScreenPoint2D, viewPoint, angle, screenHeight, screenWidth)){ScreenPoint.x = ScreenPoint2D.x;ScreenPoint.y = ScreenPoint2D.y;ScreenPoint.z = point3DMatTemp(2); //相機坐標系下的Z值ScreenPoint.rgb = localPoint.rgb;return true;}return false; }

緩沖器的初始化和釋放

void CZBuffer::initZdeep(int width, int height, int deepth) {Zdeep = new double* [width];for (int i = 0; i < width; i++){Zdeep[i] = new double[height];for (int j = 0; j < height; j++)Zdeep[i][j] = deepth;} }void CZBuffer::releaseZdeep(int width) {for (int i = 0; i < width; i++)delete[] Zdeep[i];if (Zdeep != NULL)delete Zdeep; }

根據Z值和緩沖器中的存儲值判斷是否要填充像素

void CZBuffer::drawFaceZ(int ScreenWidth, int ScreenHeight, CDC* pDC) {CBucketZ* currentCBucket = this->PCBucket;//一條掃描線一條掃描線的解決while ((currentCBucket != NULL)){CAETZ* currentpET = currentCBucket->pET;while ((currentpET != NULL) && (currentpET->pNext != NULL)){CPoint3D tempStart3D(currentpET->x, currentpET->y, currentpET->z, currentpET->rgb);CPoint3D tempEnd3D(currentpET->pNext->x, currentpET->pNext->y, currentpET->pNext->z, currentpET->pNext->rgb);//CPoint3D currentpoint3D = tempEnd3D;//沿著y掃描線,x從小到大的坐標,逐個像素給屏幕像素填充顏色for (int ix = tempStart3D.x; ix <= tempEnd3D.x; ix++){//計算像素坐標的z值double z;if (tempEnd3D.x != tempStart3D.x){z = (tempEnd3D.z - tempStart3D.z) * (ix - tempStart3D.x) / (tempEnd3D.x - tempStart3D.x)+ tempStart3D.z;}else{tempEnd3D.z > tempStart3D.z ? z = tempStart3D.z : z = tempEnd3D.z;}//比較Zdeep中的Zbuffelint iys = (int)(currentpET->y + ScreenHeight / 2);//將屏幕坐標系中所有點平移到第一象限中int ixs = (int)(ix + ScreenWidth / 2);if (z < Zdeep[ixs][iys])//ix iy 的值可能變化{Zdeep[ixs][iys] = z;//計算像素值CRGB tempRgb;if (tempEnd3D.x != tempStart3D.x){/*CRGB temp((tempEnd3D.rgb - tempStart3D.rgb) * (ix - tempStart3D.x) / (tempEnd3D.x - tempStart3D.x)+ tempStart3D.rgb);*/double r = (ix - tempStart3D.x) / (tempEnd3D.x - tempStart3D.x);tempRgb = r * tempEnd3D.rgb + (1-r)* tempStart3D.rgb;}elsetempRgb = tempStart3D.rgb;//設置屏幕像素顏色pDC->SetPixelV(ix, currentpET->y, RGB(tempRgb.red, tempRgb.green, tempRgb.blue));}}currentpET = currentpET->pNext;}currentCBucket = currentCBucket->pNext;} }

總結

以上是生活随笔為你收集整理的ZBufeer算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。