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

来源:互联网 发布:达内培训 linux全国 编辑:程序博客网 时间:2024/06/06 05:48

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

0 0