必威体育Betway必威体育官网
当前位置:首页 > IT技术

简易天体运动—— sun & earth & moon(计算机图形学)

时间:2019-10-30 13:12:15来源:IT技术作者:seo实验室小编阅读:60次「手机版」
 

天体运动

曾经的图形学作业,顺手放上来吧。(手动滑稽

PS:工程下载:https://download.csdn.net/download/weixin_41918712/10652828


一些概念

  • OpenGL在光照模拟中将光线分为辐射光、环境光、漫反射光和镜面反射光4 种独立的成分。
  • OpenGL中,材料的颜色决定于其对入射光中的红、绿、蓝各成分的反射比例。  
  • 材料的设置参数中也包括对R、G、B值的设定,但与光照的参数设置相比,两者的含义是不同的。对材料来说, R、G、B值分别对应材料对各种颜色光的反射比例。
  • 与光线的情况相似,材料也具有辐射色、环境色、漫反射色和镜面反射色。为了模拟场景中的发光体,可以设定材料的辐射光特性;而环境色、漫反射色和镜面反射色则反映材料对环境光、漫反射光和镜面反射光的反射系数。

功能描述

键盘A & a:地球顺时针自转;   键盘D & d:地球逆时针自转;

键盘S & s:地球顺时针公转;   键盘W & w:地球逆时针公转;


效果图

太阳&地球&月亮 如下图所示:


OpenGL搭建

VS中搭建OpenGL所需的头文件及库文件:

云盘链接:https://pan.baidu.com/s/1fFsic53et67IjIHdV-eUvg 密码:unyr

搭建OpenGL所需文件的方法:

① 找到并打开Visual Studio的安装目录,比如:

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428

② 打开\include文件夹,把资源里的“GL”文件夹整个复制到里面。

③ 回到①步骤,再打开lib\x86,把资源“LIB”文件夹里的5个.lib文件复制到lib文件夹里面。

④ 最后把资源“C盘syswow64或system32目录下的文件”文件夹里的两个文件复制到以下目录:

C:\windows\system32文件夹内(如果你的电脑是32位系统请选这个)

或‪C:\Windows\SysWOW64(64位系统请选这个)

使用vs插件

① 文件 -- 新建 -- 项目 -- Visual C++ -- 空项目;

② 项目 -- 管理Nuget程序包 -- 浏览 -- (搜索栏输入)NupenGL;

③ 选择第一个,安装即可完成配置。

谢谢观看~(手动滑稽


天体源码

#include <GL/glut.h>
#include <stdlib.h>

static int year = 0, day = 0, moon = 0;

void init(void)
{
	GLfloat sun_light_position[] = { 1.0f, 1.0f, 1.0f, 0.0f };  //表示光源所在的位置,(X, Y, Z, W)
	GLfloat sun_light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };   //环境光分量
	GLfloat sun_light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };    //漫反射分量
	GLfloat sun_light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };   //镜面反射分量
	glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position); //指定第0号光源的位置 
	glLightfv(GL_LIGHT0, GL_AMBIENT, sun_light_ambient); //GL_AMBIENT表示各种光线照射到该材质上,
														 //经过很多次反射后最终遗留在环境中的光线强度(颜色)
	glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse); //漫反射后
	glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);//镜面反射后
	glEnable(GL_LIGHT0); // 激活指定光源,使用第0号光照
	glEnable(GL_LIGHTING); //激活光照功能
	glEnable(GL_depth_TEST); //这句是启用深度测试,这样,在后面的物体会被挡着 
	glClearcolor(0.0, 0.0, 0.0, 0.0);
	glshadeModel(GL_SMOOTH);  //设置光滑着色模型
}

