OpenGL鼠标控制视角旋转

这篇博客探讨了如何使用OpenGL实现相机的移动和旋转。作者通过glLookAt设置视角,并结合键盘和鼠标事件来调整视点位置和角度,实现了在三维空间中的前进、后退、左右和上下转动。此外,还涉及到了特殊键位处理,如滚轮和F1键的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在研究相机的移动问题,顺便就写一下

首先,上代码

​
​
/*------------------------------头文件------------------------------*/
#define GLUT_DISABLE_ATEXIT_HACK    //不加就报错,这两行都是
#define GLEW_STATIC
#define BMP_Header_Length 54
#define WindowWidth  GetSystemMetrics(SM_CXSCREEN)
#define WindowHeight GetSystemMetrics(SM_CYSCREEN)
//省略部分头文件
#include <io.h>
#include <gl\glu.h>
#include <gl\glut.h>
#include <gl\glaux.h>
#include <graphics.h>

#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
#define PI 3.1415926535897932384626     //必须加后面,加前面会报错,我也不知道为什么
using namespace std;            //我也不知道是什么



/*__________________________________________定义变量_________________________________________________*/
//省略部分变量
...//省略部分函数
void Mouse(int button, int state, int x, int y) {
	OriX = x, OriY = y;
}

void KeyboardFunc(unsigned char Key, int x, int y) {
	du -= 90;								//添加旋转角度,要不没法直走
	if (Key == 'A' || Key == 'a') {//左走
		du += 90;
		sz -= cos(c * du) * speed;          //计算角度
		sx += sin(c * du) * speed;
		FX = 2;
		PLYERX++;
		du -= 90;
		glutPostRedisplay();
	}
	if (Key == 'D' || Key == 'd') {//右走
		du += 90;
		sz += cos(c * du) * speed;          //计算角度
		sx -= sin(c * du) * speed;
		FX = 4;
		PLYERX--;
		du -= 90;
		glutPostRedisplay();
	}
	if (Key == 'W' || Key == 'w') {//前
		sz += cos(c * du) * speed;          //计算角度
		sx -= sin(c * du) * speed;
		PLYERY++;
		glutPostRedisplay();
	}
	if (Key == 'S' || Key == 's') {//后
		sz -= cos(c * du) * speed;          //计算角度
		sx += sin(c * du) * speed;
		FX = 3;
		PLYERY--;
		glutPostRedisplay();
	}
	if (KEY_DOWN(VK_LBUTTON)) {//敌方死亡判定
		PlayBoom();
		if (DRY1 == PLYERY || DRX1 == PLYERX) {
			hth1 = 0;
		}
		if (DRY2 == PLYERY || DRX2 == PLYERX) {
			hth2 = 0;
		}
		if (DRY3 == PLYERY || DRX3 == PLYERX) {
			hth3 = 0;
		}
		if (DRY4 == PLYERY || DRX4 == PLYERX) {
			hth4 = 0;
		}
	}
	if (Key == 27) {         //ESC
		WinExec("Data\\PointData\\KillGameProcess.exe /f /t /im Point.exe", SW_NORMAL);
		exit(0);
		glutPostRedisplay();
	}
	du += 90;
}

void SpecialKeys(int key, int x, int y) {
	if (key == GLUT_KEY_UP) {
		EyeFar++;
		glutPostRedisplay();
	}
	if (key == GLUT_KEY_DOWN) {
		EyeFar--;
		glutPostRedisplay();
	}
	if (key == GLUT_KEY_F1) {
		bmppm();
		glutPostRedisplay();
	}
}

void Motion(int x, int y) {
	du += x - OriX; //鼠标在窗口x轴方向上的增量加到视点与x轴的夹角上,就可以左右转
	h += 0.03 * (y - OriY); //鼠标在窗口y轴方向上的改变加到视点y的坐标上,就可以上下转
	if (h > 4.2)
		h = 4.2; //对视点y坐标作一些限制,不会使视点太奇怪
	else if (h < -4.2)
		h = -4.2;
	OriX = x, OriY = y; //将此时的坐标作为旧值,为下一次计算增量做准备
}

void PassiveMotion(int x, int y) {
	du += x - OriX; //鼠标在窗口x轴方向上的增量加到视点与x轴的夹角上,就可以左右转
	h += 0.03 * (y - OriY); //鼠标在窗口y轴方向上的改变加到视点y的坐标上,就可以上下转
	if (h > 4.2)
		h = 4.2; //对视点y坐标作一些限制,不会使视点太奇怪
	else if (h < -4.2)
		h = -4.2;
	OriX = x, OriY = y; //将此时的坐标作为旧值,为下一次计算增量做准备
}

...//省略部分Idle代码

const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };

const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };

const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };

const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };

const GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f };

const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };

const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };

const GLfloat high_shininess[] = { 100.0f };

...   //省略主函数
​

代码直接从我的工程搬来的, 可能有些未声明的东东

主要原理就是通过gllookat设置视角旋转,再在程序里再用一个lookat设置视点到xyz尽量接近0的位置,就可以实现视角旋转

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值