11.游戏引擎源码 使用OpenGL绘制三维球体

        绘制球体的难点主要在于 要在遍历循环中 根据经纬度反复的使用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 &center, float radius,char*name="res/其他/地球.png");
		CBall(Vector3D &center, float radius,char*name="res/其他/地球.png");
		CBall();
		~CBall();
	};
}

Ball.cpp

#include "Engine.h"


namespace U3D
{

	CBall::CBall()
	{
	}


	CBall::CBall(Vector3D &center,float radius,char *name)
	{
		ballTexture = CTextureManager::getInstance()->addTexture(name);
		setBall(center, radius,name);
	}

	void CBall::setBall(Vector3D &center, 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()
	{
	}


}

猜你喜欢

转载自blog.csdn.net/qq_33531923/article/details/126913165
今日推荐