void display(void) {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清空颜色和深度缓冲
	glColor3f(1.0, 1.0, 1.0);
	// 定义太阳的材质并绘制太阳
	GLfloat sun_mat_ambient[] = { 0.5f, 0.5f, 0.0f, 1.0f };    //材料环境光颜色
	GLfloat sun_mat_diffuse[] = { 0.5f, 0.0f, 0.5f, 1.0f };    //材料漫反射光颜色
	GLfloat sun_mat_specular[] = { 0.0f, 0.0f, 0.0f, 1.0f };   //材料镜面反射光颜色
	GLfloat sun_mat_emission[] = { 0.0f, 0.0f, 0.0f, 1.0f };   //材料辐射光颜色
	GLfloat sun_mat_shininess = 60.0f; // 材料光滑指数
	glMaterialfv(GL_FRONT, GL_AMBIENT, sun_mat_ambient); //定义材料的前面采用环境光颜色
	glMaterialfv(GL_FRONT, GL_DIFFUSE, sun_mat_diffuse); //材料的前面为漫反射光颜色
	glMaterialfv(GL_FRONT, GL_SPECULAR, sun_mat_specular); //定义材料的前面为镜面反射光颜色
	glMaterialfv(GL_FRONT, GL_EMISSION, sun_mat_emission); //定义材料的前面辐射光颜色
	glMaterialf(GL_FRONT, GL_SHININESS, sun_mat_shininess); //材料的前面的光滑指数
	glpushmatrix();   //a 此处的push是为了表明堆栈当前状态
	glutSolidSphere(1.0, 20, 16); /* draw sun */     //参数分别是半径、以Z轴上线段为直径分布的圆周线的条数(类似经线)、围绕在Z轴周围的线的条数(类似纬线)
													 // 定义地球的材质并绘制地球
	GLfloat earth_mat_ambient[] = { 0.0f, 0.0f, 0.5f, 1.0f };    //材料环境光颜色,偏蓝色
	GLfloat earth_mat_diffuse[] = { 0.0f, 0.0f, 0.5f, 1.0f };    //材料漫反射光为偏蓝色的光源
	GLfloat earth_mat_specular[] = { 0.0f, 0.0f, 1.0f, 1.0f };   //材料镜面反射光为蓝色的光源
	GLfloat earth_mat_emission[] = { 0.0f, 0.0f, 0.0f, 1.0f };    //材料辐射光颜色,白光
	GLfloat earth_mat_shininess = 30.0f;
	glMaterialfv(GL_FRONT, GL_AMBIENT, earth_mat_ambient);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, earth_mat_diffuse);
	glMaterialfv(GL_FRONT, GL_SPECULAR, earth_mat_specular);
	glMaterialfv(GL_FRONT, GL_EMISSION, earth_mat_emission);
	glMaterialf(GL_FRONT, GL_SHININESS, earth_mat_shininess);
	glRotatef((GLfloat)year, 0.0, 1.0, 0.0);       //对局部坐标系统进行旋转(局部坐标系统最初与全局坐标系统是一致的),让地球绕太阳旋转
	glTranslatef(2.0, 0.0, 0.0);                  //把局部坐标系统平移到地球轨道上的一个位置
	glRotatef((GLfloat)day, 0.0, 1.0, 0.0);       //使局部坐标轴进行旋转,让地球绕局部坐标系统y轴旋转(即绕自身旋转)
	glutSolidSphere(0.3, 10, 8);    /* draw smaller planet */
									//自己
	glPushMatrix();
	GLfloat moon_mat_ambient[] = { 0.0f, 0.5f, 0.5f, 1.0f };    //材料环境光颜色
	GLfloat moon_mat_diffuse[] = { 0.0f, 0.5f, 0.5f, 1.0f };    //材料漫反射光
	GLfloat moon_mat_specular[] = { 0.0f, 1.0f, 1.0f, 1.0f };   //材料镜面反射光
	GLfloat moon_mat_emission[] = { 0.0f, 0.0f, 0.0f, 1.0f };    //材料辐射光颜色,白光
	GLfloat moon_mat_shininess = 15.0f;
	glMaterialfv(GL_FRONT, GL_AMBIENT, moon_mat_ambient);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, moon_mat_diffuse);
	glMaterialfv(GL_FRONT, GL_SPECULAR, moon_mat_specular);
	glMaterialfv(GL_FRONT, GL_EMISSION, moon_mat_emission);
	glMaterialf(GL_FRONT, GL_SHININESS, moon_mat_shininess);
	glRotatef((GLfloat)day, 0.0, 1.0, 0.0);       //对局部坐标系统进行旋转(局部坐标系统最初与全局坐标系统是一致的),让地球绕太阳旋转
	glTranslatef(0.5, 0.0, 0.0);                  //把局部坐标系统平移到地球轨道上的一个位置
	glRotatef((GLfloat)day, 0.0, 1.0, 0.0);       //使局部坐标轴进行旋转,让地球绕局部坐标系统y轴旋转(即绕自身旋转)
	glutSolidSphere(0.1, 8, 7);    /* draw smaller planet */
	glPopMatrix();
	//自己
	//glPopMatrix();          // 这个pop使得堆栈状态回到b状态
	glPopMatrix();          // 这个pop使得堆栈状态回到a状
	glutSwapBuffers();    //交换前台和后台缓冲区
}

