键盘wsad控制相机位移,鼠标左键按下控制相机旋转
效果如下
代码如下
#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) {// 初始化GLUTglutInit(&argc, argv);// 显示模式:双缓冲、RGBAglutInitDisplayMode(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

转载于:https://www.cnblogs.com/gucheng/p/10139299.html

opengl鼠标键盘控制相机漫游相关推荐

  1. Cesium 键盘鼠标控制相机漫游(源码+原理讲解)

    Cesium 键盘鼠标控制相机漫游(源码+原理讲解) 在各大博客平台上,Cesium使用键盘控制相机漫游的源码已经有不少人贴出源码,本人在浏览这些源码的过程中发现大家采用的方式基本一致,大部分代码都是 ...

  2. openGL绘制带纹理地球,并实现鼠标键盘控制

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一.绘制球体 二.关键代码 球体类(Sphere) 主函数 顶点着色器 片元着色器 显示效果 源码下载 参考 前言 openGL绘制 ...

  3. Mouse Without Borders 一套鼠标键盘控制多台电脑

    当我的桌子上除了笔记本之外还多了一个台式机后,两个鼠标,两个键盘就显得十分多余,于是开始探索怎样用一套鼠标键盘控制多台电脑... 首先搜到的是这玩意--KVM切换器 在他49个赞的诱惑下,我还去淘宝搜 ...

  4. python热键+鼠标键盘控制

    python热键+鼠标键盘控制 应用:ctrl+home自动输入文本:home停止 代码:hotkey 应用:ctrl+home自动输入文本:home停止 代码:hotkey #!/usr/bin/e ...

  5. android 键盘使用教程,用鼠标键盘控制你的Android手机完整图文教程

    网上大都是91助手for android来连接手机和电脑,我自己比较偏向于豌豆荚,都可以的,下面给出我的步骤及过程中遇到的几个小问题,供大家参考! 一.鼠标键盘控制手机教程 1.在PC上,安装豌豆荚, ...

  6. android usb鼠标,用鼠标键盘控制你的Android手机完整图文教程

    网上大都是91助手for android来连接手机和电脑,我自己比较偏向于豌豆荚,都可以的,下面给出我的步骤及过程中遇到的几个小问题,供大家参考! 一.鼠标键盘控制手机教程 1.在PC上,安装豌豆荚, ...

  7. android键盘管理,用鼠标键盘控制你的Android手机完整图文教程

    32路伺服电机控制器V3.0 官方安装版 类型:编程辅助大小:15.0M语言:中文 评分:7.5 标签: 立即下载 网上大都是91助手for android来连接手机和电脑,我自己比较偏向于豌豆荚,都 ...

  8. 一套鼠标键盘控制两台电脑-绝!

    Oliver's R&D Lab C/C++/Linux 一套鼠标键盘控制两台电脑-绝! 这个工具是推荐给双电脑工作人员的,不是的就不用往下看了,嗯. synergy-----按照它主页( h ...

  9. [共享工具] 一套鼠标键盘控制两台不同系统的主机

    问题描述 用一组有线鼠标键盘控制两台主机(不同系统). 解决方法 Barrier,推荐. synergy.

最新文章

  1. volatile 关键字解析
  2. 针对故障场景的血液,汗液和书写自动集成测试
  3. 关于dialog的一点东西
  4. 洛谷 P1824 进击的奶牛 【二分答案】(求最大的最小值)
  5. 金蝶kis专业版公网访问_金蝶KIS云专业版—【账务处理】进阶操作101问
  6. 静态页面被拦截解决办法
  7. pyqt5 不报错退出_Python学习之旅:使用virtualenv创建Python环境及PyQT5环境配置
  8. kvm虚拟化学习笔记(十)之kvm虚拟机快照备份
  9. android-getTextSize返回值是以像素(px)为单位的,setTextSize()以sp为单位
  10. lnmp之PDO_mysql.so
  11. 实验板FPGA型号在哪里看_【VE】一文看懂乙烯基树脂发展史!
  12. SQL数据库安装-数据库的下载
  13. win8.1安装马上6,连不上
  14. google play测试内购流程
  15. 2021年中式面点师(中级)最新解析及中式面点师(中级)模拟考试题库
  16. scrapy爬虫折腾系列-02
  17. 立方体在三维坐标中的旋转(3D,Spining)
  18. el-input实现防抖
  19. Python3 matplotlib+numpy画函数图像
  20. 【NLP】1、nlp各类中文文本语料库

热门文章

  1. vivo怎么调时间_手表怎么调时间?日期时间怎么调,电子手表
  2. 总裁演说思维:口才训练方法留言评论法
  3. 干货分享 | 挖到3款好用的配音软件,短视频配音超省心
  4. Java的object如何转为map_java实现Object和Map之间的转换3种方式
  5. 对于String的用法详解
  6. vue的for循环数组push的坑
  7. 游戏中的网络同步机制——Lockstep(帧同步)
  8. 深度学习评价指标系列——CDF累积分布函数(分布函数)
  9. canny算子的python实现以及pytorch实现
  10. 实用英语:“上厕所”怎么说