OpenGL视角LooAt及Perspective理解
来源:互联网 发布:矩阵制组织结构的特点 编辑:程序博客网 时间:2024/06/10 10:11
在:
http://blog.csdn.net/yulinxx/article/details/59538755
的基础上,修改 main.cpp
理解 glm::perspective 和 glm::lookAt
相机竖立在50米开外, 用90度的视角去看0,0,0点的位置,
那么50米外原点中,高度为50的物体,正好看到, 超过50则会被截断!
void
gluLookAt(GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ,
GLdouble centerX, GLdouble centerY, GLdouble centerZ,
GLdouble upX, GLdouble upY, GLdouble upZ);
glm::mat4 projection =
glm::perspective(fovyInRadians, aspect, zNear, zFar);
相机视角,以侧视图观察, 在此处以90度为 fovyInRadians 值,
在图中,以45度角进行半分开来,予以剖析
相机离原点为50, 则原点处Y最大能显示为50, z=-50处Y最大能显示为100
若在原点绘图,
我们绘制一个 98*98的正方形,则在视图中,几乎填满视图 (X Y 值分别从-49 到 +49)
为显示边框,所以绘制一个稍小于100的正方形
glm::lookAt 用于相机定位
glm::perspective用于相机视角设置
#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"#include <stdio.h>#include <Windows.h>#include <math.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 500#define HEIGH 500glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 50.0f); // 相机距离原点50glm::vec3 cameraTarg = glm::vec3(0.0f, 0.0f, 0.0f);glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);glm::vec4 mousePos;GLfloat fRotateAngle = 0.0f;void keyFun(GLFWwindow* pWnd, int nKey, int nScanCode, int nAction, int nMode);void mouseFun(GLFWwindow* pWnd, int, int, int);void cursorFun(GLFWwindow* window, double x, double y);//////////////////////////////////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); glfwSetCursorPosCallback(pWnd, cursorFun); glfwSetMouseButtonCallback(pWnd, mouseFun); glewExperimental = GL_TRUE; glewInit(); glViewport(0, 0, WIDTH, HEIGH);#if 0 // 在原点处绘图,即离相机50, 将Y值稍微缩小,便于显示 GLfloat cube[] = { -49.0f, -49.0f, -0.0f, 49.0f, -49.0f,-0.0f, 49.0f, -49.0f,-0.0f, 49.0f, 49.0f,-0.0f, 49.0f, 49.0f,-0.0f, -49.0f, -49.0f, -0.0f, -49.0f, -49.0f, -0.0f, -49.0f, 49.0f,-0.0f, -49.0f, 49.0f, -0.0f, 49.0f, 49.0f,-0.0f, -49.0f, 49.0f, -0.0f, 49.0f, -49.0f, -0.0f, };#else // 在z -50 处绘图,即离相机100,将Y值稍微缩小,便于显示 GLfloat cube[] = { -99.0f, -99.0f, -50.0f, 99.0f, -99.0f,-50.0f, 99.0f, -99.0f,-50.0f, 99.0f, 99.0f,-50.0f, 99.0f, 99.0f,-50.0f, -99.0f, -99.0f, -50.0f, -99.0f, -99.0f, -50.0f, -99.0f, 99.0f,-50.0f, -99.0f, 99.0f, -50.0f, 99.0f, 99.0f,-50.0f, -99.0f, 99.0f, -50.0f, 99.0f, -99.0f, -50.0f, };#endif GLuint nVAO, nVBO; glGenVertexArrays(1, &nVAO); glBindVertexArray(nVAO); { glGenBuffers(1, &nVBO); glBindBuffer(GL_ARRAY_BUFFER, nVBO); { glBufferData(GL_ARRAY_BUFFER, sizeof(cube), &cube[0], GL_STATIC_DRAW); glEnableVertexAttribArray(0); // vertex glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); } glBindBuffer(GL_ARRAY_BUFFER, 0); } glBindVertexArray(0); Shader shader("./Shader/vertex.vx", "./Shader/frag.fg"); shader.userShaderProg(); glm::mat4 model; // 模型矩阵 glm::mat4 view; // 视图矩阵 // 投影矩阵 视角 宽高比 近 远截面 // 侧视图 glm::mat4 proj = glm::perspective(3.141592f/2.0f, GLfloat(WIDTH / HEIGH), 1.0f, 200.0f); 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)); while (!glfwWindowShouldClose(pWnd)) { glfwPollEvents(); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); view = glm::lookAt(cameraPos, cameraTarg, cameraUp); glUniformMatrix4fv(nViewLoc, 1, GL_FALSE, glm::value_ptr(view)); glBindVertexArray(nVAO); { glDrawArrays(GL_LINES, 0, sizeof(cube)/sizeof(GLfloat)/3); } 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.1; // 移动0.1个单位向量 cameraPos += direction; } else if (nKey == GLFW_KEY_S) { glm::vec3 direction = glm::normalize(cameraTarg - cameraPos); direction *= 0.1; cameraPos -= direction; } else if (nKey == GLFW_KEY_A) { // 物体到相机的单位向量 glm::vec3 direction = glm::normalize(cameraTarg - cameraPos); // 物体到相机的单位向量 与 相机的向上向量相乘,得到垂直向量,即平移向量 glm::vec3 vertical = glm::normalize(glm::cross(direction, cameraUp)); vertical *= 0.1; 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, cameraUp)); vertical *= 0.1; cameraPos -= vertical; cameraTarg -= vertical; } else if (nKey == GLFW_KEY_Q) { GLfloat radius = glm::distance(cameraPos, cameraTarg); fRotateAngle += 0.1; 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.1; 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, 5.0f); cameraTarg = glm::vec3(0.0f, 0.0f, 0.0f); } }}void mouseFun(GLFWwindow* window, int button, int action, int mods){ if (action == GLFW_PRESS) { switch (button) { case GLFW_MOUSE_BUTTON_LEFT: { //printf("Screen X:%.3f Y:%.3f\t\tOGL X:%.3f, Y:%.3f\t\t\tLeft button clicked!\n", mousePos.x, mousePos.y, mousePos.z, mousePos.w); float mouseX = mousePos.x / (WIDTH * 0.5f) - 1.0f; float mouseY = mousePos.y / (HEIGH * 0.5f) - 1.0f; //mouseX = mousePos.z; //mouseY = -mousePos.w; //printf("mouse X:%.3f mouseY:%.3f \n", mouseX, mouseY); glm::mat4 proj = glm::perspective(45.0f, GLfloat(WIDTH / HEIGH), 1.0f, -100.0f); glm::mat4 view = glm::lookAt(cameraPos, cameraTarg, cameraUp); glm::mat4 invVP = glm::inverse(proj * view); glm::vec4 screenPos = glm::vec4(mouseX, -mouseY, 1.0f, 1.0f); glm::vec4 worldPos = invVP * screenPos; glm::vec3 dir = glm::normalize(glm::vec3(worldPos)); printf("dir X:%.3f dir:%.3f dir:%.3f\n", dir.x, dir.y, dir.z); } break; case GLFW_MOUSE_BUTTON_MIDDLE: printf("Middle button clicked!\n"); break; case GLFW_MOUSE_BUTTON_RIGHT: system("cls"); printf("Right button clicked!\n"); break; default: printf("Default \n"); return; } } return;}void cursorFun(GLFWwindow* window, double x, double y){ float xpos = float((x - WIDTH / 2) / WIDTH) * 2; float ypos = float(0 - (y - HEIGH / 2) / HEIGH) * 2; //printf("Mouse position move to [ %.3f : %.3f ]\n", xpos, ypos); mousePos = glm::vec4(x, y, xpos, ypos); return;}
源码:
http://download.csdn.net/download/yulinxx/9975863
- OpenGL视角LooAt及Perspective理解
- OpenGL Perspective Projection Matrix
- OpenGL Perspective Projection Matrix
- OpenGL Perspective Projection Matrix
- OpenGL Perspective Projection Matrix
- OpenGL Perspective Projection Matrix
- opencv3_java 图像透视视角转换Perspective warpPerspective
- OpenGL视角控制
- opengl 视角问题
- Android OpenGL相机视角
- 学习openGL灯光、视角,便于理解参数含义的几个演示程序
- OpenGL Es 视角设定(glFrustum)
- opengl简单的视角变换
- OpenGL(3)-OpenGL视角的计算
- OpenGL Perspective Projection Matrix (Easy Understood)
- Perspective
- Perspective
- perspective
- Java Jersey web service 总结
- vim:学习资料——把vim打造成 IDE
- ZooKeeper学习之zookeeper的ACL(AUTH)
- JDBC的使用
- http://doc.qt.io/qt-5/qtwidgets-gestures-imagegestures-example.html
- OpenGL视角LooAt及Perspective理解
- 【Leetcode】【python】Search Insert Position
- QGesture
- Leetcode--Two Sum
- 深度学习--Batch_Normlization
- day3代码
- “RPC好,还是RESTful好?”
- 牛客网-剑指offer-10-矩形覆盖
- HDU 6194 string string string :后缀数组+单调队列 | 后缀自动机