opengGL实战——太阳系三维场景动画搭建

写在前面:最近在学习三维Opengl相关技术,做了一个太阳系三维场景的简单动画,先看一下效果图:

演示视屏https://www.bilibili.com/video/BV1HK4y1D7pM

 

界面采用Qt进行搭建,主要的渲染绘制过程如下:

1.球体的绘制函数:

glPushMatrix();
	if (m_enableOrbit)
	{
		glDisable(GL_LIGHTING);
		glColor3d(0.5, 0.5, 0.5);
		glBegin(GL_LINE_LOOP);
		int n = 50;
		for (int i = 0; i < n; ++i)
			glVertex3f(rotateRadius*cos(2 * 3.1415926 / n * i), 0.0f, rotateRadius*sin(2 * 3.1415926 / n * i));
		glEnd();
		glEnable(GL_LIGHTING);
	}
	glRotatef(revolution * speed, 0, 1, 0);
	glTranslatef(0, 0, rotateRadius);
	glRotatef(rotation * speed * 5.0, 0, 1, 0);
	glRotatef(90, 1, 0, 0);

	glScalef(scale, scale, scale);
	glColor3f(1.0, 1.0, 1.0);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, tex_id);

	gluSphere(sphere, 1, 40, 40);
	glBindTexture(GL_TEXTURE_2D, 0);

	glDisable(GL_TEXTURE_2D);
	glPopMatrix();

2.环境的渲染:

