首页 > 学院 > 开发设计 > 正文

OpenGL键盘 WSADQE进行旋转缩放平移简单操作

2019-11-06 07:52:17
字体:
来源:转载
供稿:网友

http://blog.csdn.net/yulinxx/article/details/59538755

在上篇的基础上,添加键盘的控制,实现物体的缩放,平移,旋转操作

这里写图片描述

这里写图片描述 分析: 放大: 当摄像机沿Z轴靠近物体,则物体显示会变大,反之则小 左右平移: 摄像机往左移,则看到的物体往右移 旋转: 以相机到物体的距离为半径进行旋转 当旋转后,再平移,比如相机到了b位置,再平移,以绿线为向量进行平移. 已知相机到物体的向量,已知相机的向上up向量0,1,0,可以叉乘得到垂直的绿线向量,再以此向量进行平移即可. 旋转后的放大缩小,则以相机到物体的向量进行平移. 代码如下: 定义两个全局变量: glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f); // 相机位置 glm::vec3 cameraTarg = glm::vec3(0.0f, 0.0f, 0.0f); // 物体位置

WSAD移动相机, QE旋转相机,X还原视图

这里写图片描述

#define GLEW_STATIC#include <GL/glew.h>#include <GLFW/glfw3.h>#include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>#include <glm/gtc/type_ptr.hpp>#include <SOIL/SOIL.h>#include "Shader.h"#PRagma comment(lib, "SOIL.lib")#pragma comment (lib, "opengl32.lib")#pragma comment (lib, "glew32s.lib")#pragma comment (lib, "glfw3.lib") #pragma comment (lib, "glfw3dll.lib") #pragma comment (lib, "glew32mxs.lib")#pragma comment (lib, "assimp.lib")#define WIDTH 800#define HEIGH 600GLfloat g_nX = 0;GLfloat g_nY = 0;GLfloat g_nZ = 0;glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);glm::vec3 cameraTarg = glm::vec3(0.0f, 0.0f, 0.0f);//glm::mat4 view; // 视图矩阵GLfloat fRotateAngle = 0.0f;void keyFun(GLFWwindow* pWnd, int nKey, int nScanCode, int nAction, int nMode);int main(){ glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); GLFWwindow* pWnd = glfwCreateWindow(WIDTH, HEIGH, "OGL Geometry Shader", nullptr, nullptr); glfwMakeContextCurrent(pWnd); glfwSetKeyCallback(pWnd, keyFun); glewExperimental = GL_TRUE; glewInit(); glViewport(0, 0, WIDTH, HEIGH); GLfloat fPoint[] = { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, -0.5f, 0.6f, 0.0f, 0.0f, 1.0f, 1.0f, -0.2f, -0.5f, 0.0f, 0.0f, 0.4f, 1.0f, - 0.8f, 0.3f, 0.0f, 1.0f, 0.30f, 1.0f }; GLuint nVAO, nVBO; glGenVertexArrays(1, &nVAO); glBindVertexArray(nVAO); { glGenBuffers(1, &nVBO); glBindBuffer(GL_ARRAY_BUFFER, nVBO); { glBufferData(GL_ARRAY_BUFFER, sizeof(fPoint), fPoint, GL_STATIC_DRAW); glEnableVertexAttribArray(0); // vertex glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6* sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(1); // color glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6* sizeof(GLfloat), (GLvoid*)(3 * sizeof(GL_FLOAT))); } glBindBuffer(GL_ARRAY_BUFFER, 0); } glBindVertexArray(0); glEnable(GL_PROGRAM_POINT_SIZE); //Shader shader("./Shader/vertex.vx", "./Shader/geo.geo", "./Shader/frag.fg"); Shader shader("./Shader/vertex.vx", "./Shader/frag.fg"); shader.userShaderProg(); glm::mat4 model; // 模型矩阵 glm::mat4 view; // 视图矩阵 // 后移(观察点与物体在同一平面) 否则无法显示物体 view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f)); // 投影矩阵 视角 宽高比 近 远截面 glm::mat4 proj = glm::perspective(45.0f, GLfloat(WIDTH / HEIGH), 0.1f, 100.0f); // 获取Shader中 uniform 变量位置 GLint nModelLoc = glGetUniformLocation(shader.getProg(), "model"); GLint nViewLoc = glGetUniformLocation(shader.getProg(), "view"); GLint nProjLoc = glGetUniformLocation(shader.getProg(), "projection"); // 将矩阵传至Shader glUniformMatrix4fv(nModelLoc, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(nViewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(nProjLoc, 1, GL_FALSE, glm::value_ptr(proj)); GLfloat radius = 6.0f; while (!glfwWindowShouldClose(pWnd)) { glfwPollEvents(); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); GLfloat camX = sin(glfwGetTime()) * radius; GLfloat camZ = cos(glfwGetTime()) * radius; view = glm::lookAt(cameraPos, cameraTarg, glm::vec3(0.0, 1.0, 0.0)); glUniformMatrix4fv(nViewLoc, 1, GL_FALSE, glm::value_ptr(view)); glBindVertexArray(nVAO); { //glDrawArrays(GL_TRIANGLES, 0, sizeof(fPoint) / sizeof(GLfloat) / 6); //glDrawArrays(GL_POINTS, 0, sizeof(fPoint) / sizeof(GLfloat) / 6); glDrawArrays(GL_LINE_STRip, 0, sizeof(fPoint) / sizeof(GLfloat) / 6); } glBindVertexArray(0); glfwSwapBuffers(pWnd); } return 0;}void keyFun(GLFWwindow* pWnd, int nKey, int nScanCode, int nAction, int nMode){ if (nAction == GLFW_PRESS) { if (nKey == GLFW_KEY_W ) { // 物体到相机的单位向量 glm::vec3 direction = glm::normalize(cameraTarg - cameraPos); direction *= 0.2; // 移动0.2个单位向量 cameraPos += direction; } else if (nKey == GLFW_KEY_S) { glm::vec3 direction = glm::normalize(cameraTarg - cameraPos); direction *= 0.2; cameraPos -= direction; } else if (nKey == GLFW_KEY_A) { // 物体到相机的单位向量 glm::vec3 direction = glm::normalize(cameraTarg - cameraPos); // 物体到相机的单位向量 与 相机的向上向量相乘,得到垂直向量,即平移向量 glm::vec3 vertical = glm::normalize(glm::cross(direction, glm::vec3(0.0f, 1.0f, 0.0f))); vertical *= 0.2; cameraPos += vertical; // 移动相机位置 cameraTarg += vertical; //相机的指向位置也一起平衡(不平移则以原来的目标转圈) } else if (nKey == GLFW_KEY_D) { glm::vec3 direction = glm::normalize(cameraTarg - cameraPos); glm::vec3 vertical = glm::normalize(glm::cross(direction, glm::vec3(0.0f, 1.0f, 0.0f))); vertical *= 0.2; cameraPos -= vertical; cameraTarg -= vertical; } else if (nKey == GLFW_KEY_Q) { GLfloat radius = glm::distance(cameraPos, cameraTarg); fRotateAngle += 0.2; GLfloat camX = sin(fRotateAngle) * radius + cameraTarg.x; GLfloat camZ = cos(fRotateAngle) * radius + cameraTarg.z; cameraPos = glm::vec3(camX, 0.0, camZ); } else if (nKey == GLFW_KEY_E) { GLfloat radius = glm::distance(cameraPos, cameraTarg); fRotateAngle -= 0.2; GLfloat camX = sin(fRotateAngle) * radius + cameraTarg.x; GLfloat camZ = cos(fRotateAngle) * radius + cameraTarg.z; cameraPos = glm::vec3(camX, 0.0, camZ); } else if (nKey == GLFW_KEY_X) // 还原视图 { cameraPos = glm::vec3(0.0f, 0.0f, 3.0f); cameraTarg = glm::vec3(0.0f, 0.0f, 0.0f); } }}

这里写图片描述

源码下载: http://download.csdn.net/detail/yulinxx/9769945


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表