绘制球体的难点主要在于 要在遍历循环中 根据经纬度反复的使用Cos、Sin函数算出球面上的XYZ三个顶点坐标,一直反复计算,最终三角面多的形成了一个球的形状。
还是老样子,直接贴代码,感兴趣的先自己看看吧。原理后面有空了统一讲!
Ball.h
#pragma once namespace U3D { class CBall :public CElement { private: GLSphere *sphere=NULL; CCTexture *ballTexture; public: void draw(float deltaTime); GLAABB3D getBoundBox() { return GLAABB3D{Vector3D(-9999,-9999,-99999),Vector3D(9999,9999,9999)};} GLSphere *getBall(); void setBall(Vector3D ¢er, float radius,char*name="res/其他/地球.png"); CBall(Vector3D ¢er, float radius,char*name="res/其他/地球.png"); CBall(); ~CBall(); }; }
Ball.cpp
#include "Engine.h" namespace U3D { CBall::CBall() { } CBall::CBall(Vector3D ¢er,float radius,char *name) { ballTexture = CTextureManager::getInstance()->addTexture(name); setBall(center, radius,name); } void CBall::setBall(Vector3D ¢er, float radius,char*name) { ballTexture = CTextureManager::getInstance()->addTexture(name); if (sphere == NULL) { sphere = new GLSphere; } sphere->Set(center, radius); } void CBall::draw(float deltaTime) { Matrix3D scaleMatrix; Matrix3D rotateMatrix; Matrix3D transMatrix; //放缩图片 scaleMatrix.Scale(scale.x, scale.y, scale.z); //水平翻转 if (flip == true) scaleMatrix._11 *= -1; //旋转图片 Matrix3D tempx, tempy, tempz; tempy.YRotate(angle.y); tempx.XRotate(angle.x); tempz.ZRotate(angle.z); rotateMatrix = tempx*tempy*tempz; // 平移图片到我们的指定位置 transMatrix.Translate(pos.x, pos.y, pos.z); local_matrix = scaleMatrix*rotateMatrix*transMatrix; if (parent == NULL) { world_color = local_color; world_matrix = local_matrix; } else { sColor col = parent->getWorldColor(); world_color.r = local_color.r*col.r; world_color.g = local_color.g*col.g; world_color.b = local_color.b*col.b; world_color.a = local_color.a*col.a; world_matrix = local_matrix*parent->getWorldMatrix();//行*列矩阵相乘__计算得到新矩阵 } if (visible == false) return; Vector3D v; float radius = sphere->m_radius; Vector3D center = sphere->m_center; float dtor = PI / 180.0f; int dphi = 10; //纬度 int dtheta = 10; //经度 glPushMatrix(); glColor4fv(world_color.color); glMultMatrixf(world_matrix.mat); glDisable(GL_CULL_FACE); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, ballTexture->getTextureID()); glBegin(GL_TRIANGLE_STRIP); for (int phi = 0; phi <= 180 - dphi; phi += dphi) { for (int theta = 0; theta <= 360 - dtheta; theta += dtheta) { v.x = sinf(phi*dtor)*cosf(theta*dtor); v.y = cosf(phi*dtor); v.z = sinf(phi*dtor)*sinf(theta*dtor); glTexCoord2f(asinf(v.x) / PI + 0.5f, asinf(v.y) / PI + 0.5f); glVertex3f(radius*v.x + center.x, radius*v.y + center.y, radius*v.z + center.z); v.x = sinf((phi + dphi)*dtor)*cosf(theta*dtor); v.y = cosf((phi + dphi)*dtor); v.z = sinf((phi + dphi)*dtor)*sinf(theta*dtor); glTexCoord2f(asinf(v.x) / PI + 0.5f, asinf(v.y) / PI + 0.5f); glVertex3f(radius*v.x + center.x, radius*v.y + center.y, radius*v.z + center.z); v.x = sinf(phi*dtor)*cosf((theta - dtheta)*dtor); v.y = cosf(phi*dtor); v.z = sinf(phi*dtor)*sinf((theta - dtheta)*dtor); glTexCoord2f(asinf(v.x) / PI + 0.5f, asinf(v.y) / PI + 0.5f); glVertex3f(radius*v.x + center.x, radius*v.y + center.y, radius*v.z + center.z); if (phi > -180 && phi < 180) { v.x = sinf((phi + dphi)*dtor)*cosf((theta - dtheta)*dtor); v.y = cosf((phi + dphi)*dtor); v.z = sinf((phi + dphi)*dtor)*sinf((theta - dtheta)*dtor); glTexCoord2f(asinf(v.x) / PI + 0.5f, asinf(v.y) / PI + 0.5f); glVertex3f(radius*v.x + center.x, radius*v.y + center.y, radius*v.z + center.z); } } } glEnd(); glDisable(GL_TEXTURE_2D); glEnable(GL_CULL_FACE); glColor4f(1,1,1,1); glPopMatrix(); } GLSphere* CBall::getBall() { return sphere; } CBall::~CBall() { } }