void reshape(int w, int h) {
	glViewport(0, 0, (GLsizei)w, (GLsizei)h);
	glMatrixMode(GL_PROJECTION);      //设置投影变换
	glLoadIdentity();
	gluPerspective(60.0, (GLfloat)w / (GLfloat)h, 1.0, 20.0);   //设置透视投影,视角大小及宽高比来确定沿视线方向的棱锥,并通过指定近、远剪切面与视点间的距离来截断棱锥,得到取景体。
																// glOrtho(-3.0, 3.0, -3.0, 3.0, -10, 10);   //设置正交投影,取景体是一个各面均为矩形的六面体。前4个参数是坐标,后两个是距离
	glMatrixMode(GL_MODELVIEW);      //设置视图变换
	glLoadIdentity();
	glulookat(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}

void keyboard(unsigned char key, int x, int y)
{
	switch (key)
	{
		case 'd':  //逆时针自转
		case 'D':
			day = (day + 10) % 360;
			moon = (moon + 5) % 360;
			glutPostRedisplay();   //标记当前窗口需要重新绘制
			break;
		case 'a':  //顺时针自转
		case 'A':
			day = (day - 10) % 360;
			glutPostRedisplay();
			break;
		case 'w':  //逆时针公转
		case 'W':
			year = (year + 5) % 360;
			day = (day + 10) % 360;
			moon = (moon + 5) % 360;
			glutPostRedisplay();
			break;
		case 's':  //顺时针公转
		case 'S':
			year = (year - 5) % 360;
			moon = (moon - 10) % 360;
			glutPostRedisplay();
			break;
		case 27:
			exit(0);
			break;
		default:
			break;
	}
}

int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(800, 600);
	glutInitWindowPosition(100, 100);
	glutcreatewindow("Sun & Earth");
	init();
	glutDisplayFunc(display); //设置display函数,当需要进行画图时,这个函数就会被调用 
	glutReshapeFunc(reshape);  //调用此函数,重新建立用作新渲染画布的矩形区域
	glutKeyboardFunc(keyboard);  //这个函数是告诉窗口系统,哪一个函数将会被调用来处理普通按键消息
	glutMainLoop();    //进入 GLUT 消息循环,开始执行程序,显示窗口,并且等待窗口关闭才会返回
	return 0;
}

✎﹏﹏₯㎕《晴天》随记忆一直晃到现在 ...﹍﹍﹍﹍﹍﹍

文章最后发布于: 2018-09-07 20:59:37

相关阅读

运动蓝牙耳机良心推荐:运动圈公认的五款旗舰耳机

很多人都喜欢在运动时来点有节奏的音乐,这样能让运动更加有激情,因为传统耳机在运动时总是会牵绊到线,运动起来很不方便,那么运动蓝牙

百度可穿戴设备研究报告 健康与运动成核心需求

10月底,百度可穿戴设备网站上线,宣告百度正式进入可穿戴智能设备市场。在这个网站上,两款与百度开放云合作的产品咕咚手环以及inWatc

马拉松运动员信息记录系统(基于百度地图API)

这个项目的想法是在运动员身上放置一个可以检测运动员身体状况以及位置的设备,通过将数据发送到数据库然后通过系统就可以监测运动

微信运动怎么不显示步数?该怎么办?

在微信里面关注微信运动公众号之后就可以开始你的运动之旅了,微信运动会将你每天行走的步数都记录下来,可以和朋友进行PK,步数捐赠等

【Scratch】动物运动会

1. 平台介绍 scratch是美国麻省理工学院的开发团队开发的简易编程工具,旨在建立起人们对编程的兴趣。我们今天下载的是scratch2.0

分享到:

栏目导航

推荐阅读

热门阅读