OpenGL绘制地球仪

环境配置

使用软件visual studio 2019

glut配置

新建一新项目控制台应用点击项目/管理NuGet程序包

请添加图片描述

搜索nupengl安装,至此glut配置完成
请添加图片描述

glaux环境配置

可以自行下载glaux,也可以文章底部链接下载

在这里插入图片描述

glaux.dll放置

C:WindowsSysWOW64(64位)

C:WindowsSystem32(32位)

glaux.h放置

C:Program Files (x86)Microsoft Visual Studio2019CommunityVCToolsMSVC14.29.30133include

在此目录下新建一GL文件夹,将glaux.h放进去

请添加图片描述

glaux.lib放置

C:Program Files (x86)Microsoft Visual Studio2019CommunityVCToolsMSVC14.29.30133libx86

ps:位置可能不一致,但大体相同

源码

Main.cpp
#include "MyTexMgr.h"
#include <iostream&gt;
#include <stdlib.h>
#include <vector>
#include "MyTexMgr.h"
#include <GL/glut.h>
#define  GLUT_WHEEL_UP 3           //定义滚轮操作
#define  GLUT_WHEEL_DOWN 4

using namespace std;

static float _angle = 30.0f;
static float _cameraAngle = 0.0f;
static int oldX;
static int oldY;
static int X = 400;
static int Y = 240;
static int flag = 33;
static float _rotX=0;
static float _rotY=0;
static float xyz[3]={1,1,1};
static float r=200;

static GLUquadric*	_earth;
static MyTexMgr		_texLoader;


//键盘操作
void handleKeypress(unsigned char key, int x, int y) {
	switch (key) {
		case 27: //Escape key
			exit(0);break;
		//按键+为我旋转加速
		case '+':
			flag -= 3;
			break;
		//按键+为我旋转减速
		case '-':
			flag += 3;
			break;
		case 'w':
			Y += 20;
			break;
		case 'a':
			X -= 20;
			 break;
		case 's':
			Y -= 20;
			 break;
		case 'd':
			X += 20;
			break;
	}
}

//光照
void initLight()
{
	GLfloat	position[] = { -1.0,1.0,1.0,0};
	GLfloat	ambientLight[]={0.4,0.4,0.4,1};
	GLfloat diffuseLight[]={0.8,0.8,0.8,1};
	GLfloat specularLight[]={0.8,0.8,0.8,1};
	GLfloat posLight[]={400,240,1,1};
	//设置照明模型参数
	//全局环境glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambientLight);
	//环境glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
	//位置
	glLightfv(GL_LIGHT0, GL_POSITION, position);
	//漫射光
	glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
	//反射glLightfv(GL_LIGHT0,GL_SPECULAR,specularLight);
	//指定材质
	glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,128);
}

//定义D建模光照材质
void initRendering() {
	//创建二次曲面对象
	_earth=gluNewQuadric();
	//纹理装载(指定bmp位图位置)
	_texLoader.loadTex(L"earth",L"D:/download/earth.bmp");
	

	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHTING);
	initLight();
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_LINE_SMOOTH);
}

//删除建模
void deinitRendering()
{
	gluDeleteQuadric(_earth);
}

//窗口调整调用
void handleResize(int w, int h) {
	if (h==0)
	{
		h=1;
	}	
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0,w,0,h,-200,200);
	glMatrixMode(GL_MODELVIEW);
}

//画地球
void drawEarth()
{
	static bool loaded=false;
	//纹理绑定目标
	glBindTexture(GL_TEXTURE_2D,_texLoader.getTex(L"earth"));
	if (!loaded)
	{	
		//纹理坐标自动生成	
		glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
		glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
		//表面生成纹理坐标
		gluQuadricDrawStyle(_earth,GL_FILL);
		gluQuadricNormals(_earth,GLU_SMOOTH);
		//生成纹理坐标
		gluQuadricTexture(_earth,GL_TRUE);
		
	}
	//生成球体
	glPushMatrix();
	{	
		glEnable(GL_TEXTURE_2D);
		glRotatef(-90,1,0,0);
		gluSphere(_earth,r,100,100);
		glDisable(GL_TEXTURE_2D);

	}
	glPopMatrix();
	
}

//绘制D场景
void drawScene() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glMatrixMode(GL_MODELVIEW); //切换绘图视图
	glLoadIdentity(); //重置绘图视图

	glPushMatrix();
	//实现缩放
	glScalef(xyz[0],xyz[1],xyz[2]);
	//此时需要把地球往后方移动防止放大时候中间出现黑色圆圈
	glTranslatef(X,Y,-200);
	//实现拖动旋转
	glRotatef(_rotX/100,0,1,0);
	glRotatef(-_rotY/100,1,0,0);
	//实现自动旋转
	glRotatef(_angle,0,1,0);
	drawEarth();
	glPopMatrix();

	glutSwapBuffers();
}

//实现自动旋转效果
void update(int value) {
	_angle += 2.0f;
	if (_angle > 360) {
		_angle -= 360;
	}

	//刷新
	glutPostRedisplay(); 
	
	//初始值为30fps
	glutTimerFunc(flag, update, 0);
}