clock_t current_t = GetTick();
	float delta_t = (current_t - m_time) * 0.001 * m_pMainOpenGLWidgetPrivate->m_speed;
	if (m_pMainOpenGLWidgetPrivate->m_enableRevolution)
		revolution += delta_t;
		m_rotation += delta_t;
		m_time = current_t;

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-m_pMainOpenGLWidgetPrivate->m_translateZ * aspect, m_pMainOpenGLWidgetPrivate->m_translateZ * aspect, -m_pMainOpenGLWidgetPrivate->m_translateZ, m_pMainOpenGLWidgetPrivate->m_translateZ, -100, 100);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	m_pMainOpenGLWidgetPrivate->drawBackground();
	glTranslated(m_pMainOpenGLWidgetPrivate->m_translateX, m_pMainOpenGLWidgetPrivate->m_translateY, m_pMainOpenGLWidgetPrivate->m_translateZ - 40);
	glRotated(m_rotateX + 25, 1.0, 0.0, 0.0);
	glRotated(m_rotateZ, 0.0, 0.0, 1.0);

	//light
	float sunlight_pos[4] = { 0.0, 0.0, 0.0, 1.0 };
	glLightfv(GL_LIGHT0, GL_POSITION, sunlight_pos);
	float artfical_light_pos[4] = { 1.0, 1.0, 1.0, 0.0 };
	glLightfv(GL_LIGHT1, GL_POSITION, artfical_light_pos);

	float while_color[4] = { 1.0f * m_pMainOpenGLWidgetPrivate->m_lightBrightness, 1.0f * m_pMainOpenGLWidgetPrivate->m_lightBrightness, 1.0f * m_pMainOpenGLWidgetPrivate->m_lightBrightness, 1.0 };
	float black_color[4] = { 0.0, 0.0, 0.0, 1.0 };
	glLightfv(GL_LIGHT0, GL_DIFFUSE, while_color);
	glLightfv(GL_LIGHT0, GL_SPECULAR, while_color);
	glLightfv(GL_LIGHT0, GL_AMBIENT, black_color);

	glLightfv(GL_LIGHT1, GL_DIFFUSE, while_color);
	glLightfv(GL_LIGHT1, GL_SPECULAR, while_color);
	glLightfv(GL_LIGHT1, GL_AMBIENT, black_color);

	m_pMainOpenGLWidgetPrivate->m_enableSunLight? glEnable(GL_LIGHT0): glDisable(GL_LIGHT0);
	glEnable(GL_LIGHT1);
	
	float base_color[4] = { 1.0f, 1.0f, 1.0f, 1 };
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, base_color);
	float specular_color[4] = { 1.0f, 1.0f, 1.0f, 1 };
	glMaterialfv(GL_FRONT, GL_SPECULAR, specular_color);
	glMaterialf(GL_FRONT, GL_SHININESS, 50);
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glScalef(3.0, 3.0, 3.0);
	glColor3f(1.0, 1.0, 1.0);
	glRotatef(m_rotation, 0, 1, 0);
	glRotatef(90, 1, 0, 0);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, m_pMainOpenGLWidgetPrivate->m_textures_ids[0]);
	gluSphere(m_sphere, 1, 40, 40);
	glBindTexture(GL_TEXTURE_2D, 0);
	glDisable(GL_TEXTURE_2D);
	glPopMatrix();

	float color[4] = { 0.5f, 0.5f, 0.5f, 1 };
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
	float specular_color2[4] = { 0.8f, 0.8f, 0.8, 1 };
	glMaterialfv(GL_FRONT, GL_SPECULAR, specular_color2);
	glMaterialf(GL_FRONT, GL_SHININESS, 30);
	m_pMainOpenGLWidgetPrivate->drawPlanet(m_pMainOpenGLWidgetPrivate->m_textures_ids[1], 0.2, 6, 3,revolution,m_rotation,m_sphere);
	m_pMainOpenGLWidgetPrivate->drawPlanet(m_pMainOpenGLWidgetPrivate->m_textures_ids[2], 0.6, 9, 2, revolution, m_rotation, m_sphere);
	m_pMainOpenGLWidgetPrivate->drawPlanet(m_pMainOpenGLWidgetPrivate->m_textures_ids[3], 0.7, 11, 1, revolution, m_rotation, m_sphere);
	m_pMainOpenGLWidgetPrivate->drawPlanet(m_pMainOpenGLWidgetPrivate->m_textures_ids[4], 0.5, 16, 0.8, revolution, m_rotation, m_sphere);
	m_pMainOpenGLWidgetPrivate->drawPlanet(m_pMainOpenGLWidgetPrivate->m_textures_ids[5], 1.5, 19, 0.7, revolution, m_rotation, m_sphere);
	m_pMainOpenGLWidgetPrivate->drawPlanet(m_pMainOpenGLWidgetPrivate->m_textures_ids[6], 1.2, 21, 0.5, revolution, m_rotation, m_sphere);
	float saturnScale = 1.2; float rotateRadius = 21; float saturnm_speed = 0.5;
	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GREATER, 0.5f);
	glPushMatrix();

	glRotatef(revolution * saturnm_speed, 0, 1, 0);
	glTranslatef(0, 0, rotateRadius);
	glRotatef(m_rotation * saturnm_speed * 5.0, 0, 1, 0);
	saturnScale *= 2;
	glScalef(saturnScale, saturnScale, saturnScale);
	glColor3f(1.0, 1.0, 1.0);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, m_pMainOpenGLWidgetPrivate->m_textures_ids[10]);
	glBegin(GL_QUADS);
	glTexCoord2f(0.0, 0.0);
	glVertex3f(-1.0, 0.0, -1.0);
	glTexCoord2f(0.0, 1.0);
	glVertex3f(-1.0, 0.0, 1.0);
	glTexCoord2f(1.0, 1.0);
	glVertex3f(1.0, 0.0, 1.0);
	glTexCoord2f(1.0, 0.0);
	glVertex3f(1.0, 0.0, -1.0);

	glEnd();
	glBindTexture(GL_TEXTURE_2D, 0);
	glDisable(GL_TEXTURE_2D);
	glPopMatrix();
	glDisable(GL_ALPHA_TEST);

	m_pMainOpenGLWidgetPrivate->drawPlanet(m_pMainOpenGLWidgetPrivate->m_textures_ids[7], 1.1, 24, 0.4, revolution, m_rotation, m_sphere);
	m_pMainOpenGLWidgetPrivate->drawPlanet(m_pMainOpenGLWidgetPrivate->m_textures_ids[8], 0.9, 28, 1, revolution, m_rotation, m_sphere);
	m_pMainOpenGLWidgetPrivate->drawSatellites(revolution,m_rotation,m_sphere);
	glPushMatrix();
	glScaled(5.0, 5.0, 5.0);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, m_pMainOpenGLWidgetPrivate->m_textures_ids[12]);
	glPushMatrix();
	glTranslated(1.0, 0.0, 0.0);
	glBegin(GL_POLYGON);
	glNormal3f(0.0, 1.0, 0.0);
	glTexCoord2d(0.0, 0.0);
	glVertex3f(0.0, 0.0, -1.0);
	glTexCoord2d(1.0, 0.0);
	glVertex3f(1.0, 0.0, -1.0);
	glTexCoord2d(1.0, 1.0);
	glVertex3f(1.0, 0.0, 1.0);
	glTexCoord2d(0.0, 1.0);
	glVertex3f(0.0, 0.0, 1.0);
	glEnd();
	glPopMatrix();
	glPushMatrix();
	glRotated(180, 0.0, 1.0, 0.0);
	glTranslated(1.0, 0.0, 0.0);
	glBegin(GL_POLYGON);
	glNormal3f(0.0, 1.0, 0.0);
	glTexCoord2d(0.0, 0.0);
	glVertex3f(0.0, 0.0, -1.0);
	glTexCoord2d(1.0, 0.0);
	glVertex3f(1.0, 0.0, -1.0);
	glTexCoord2d(1.0, 1.0);
	glVertex3f(1.0, 0.0, 1.0);
	glTexCoord2d(0.0, 1.0);
	glVertex3f(0.0, 0.0, 1.0);
	glEnd();
	glPopMatrix();
	glBindTexture(GL_TEXTURE_2D, 0);
	glDisable(GL_TEXTURE_2D);
	gluSphere(m_sphere, 1, 40, 40);
	glPopMatrix();

 所有的鼠标事件操作使用了Qt的信号槽进行处理:

