OpenGL + vc6.0 控制台实现《太阳系模型》
来源:互联网 发布:广州市梦享网络 编辑:程序博客网 时间:2024/05/16 07:05
OpenGL + vc6.0 控制台实现《太阳系模型》
#define BITMAP_ID 0x4D42#define PI 3.1415926#include <windows.h>#include <stdio.h>#include <stdlib.h>#include <math.h>#include <gl\glut.h>#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )//---------- 纹理数据结构typedef struct{int width;//纹理宽度int height;//纹理高度unsigned int texID;//纹理对象 IDunsigned char * data;//实际纹理数据}texture;static float year = 0, month =0,day = 0, angle=30;static bool first=false;texture * sun,* earth,* moon;//纹理指针//---------- 调入位图作为纹理数据unsigned char * LoadBmpFile(char * filename,BITMAPINFOHEADER * bmpInfoHeader){FILE * file;BITMAPFILEHEADER bmpFileHeader;unsigned char * image;unsigned int imageIdx =0;unsigned char tempRGB;file = fopen(filename,"rb");if(file == NULL)return 0;fread(& bmpFileHeader,sizeof(BITMAPFILEHEADER),1,file);// 读取 BMP 文件头if (bmpFileHeader.bfType != BITMAP_ID)// 验证是否是一个 BMP 文件{fclose(file);return 0;}fread(bmpInfoHeader,sizeof(BITMAPINFOHEADER),1,file);// 读位图信息头fseek(file,bmpFileHeader.bfOffBits,SEEK_SET);// 将文件指针移到位图数据的开始处image = (unsigned char * )malloc(bmpInfoHeader->biSizeImage);// 分配内存给位图数据if (! image){free(image);fclose(file);return 0;}fread(image,1,bmpInfoHeader->biSizeImage,file);// 读取位图数据if (image == NULL){fclose(file);return 0;}// 反转 R 和 B 值以得到 RGB,因为位图颜色格式是 BGRfor (imageIdx = 0;imageIdx < bmpInfoHeader->biSizeImage;imageIdx += 3){tempRGB = image[imageIdx];image[imageIdx] = image[imageIdx + 2];image[imageIdx + 2] = tempRGB;}fclose(file);return image;}//---------- 调入纹理文件texture * LoadTexFile(char * filename){BITMAPINFOHEADER texInfo;texture * thisTexture;thisTexture = (texture * )malloc(sizeof(texture));if(thisTexture == NULL)return 0;thisTexture->data = LoadBmpFile(filename,&texInfo);// 调入纹理数据并检查有效性if (thisTexture->data == NULL){free(thisTexture);return 0;}thisTexture->width = texInfo.biWidth;// 设置纹理的宽和高thisTexture->height = texInfo.biHeight;glGenTextures(1,&thisTexture->texID);// 生成纹理对象名return thisTexture;}//---------- 初始化所有纹理数据和属性BOOL LoadAllTextures(){sun = LoadTexFile("sun.bmp");if(sun == NULL)return FALSE;glBindTexture(GL_TEXTURE_2D,sun->texID);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA,sun->width,sun->height,GL_RGB,GL_UNSIGNED_BYTE,sun->data);earth = LoadTexFile("earth.bmp");if(earth == NULL)return FALSE;glBindTexture(GL_TEXTURE_2D,earth->texID);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA,earth->width,earth->height,GL_RGB,GL_UNSIGNED_BYTE,earth->data);moon = LoadTexFile("moon.bmp");if(moon == NULL)return FALSE;glBindTexture(GL_TEXTURE_2D,moon->texID);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA,moon->width,moon->height,GL_RGB,GL_UNSIGNED_BYTE,moon->data);return TRUE;}void gltDrawSphere(GLfloat fRadius, GLint iSlices, GLint iStacks){ GLfloat drho = (GLfloat)(3.141592653589) / (GLfloat) iStacks; GLfloat dtheta = 2.0f * (GLfloat)(3.141592653589) / (GLfloat) iSlices;GLfloat ds = 1.0f / (GLfloat) iSlices;GLfloat dt = 1.0f / (GLfloat) iStacks;GLfloat t = 1.0f;GLfloat s = 0.0f; GLint i, j; for (i = 0; i < iStacks; i++) {GLfloat rho = (GLfloat)i * drho;GLfloat srho = (GLfloat)(sin(rho));GLfloat crho = (GLfloat)(cos(rho));GLfloat srhodrho = (GLfloat)(sin(rho + drho));GLfloat crhodrho = (GLfloat)(cos(rho + drho));glBegin(GL_TRIANGLE_STRIP); s = 0.0f;for ( j = 0; j <= iSlices; j++) {GLfloat theta = (j == iSlices) ? 0.0f : j * dtheta;GLfloat stheta = (GLfloat)(-sin(theta));GLfloat ctheta = (GLfloat)(cos(theta));GLfloat x = stheta * srho;GLfloat y = ctheta * srho;GLfloat z = crho; glTexCoord2f(s, t); glNormal3f(x, y, z); glVertex3f(x * fRadius, y * fRadius, z * fRadius); x = stheta * srhodrho;y = ctheta * srhodrho;z = crhodrho;glTexCoord2f(s, t - dt); s += ds; glNormal3f(x, y, z); glVertex3f(x * fRadius, y * fRadius, z * fRadius);} glEnd(); t -= dt;}}void myinit(void) {glClearColor (0.0, 0.0, 0.0, 0.0);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glEnable(GL_DEPTH_TEST);glEnable(GL_TEXTURE_2D);//启用二维纹理GLfloat light0_ambient[] = {1, 1, 1, 1};//环境光GLfloat light0_diffuse[] = {1, 1, 1, 1};//散射光GLfloat light0_position[] = {0, 0, 0, 1};//光源位置glLightfv(GL_LIGHT0,GL_AMBIENT,light0_ambient);glLightfv(GL_LIGHT0,GL_DIFFUSE,light0_diffuse);glLightfv(GL_LIGHT0,GL_POSITION,light0_position);LoadAllTextures();//调入纹理}void myidle(){day+=angle;glutPostRedisplay();}void mymouse(int button,int state,int x,int y){if(state==GLUT_DOWN && button==GLUT_LEFT_BUTTON){if(first){glutIdleFunc(myidle);first=!first;}else{glutIdleFunc(0);first=!first;}}}void mykeyboard(unsigned char key, int x, int y) {if (key == 27) exit(0); } void mydisplay(void){year=day/365;month=day/30;glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);GLfloat mat_ambient1[] = {1,0,0,1};GLfloat mat_emission[] = {1,1,1,0};GLfloat mat_ambient2[] = {0.4,0.4,0.8,1};GLfloat no_emission[] = {0,0,0,1};glPushMatrix();glBindTexture(GL_TEXTURE_2D,sun->texID);glRotatef (month, 0.0, 1.0, 0.0);//太阳自转glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient1);glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);glRotatef (90, -1, 0, 0);gltDrawSphere(1.0, 40, 40);//绘制太阳glPopMatrix();glPushMatrix();glRotatef (year, 0.0, 1.0, 0.0);//月亮与地球一起绕太阳转(地球公转)glPushMatrix();glBindTexture(GL_TEXTURE_2D,earth->texID);glTranslatef (3.0, 0.0, 0.0);glRotatef (month, 0.0, 1.0, 0.0);//地球自转 glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient2);glMaterialfv(GL_FRONT, GL_EMISSION, no_emission);glRotatef (90, -1, 0, 0);gltDrawSphere(0.4, 40, 40);//绘制地球glPopMatrix();glPushMatrix();glBindTexture(GL_TEXTURE_2D,moon->texID);glTranslatef (3.0, 0.0, 0.0);glRotatef (60, -1, 1, 0);glRotatef (month, 0, 1.0, 0);//月球绕地球转glTranslatef (0.6, 0.0, 0.0);glRotatef (90, -1, 0, 0);gltDrawSphere(0.07, 20, 20);//绘制月球glPopMatrix();glPopMatrix();glFlush();glutSwapBuffers(); }void myreshape (int w, int h){glViewport (0, 0, (GLsizei) w, (GLsizei) h);//指定视口大小glMatrixMode (GL_PROJECTION);glLoadIdentity ();gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1, 20);//透视投影glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);//指定照相机的位置}int main(int argc, char** argv){glutInit(&argc, argv);glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowSize (1000, 600); glutInitWindowPosition (100, 100);glutCreateWindow (argv[0]);myinit ();glutDisplayFunc(mydisplay); glutReshapeFunc(myreshape);glutIdleFunc(myidle);glutMouseFunc(mymouse);glutKeyboardFunc(mykeyboard);glutMainLoop();return 0;}
说明:上述代码已经在vc控制台中编译运行通过。
此链接为此程序的源代码文件(包含此程序所需的三个bmp图片,及exe文件)
http://download.csdn.net/detail/shen_gan/4279261
以下为运行效果图:
- OpenGL + vc6.0 控制台实现《太阳系模型》
- OpenGL实现太阳系模型 —— Juwend
- 太阳系模型——OpenGL
- OpenGL 实现模拟太阳系运动
- OpenGL简单实现太阳系模拟
- 《高效学习OpenGL》之 创建太阳系模型
- Java实现的简易太阳系模型
- opengl 使用 vc6.0中win32控制台工程去掉控制台窗口
- OpenGL(5)--太阳系和的日月地实现
- 计算机绘图OPENgl---太阳系
- OpenGL模拟太阳系运行
- 【OpenGL】模拟太阳系
- VC6.0建立控制台程序实现PDA应用
- VC6.0+OpenGL入门
- vc6.0安装opengl
- VC6.0配置OpenGL
- VC6.0配置OpenGL
- 简单的太阳系模型
- How to get the query statement of LOV in Oracle Form
- android的设备永不休眠(增加 Settings-->Dispaly-->-->screenout-->never Timeout)
- HDU 4432(Sum of divisors)
- 对xml的处理_Dom4j入门_一个工具类
- C#代码写的一个计算器的小程序
- OpenGL + vc6.0 控制台实现《太阳系模型》
- Android 双缓冲技术
- mysql读写分离实现
- winform中配置Log4Net
- Ubuntu下以USB调试方式链接Android手机
- COL命令用法
- JQuery 禁用所有select标签的值
- Java程序设计(九)----模拟用户帐户的程序
- 由浅入深 Core Data 详解