//处理鼠标点击旋转事件
//处理鼠标点击滑动事件
void handleMotion(int x,int y)
{
	int rx=x-oldX;
	int ry=480-y-oldY;
	_rotX+=rx;
	_rotY+=ry;
	//重画
	glutPostRedisplay();
}

//处理鼠标事件
void handleMouse(int button,int state,int x,int y)
{	
	//控制旋转
	static bool done=false;
	if (button==GLUT_LEFT_BUTTON)
	{	
		oldX=x;
		oldY=480-y;
	}	
	//放大
	if (button == GLUT_WHEEL_UP) {
		xyz[0] += 0.1; xyz[1] += 0.1; xyz[2] += 0.1;
		glutPostRedisplay();
	}
	//缩小
	if (button == GLUT_WHEEL_DOWN) {
		if (xyz[0] > 0.4) {
			xyz[0] -= 0.1; xyz[1] -= 0.1; xyz[2] -= 0.1;
		}
		glutPostRedisplay();
	}
}

int main(int argc, char** argv) {
	//初始化
	glutInit(&amp;argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
	glutInitWindowSize(800, 480);
	
	//创建窗口
	glutCreateWindow("地球仪");
	initRendering();
	
	//设置用户操作
	glutDisplayFunc(drawScene);
	glutKeyboardFunc(handleKeypress);
	glutReshapeFunc(handleResize);
	glutMotionFunc(handleMotion);
	glutMouseFunc(handleMouse);
	
	//运动效果
	glutTimerFunc(flag, update, 0); 
	
	glutMainLoop();
	//退出删除建模
	deinitRendering();
	return 0;
}

MyTexMgr.h
#pragma once

#include <string>
#include <map>
#include <gl/GLAux.h>

using namespace std;

enum TexMgrErrCode
{
	INVALD_TEXTURE = 0
};

typedef unsigned int uint;

/**
	@class MyTexMgr
	@brief Texture管理

*/
class MyTexMgr
{
public:
	MyTexMgr(void);
	virtual ~MyTexMgr(void);

public:
	bool	loadTex(const wstring&amp; texName, const wstring&amp; fileName);
	uint	getTex(const wstring&amp; texName);
	bool	delTex(const wstring&amp; texName);

public:
	bool	clear();

protected:
	AUX_RGBImageRec* loadBMP(const wchar_t* fileName);
	map<wstring, uint>	m_textures;
};

MyTexMgr.cpp
#include <GL/glaux.h>
#pragma comment ( lib, "glaux.lib" )
#include "MyTexMgr.h"
#include <fstream>
#include <gl/GL.h>
#include <gl/GLU.h>

MyTexMgr::MyTexMgr(void)
{
}

MyTexMgr::~MyTexMgr(void)
{
	if (m_textures.empty())
	{
		return;
	}
	map<wstring, uint>::iterator it;
	for (it = m_textures.begin(); it != m_textures.end(); ++it)
	{
		glDeleteTextures(1, &amp;it->second);
	}
}

bool MyTexMgr::loadTex(const wstring&amp; texName, const wstring&amp; fileName)
{
	GLuint	newElem;
	glGenTextures(1, &amp;newElem);

	AUX_RGBImageRec* rec = loadBMP(fileName.c_str());
	if (!rec)
	{
		glDeleteTextures(1, &amp;newElem);
		return false;
	}

	glBindTexture(GL_TEXTURE_2D, newElem);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rec->sizeX, rec->sizeY,
		0, GL_RGB, GL_UNSIGNED_BYTE, rec->data);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	if (getTex(texName) != INVALD_TEXTURE)
	{
		delTex(texName);
	}
	m_textures.insert(make_pair(texName, newElem));
	delete	rec->data;
	free(rec);

	return true;

}

uint MyTexMgr::getTex(const wstring&amp; texName)
{
	map<wstring, uint>::iterator it;
	it = m_textures.find(texName);
	if (it != m_textures.end())
	{
		return it->second;
	}
	else
	{
		return INVALD_TEXTURE;
	}
}

bool MyTexMgr::delTex(const wstring&amp; texName)
{
	map<wstring, uint>::iterator it;
	it = m_textures.find(texName);
	if (it != m_textures.end())
	{
		glDeleteTextures(1, &amp;it->second);
		m_textures.erase(it);
	}
	return true;
}

AUX_RGBImageRec* MyTexMgr::loadBMP(const wchar_t* fileName)
{
	wifstream infile(fileName);
	if (infile.is_open())
	{
		return auxDIBImageLoadW(fileName);
	}
	else
	{
		return NULL;
	}

}

bool MyTexMgr::clear()
{
	if (m_textures.empty())
	{
		return true;
	}
	map<wstring, uint>::iterator it;
	for (it = m_textures.begin(); it != m_textures.end(); ++it)
	{
		glDeleteTextures(1, &amp;it->second);
	}
	m_textures.clear();
	return true;
}

资料下载

百度网盘 提取码:srhl

原文地址:https://blog.csdn.net/qq_39411709/article/details/128414310

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_48400.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注