void MainWindow::initConnect(void)
{
	connect(ui.orbitCheckBox, &QCheckBox::stateChanged, this, &MainWindow::on_orbitCheckBoxstateChanged);
	connect(ui.lightCheckBox, &QCheckBox::stateChanged, this, &MainWindow::on_lightCheckBoxChanged);
	connect(ui.startPushButton, &QPushButton::clicked, this, &MainWindow::on_startPushButtonClicked);
	connect(ui.spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_spinBoxValueChanged(int)));
	connect(ui.horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(on_horizontalSliderValueChanged(int)));
	connect(ui.verticalSlider, SIGNAL(valueChanged(int)), this, SLOT(on_verticalSliderValueChanged(int)));
	connect(ui.horizontalSliderLightness, SIGNAL(valueChanged(int)), this, SLOT(on_horizontalSliderLightnessValueChanged(int)));
	connect(ui.horizontalSliderZoom, SIGNAL(valueChanged(int)), this, SLOT(on_horizontalSliderZoomValueChanged(int)));
}

void MainWindow::disConnect(void)
{
	disconnect(ui.orbitCheckBox, &QCheckBox::stateChanged, this, &MainWindow::on_orbitCheckBoxstateChanged);
	disconnect(ui.lightCheckBox, &QCheckBox::stateChanged, this, &MainWindow::on_lightCheckBoxChanged);
	disconnect(ui.startPushButton, &QPushButton::clicked, this, &MainWindow::on_startPushButtonClicked);
	disconnect(ui.spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_spinBoxValueChanged(int)));
	disconnect(ui.horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(on_horizontalSliderValueChanged(int)));
	disconnect(ui.verticalSlider, SIGNAL(valueChanged(int)), this, SLOT(on_verticalSliderValueChanged(int)));
	disconnect(ui.horizontalSliderLightness, SIGNAL(valueChanged(int)), this, SLOT(on_horizontalSliderLightnessValueChanged(int)));
	disconnect(ui.horizontalSliderZoom, SIGNAL(valueChanged(int)), this, SLOT(on_horizontalSliderZoomValueChanged(int)));
}

可执行工程下载:https://download.csdn.net/download/weixin_39951988/15490556

工程源码下载:https://download.csdn.net/download/weixin_39951988/15490585

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尘海折柳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值