opengl鼠标键盘控制相机漫游

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> using namespace std;
using namespace glm; const char* vsShaderName = "shader.vs";//顶点着色器
const char* fsShaderName = "shader.fs";//片元着色器 GLuint VBO;//顶点缓冲对象
GLuint IBO;//索引缓冲对象
static GLfloat *vertices;//顶点数组
static unsigned int *indices; //索引数组
GLuint ShaderProgram;
GLuint MatrixID;
int windowWidth = 800;
int windowHeight = 800;
//相机参数
glm::mat4 ViewMatrix;//视图矩阵
glm::mat4 ProjectionMatrix; //投影矩阵
glm::mat4 MVP;//模型视图矩阵
glm::mat4 ModelMatrix;//模型矩阵
glm::vec3 position = glm::vec3(5, 5, 5); //相机位置
float horizontalAngle = 3.14f;
float verticalAngle = 0.0f;
float initialFoV = 45.0f; //相机视场角
float speed = 0.05f; //平移速度
float mouseSpeed = 0.005f;
int mouseX, mouseY;//鼠标位置 窗口坐标
bool mouseLeftDown=false;//鼠标左键按下 // 传递键盘事件
static void SpecialKeyboardCB(unsigned char Key, int x, int y)
{
glm::vec3 direction(
cos(verticalAngle) * sin(horizontalAngle),
sin(verticalAngle),
cos(verticalAngle) * cos(horizontalAngle)
);
glm::vec3 right = glm::vec3(
sin(horizontalAngle - 3.14f / 2.0f),
0,
cos(horizontalAngle - 3.14f / 2.0f)
);
glm::vec3 up = glm::cross(right, direction); switch (Key) {
case 'w':
position += direction * speed;
//fprintf(stderr, "up \n");
break;
case 'd':
position += right * speed;
//fprintf(stderr, "right \n");
break;
case 's':
position -= direction * speed;
//fprintf(stderr, "down \n");
break;
case 'a':
position -= right * speed;
//fprintf(stderr, "left \n");
break;
case 27:
exit(1);
break;
default:
break;
//fprintf(stderr, "Unimplemented GLUT key\n");
//exit(1);
} float FoV = initialFoV;
ProjectionMatrix = glm::perspective(glm::radians(FoV), (float)windowWidth /(float) windowHeight, 0.1f, 100.0f);
ViewMatrix = glm::lookAt(
position,
position + direction,
up
);
ModelMatrix = glm::mat4(1.0);
MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;
glutPostRedisplay();//设置窗口重绘
} //传递鼠标事件
void mouseCB(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_DOWN)
{
mouseLeftDown = true;
mouseX = x;
mouseY = y;
}
else if (state == GLUT_UP)
{
mouseLeftDown = false;
}
}
} //传递鼠标位置
static void mouseMotionCB(int x, int y)
{
if (mouseLeftDown == true)
{
horizontalAngle += mouseSpeed * float(x - mouseX);
verticalAngle += mouseSpeed * float(y - mouseY);
mouseX = x;
mouseY = y;
SpecialKeyboardCB(0, 0, 0);
}
} //渲染回调函数
void RenderScenceCB() {
// 清空颜色缓存
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_LINES, 0, 40*4);
glDisableVertexAttribArray(0);
//交换前后缓存
glutSwapBuffers();
} //创建顶点
static void CreateVertexBuffer()
{
vertices = new GLfloat[40*3];
for (size_t i = 0; i < 10; i++)
{
vertices[i * 12] = 0;
vertices[i * 12 + 1] = 0;
vertices[i * 12 + 2] = i; vertices[i * 12 + 3] = 9;
vertices[i * 12 + 4] = 0;
vertices[i * 12 + 5] = i; vertices[i * 12 + 6] = i;
vertices[i * 12 + 7] = 0;
vertices[i * 12 + 8] = 0; vertices[i * 12 + 9] = i;
vertices[i * 12 + 10] = 0;
vertices[i * 12 + 11] = 9;
}
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, 40*3* sizeof(GLfloat), vertices, GL_STATIC_DRAW);
} static void AddShader(GLuint ShaderProgram, const char* pShaderText, GLenum ShaderType)
{
// 根据shader类型参数定义两个shader对象
GLuint ShaderObj = glCreateShader(ShaderType);
// 检查是否定义成功
if (ShaderObj == 0) {
fprintf(stderr, "Error creating shader type %d\n", ShaderType);
exit(0);
}
// 定义shader的代码源
const GLchar* p[1];
p[0] = pShaderText;
GLint Lengths[1];
Lengths[0] = strlen(pShaderText);
glShaderSource(ShaderObj, 1, p, Lengths);
glCompileShader(ShaderObj);// 编译shader对象
// 检查和shader相关的错误
GLint success;
glGetShaderiv(ShaderObj, GL_COMPILE_STATUS, &success);
if (!success) {
GLchar InfoLog[1024];
glGetShaderInfoLog(ShaderObj, 1024, NULL, InfoLog);
fprintf(stderr, "Error compiling shader type %d: '%s'\n", ShaderType, InfoLog);
exit(1);
}
// 将编译好的shader对象绑定到program object程序对象上
glAttachShader(ShaderProgram, ShaderObj);
} // 编译着色器函数
static void CompileShaders()
{
// 创建着色器程序
ShaderProgram = glCreateProgram();
// 检查是否创建成功
if (ShaderProgram == 0) {
fprintf(stderr, "Error creating shader program\n");
exit(1);
}
// 存储着色器文本的字符串
string vs, fs;
// 分别读取着色器文件中的文本到字符串
std::ifstream VertexShaderStream(vsShaderName, std::ios::in);
if (VertexShaderStream.is_open()) {
std::stringstream sstr;
sstr << VertexShaderStream.rdbuf();
vs = sstr.str();
VertexShaderStream.close();
}
else {
printf("Error to open %s\n", vsShaderName);
getchar();
exit(0);
}
std::ifstream FragmentShaderStream(fsShaderName, std::ios::in);
if (FragmentShaderStream.is_open()) {
std::stringstream sstr;
sstr << FragmentShaderStream.rdbuf();
fs = sstr.str();
FragmentShaderStream.close();
} // 添加顶点着色器和片段着色器
AddShader(ShaderProgram, vs.c_str(), GL_VERTEX_SHADER);
AddShader(ShaderProgram, fs.c_str(), GL_FRAGMENT_SHADER);
// 链接shader着色器程序,并检查程序相关错误
GLint Success = 0;
GLchar ErrorLog[1024] = { 0 };
glLinkProgram(ShaderProgram);
glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success);
if (Success == 0) {
glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog);
fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog);
exit(1);
}
// 检查验证在当前的管线状态程序是否可以被执行
glValidateProgram(ShaderProgram);
glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &Success);
if (!Success) {
glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog);
fprintf(stderr, "Invalid shader program: '%s'\n", ErrorLog);
exit(1);
}
// 设置到管线声明中来使用上面成功建立的shader程序
glUseProgram(ShaderProgram);
MatrixID = glGetUniformLocation(ShaderProgram, "gWVP");
} int main(int argc, char ** argv) {
// 初始化GLUT
glutInit(&argc, argv);
// 显示模式:双缓冲、RGBA
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(windowWidth, windowHeight);
glutInitWindowPosition(100, 100);
glutCreateWindow("CameraTest");
GLenum res = glewInit();
if (res != GLEW_OK) {
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return 1;
}
// 开始渲染
glutDisplayFunc(RenderScenceCB);
// 注册键盘事件
glutKeyboardFunc(SpecialKeyboardCB);
//注册鼠标事件
glutMouseFunc(mouseCB);
glutMotionFunc(mouseMotionCB);
mouseX = windowWidth / 2;
mouseY = windowHeight / 2;
// 缓存清空后的颜色值
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//创建顶点
CreateVertexBuffer();
// 编译着色器
CompileShaders();
//开启深度测试
glEnable(GL_DEPTH_TEST);
// 通知开始GLUT的内部循环
glutMainLoop();
delete vertices;
return 0;
}
#version 330
layout (location = 0) in vec3 Position;
uniform mat4 gWVP;
out vec3 Color;
void main()
{
gl_Position = gWVP * vec4(Position, 1.0);
Color = Position/10;
}
#version 330
out vec3 FragColor;
in vec3 Color;
void main()
{
FragColor = Color;
}
本文链接https://www.cnblogs.com/gucheng/p/10139299.html
opengl鼠标键盘控制相机漫游的更多相关文章
- 【Unity3D】使用鼠标键盘控制Camera视角(即时战略类游戏视角):缩近,拉远,旋转
今天写一个demo,要用到鼠标键盘控制三维视角,因此写了个脚本用于控制. 该脚本可以用于即时战略类游戏的视角,提供了缩进,拉伸,旋转.同时按住鼠标右键不放,移动鼠标可以实现第一人称视角的效果. usi ...
- C#模拟鼠标键盘控制其他窗口(一)
编写程序模拟鼠标和键盘操作可以方便的实现你需要的功能,而不需要对方程序为你开放接口.比如,操作飞信定时发送短信等.我之前开发过飞信耗子,用的是对飞信协议进行抓包,然后分析协议,进而模拟协议的执行,开发 ...
- synergy一个鼠标键盘控制多台电脑
有些时候我们同时操作多台电脑,但是我们只用一个鼠标和一个键盘,如果通过转换器啊或者是多个鼠标键盘就非常不方便了 下面我介绍一下通过安装synergy这个软件来给开发人员提供方便 这个软件安装比较简单, ...
- 一个鼠标键盘控制两台甚至多台主机的方法--Synergy
在多台主机,不同系统中操作.避免了更换键鼠的麻烦.即使下面图中的功能. 鼠标同时在三台或者多台主机之间进行移动,而且是无缝滑动,鼠标直接从左滑倒右,而且支持,这台电脑复制,另一台黏贴.非常的方便实用. ...
- 用鼠标键盘来控制你的Android手机——同屏显示简单教程
今天在微博上看到有人用电脑鼠标操作iPhone手机玩打飞机游戏,非常炫,虽然自己用的不是iPhone,但相信Android手机肯定也能实现这样的功能,于是网上各种搜索方法,终于看到了一篇试用成功的帖子 ...
- 【198】Synergy - 鼠标键盘共享软件
参考:Synergy X64 v1.7.4 官方最新版 参考:Synergy安装方法 功能介绍: 可以将配置局域网的电脑实现同一个鼠标键盘控制两台电脑,效果类似一台电脑使用双屏的效果,键盘会根据鼠标的 ...
- 关于MFC与OpenGL结合绘图区域用鼠标来控制图形的移动的坑
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/11773171.html 之前开发的导入多个模型,旋转,分别移动什么什么的,都是在纯OpenGL ...
- 用代码控制鼠标键盘(C#语言)
前些时间想做一个鼠标点击器,用到了这些知识. 下面整理记录一下. ps.感谢各位大神 下面直接上代码 1.鼠标的控制 class MouseMove { #region MouseEvent [Sys ...
- OpenGL之路(八)加入�光照效果和键盘控制
在opengl中加入�光照的效果,可用键盘控制放大缩小 w键放大 s键缩小 d键开关灯 预览效果例如以下: 源代码例如以下: #include <gl/glut.h> #include & ...
随机推荐
- XSS攻击(出现的原因、预防措施)
XSS攻击(出现的原因.预防措施......) 验证XSS攻击重点不是去查找可输入哪些内容会出现什么样的bug就是测试XSS攻击,重点是了解它出现的原理,为什么会出现XSS攻击,导致一些问题出现? ...
- javaweb的maven项目结构
本来准备看javaweb的项目结构,因为之前自己建maven的项目结构,总是各种出错,后来干脆用maven自己携带的项目结构. 一个最基本的web目录结构如下,红框部分为必须有的,其他的随意. 这是一 ...
- 希尔排序Shell_Sort
概述:听到希尔排序这个名称,心里完全没有任何概念,因为这个名称不能给你提供任何有效的信息.但是它的名字又是那么的特殊,以至于学习过数据结构排序的都知道这种方法的存在.现在我们就来看一下所谓的希尔排序. ...
- ln -s /usr/local/jdk1.8.0_201/bin/java /bin/java
ln -s /usr/local/jdk1.8.0_201/bin/java /bin/java
- python协程初步---一个生成器的实现
和列表那种一下占据长度为n的内存空间不同的是,生成器在调用的过程中逐步占据内存空间,因此有着很大的优势 一个斐波纳契数列的例子 def myfibbo(num): a,b=, count= while ...
- JQuery实践--动画
显示和隐藏没有动画的元素 使包装集里的元素隐藏 hide(speed,callback) speed:可选,速度.slow,normal,fastcallback:函数,可选,完成后调用的函数,无参数 ...
- AtCoder Beginner Contest 142【D题】【判断素数的模板+求一个数的因子的模板】
D - Disjoint Set of Common Divisors Problem Statement Given are positive integers AA and BB. Let us ...
- 五十一.Openstack概述 部署安装环境 、 部署Openstack OpenStack操作基础
虚拟化技术的底层构成: 内核的虚拟化模块(KVM):从内核集去提供虚拟化及CPU指令集的支持,要求CPU支持,(CPU有VMX指令集) 硬件仿真层(QEMU):虚拟一些周边设备,鼠标.键盘.网卡. ...
- APPLICATION SERVER和WEBSHPERE和Red Hat操作系统
1.Web服务器专门处理HTTP请求(request),但是应用程序服务器是通过很多协议来为应用程序提供(serves)商业逻辑(business logic) 2.WebSphere Applica ...
- MySQL备忘点(上)
给自己看的,所以以举例子为主了 检索数据 SELECT 检索单列 SELECT name FROM student 检索多列 SELECT no, name FROM student 检索所有列 S ...