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 & ...
随机推荐
- Css案例整理
1.实现两个div并排显示 案例:checkbox的标题和内容需要并排显示,checkbox竖向排列 <head> <style type="text/css"& ...
- 关于静态资源放在CDN上
https://www.netlify.com/ https://app.netlify.com/signup?_ga=2.194141613.1097457726.1543799087-101005 ...
- 基于SSM框架的通用权限框架设计
1. 整体解决方案概述 1.1 权限整体解决方案概述 权限设计主要有一下几大部分组成: PassPort: 针对现在系统的分析,系统之间有部分信息是共享的,这部分信息将由 ...
- BZOJ 4013/Luogu P3240 [HNOI2015] 实验比较 (树形DP)
题目传送门 分析 放一个dalao博客: xyz32768 的博客,看完再回来看本蒟蒻的口胡吧(其实嘛-不回来也行) 精髓是合并的方案数的计算,至于为什么是Ci−1j−1\large C_{i-1}^ ...
- tap 事件会触发两次问题
因项目中使用 coffeeScript (http://coffee-script.org/),此处记录下用 coffeeScript 语法解决 tap 事件触发两次的问题. 在 id="b ...
- 定时器TIM,pwm
一.定时器 1. 定义 设置等待时间,到达后则执行指定操作的硬件. 2. STM32F407的定时器有以下特征 具有基本的定时功能,也有PWM输出(灯光控制.电机的转速).脉冲捕获功能( ...
- 51nod 1051
* 最大子矩阵 * sum[i][j] 表示第 i 行前 j 列的和,即每一行的前缀 * i,j 指针枚举列,k指针枚举行 * Now 记录当前枚举的子矩阵的价值 * 由于记录了前缀信息,一旦 Now ...
- 关于openstack 网络相关的文章收集
journalctl工具基础介绍(你需要这个的.) https://blog.51cto.com/13598893/2072212 新版devstack使用systemd的方式来管理OpenStack ...
- 如何更改电脑ip
首先打开控制面板==>点击网络和internet==>点击网络和共享中心==>点击更改适配器设置==>右键无线连接或宽带连接(视情况而定)==>属性==>双击ipv ...
- codeforces gym #101161F-Dictionary Game(字典树+树上删边游戏)
题目链接: http://codeforces.com/gym/101161/attachments 题意: 给一个可以变化的字典树 在字典树上删边 如果某条边和根节点不连通那么这条边也删除 谁没得删 ...