{"id":842,"date":"2022-07-27T16:00:12","date_gmt":"2022-07-27T08:00:12","guid":{"rendered":"https:\/\/www.acgloby.com\/?p=842"},"modified":"2022-07-27T16:00:12","modified_gmt":"2022-07-27T08:00:12","slug":"opengl-camera","status":"publish","type":"post","link":"https:\/\/www.acgloby.com\/index.php\/2022\/07\/27\/opengl-camera\/","title":{"rendered":"OpenGL-Camera"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u89c2\u5bdf\u7a7a\u95f4\uff08View Space\uff09<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.acgloby.com\/wp-content\/uploads\/2022\/07\/image-36.png\" alt=\"\" class=\"wp-image-843\"\/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">Direction<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">\u76f8\u673a\u65b9\u5411 = \u76f8\u673a\u4f4d\u7f6e - \u76f8\u673a\u76ee\u6807\u4f4d\u7f6e<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Right<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">\u53f3\u8f74 = \u4e0a\u5411\u91cf x \u76f8\u673a\u65b9\u5411<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Up<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e0a\u8f74 = \u76f8\u673a\u65b9\u5411 x \u53f3\u8f74<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">LookAt<\/h3>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" src=\"https:\/\/www.acgloby.com\/wp-content\/uploads\/2022\/07\/image-37.png\" alt=\"\" class=\"wp-image-850\"\/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">\u5176\u4e2d<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\"><strong>R<\/strong><\/mark>\u662f\u53f3\u5411\u91cf\uff0c<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\"><strong>U<\/strong><\/mark>\u662f\u4e0a\u5411\u91cf\uff0c<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>D<\/strong><\/mark>\u662f\u65b9\u5411\u5411\u91cf<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\"><strong>P<\/strong><\/mark>\u662f\u6444\u50cf\u673a\u4f4d\u7f6e\u5411\u91cf\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>glm::mat4 view;\nview = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), \n           glm::vec3(0.0f, 0.0f, 0.0f), \n           glm::vec3(0.0f, 1.0f, 0.0f));<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\u76f8\u673a\u79fb\u52a8<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">deltaTime<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">\u5728\u6bcf\u5e27\u4e2d\u8ba1\u7b97deltaTime<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>float currentFrame = glfwGetTime();\ndeltaTime = currentFrame - lastFrame;\nlastFrame = currentFrame;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">\u952e\u76d8\u8f93\u5165\u6539\u53d8\u4f4d\u7f6e<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">\u901a\u8fc7\u952e\u76d8\u7684\u8f93\u5165\uff0c\u6765\u6539\u53d8\u76f8\u673a\u7684\u4f4d\u7f6e<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void processInput(GLFWwindow *window)\n{\n    float cameraSpeed = 2.5f * deltaTime;\n    if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)\n        cameraPos += cameraSpeed * cameraFront;\n    if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)\n        cameraPos -= cameraSpeed * cameraFront;\n    if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)\n        cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;\n    if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)\n        cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u89c6\u89d2\u79fb\u52a8<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">\u6b27\u62c9\u89d2<\/h4>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.acgloby.com\/wp-content\/uploads\/2022\/07\/image-38.png\" alt=\"\" class=\"wp-image-854\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\u6b27\u62c9\u89d2(Euler Angle)\u662f\u53ef\u4ee5\u8868\u793a3D\u7a7a\u95f4\u4e2d\u4efb\u4f55\u65cb\u8f6c\u76843\u4e2a\u503c\uff0c\u4e00\u5171\u67093\u79cd\u6b27\u62c9\u89d2\uff1a\u4fef\u4ef0\u89d2(Pitch)\u3001\u504f\u822a\u89d2(Yaw)\u548c\u6eda\u8f6c\u89d2(Roll)\u3002<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"alignleft size-full\"><img decoding=\"async\" src=\"https:\/\/www.acgloby.com\/wp-content\/uploads\/2022\/07\/image-39.png\" alt=\"\" class=\"wp-image-855\"\/><\/figure>\n<\/div>\n\n<div class=\"wp-block-image\">\n<figure class=\"alignleft size-full\"><img decoding=\"async\" src=\"https:\/\/www.acgloby.com\/wp-content\/uploads\/2022\/07\/image-40.png\" alt=\"\" class=\"wp-image-856\"\/><\/figure>\n<\/div>\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.acgloby.com\/wp-content\/uploads\/2022\/07\/image-41.png\" alt=\"\" class=\"wp-image-859\"\/><\/figure>\n<\/div><\/div>\n\n\n\n<p class=\"has-white-color has-text-color wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"has-text-color wp-block-paragraph\" style=\"color:#ffffff00\">---<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>direction.x = cos(glm::radians(pitch)) * cos(glm::radians(yaw));\ndirection.y = sin(glm::radians(pitch));\ndirection.z = cos(glm::radians(pitch)) * sin(glm::radians(yaw));<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">\u9f20\u6807\u56de\u8c03\u51fd\u6570<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\"><code>glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>glfwSetCursorPosCallback(window, mouse_callback);<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>void mouse_callback(GLFWwindow* window, double xpos, double ypos);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>\u8ba1\u7b97\u9f20\u6807\u8ddd\u4e0a\u4e00\u5e27\u7684\u504f\u79fb\u91cf\u3002<\/li><li>\u628a\u504f\u79fb\u91cf\u6dfb\u52a0\u5230\u6444\u50cf\u673a\u7684\u4fef\u4ef0\u89d2\u548c\u504f\u822a\u89d2\u4e2d\u3002<\/li><li>\u5bf9\u504f\u822a\u89d2\u548c\u4fef\u4ef0\u89d2\u8fdb\u884c\u6700\u5927\u548c\u6700\u5c0f\u503c\u7684\u9650\u5236\u3002<\/li><li>\u8ba1\u7b97\u65b9\u5411\u5411\u91cf\u3002<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>void mouse_callback(GLFWwindow* window, double xpos, double ypos)\n{\n    float xoffset = xpos - lastX;\n    float yoffset = lastY - ypos; \n    lastX = xpos;\n    lastY = ypos;\n\n    float sensitivity = 0.05; \/\/\u7075\u654f\u5ea6\n    xoffset *= sensitivity;\n    yoffset *= sensitivity;\n\n    yaw   += xoffset;\n    pitch += yoffset;\n\n    \/\/\u572890\u5ea6\u65f6\u89c6\u89d2\u4f1a\u53d1\u751f\u9006\u8f6c\uff0c\u6240\u4ee5\u6211\u4eec\u628a89\u5ea6\u4f5c\u4e3a\u6781\u9650\n    if(pitch > 89.0f)\n        pitch = 89.0f;\n    if(pitch &lt; -89.0f)\n        pitch = -89.0f;\n\n    \/\/\u8ba1\u7b97\n    glm::vec3 front;\n    front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));\n    front.y = sin(glm::radians(pitch));\n    front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));\n    cameraFront = glm::normalize(front);\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\u76f8\u673a\u7f29\u653e<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">\u9f20\u6807\u6eda\u8f6e\u56de\u8c03\u51fd\u6570<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\"><code>glfwSetScrollCallback(window, scroll_callback);<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)\n{\n  if(fov >= 1.0f &amp;&amp; fov &lt;= 45.0f)\n    fov -= yoffset;\n  if(fov &lt;= 1.0f)\n    fov = 1.0f;\n  if(fov >= 45.0f)\n    fov = 45.0f;\n}<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>projection = glm::perspective(glm::radians(fov), WIDTH \/ HEIGHT, 0.1f, 100.0f);<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.acgloby.com\/wp-content\/uploads\/2022\/07\/cube3-1.gif\" alt=\"\" class=\"wp-image-884\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">\u6444\u50cf\u673a\u7c7b<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;glm\/glm.hpp>\n#include &lt;glm\/gtc\/matrix_transform.hpp>\n\nenum Camera_Movement {\n\tFORWARD,\n\tBACKWARD,\n\tLEFT,\n\tRIGHT\n};\n\n#pragma once\nclass Camera\n{\npublic :\n\tCamera(glm::vec3 position, glm::vec3 worldup, float yaw, float pitch);\n\t~Camera();\n\tglm::mat4 GetViewMatrix();\n\tvoid ProcessMouseScroll(float yoffset);\n\tvoid ProcessMouseMovement(float xoffset, float yoffset, bool constrainPitch);\n\tvoid ProcessKeyboard(Camera_Movement direction, float deltaTime);\n\n\tglm::vec3 Position = glm::vec3(0.0f, 0.0f, 0.0f);\n\tglm::vec3 Up;\n\tglm::vec3 Right;\n\tglm::vec3 Front;\n\tglm::vec3 WorldUp;\n\tfloat Pitch;\n\tfloat Yaw;\n\tfloat Fov;\n\tfloat MovementSpeed;\n\tfloat MouseSensitivity;\n\nprivate :\n\tvoid UpdateCameraVectors();\n};\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>#include \"Camera.h\"\n\n\/\/\u504f\u822a\u89d2\nconst float YAW\t\t\t= -90.0f;\n\/\/\u4fef\u4ef0\u89d2\nconst float PITCH\t\t= 0.0f;\n\/\/\u89c6\u91ce(Field of View)\nconst float FOV\t\t\t= 45.0f;\n\/\/\u79fb\u52a8\u901f\u5ea6\nconst float SPEED\t\t= 5.0f;\n\/\/\u9f20\u6807\u7075\u654f\u5ea6\nconst float SENSITIVITY = 0.1f;\n\nCamera::Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 worldup = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Fov(FOV)\n{\n\tPosition = position;\n\tYaw = yaw;\n\tPitch = pitch;\n\tWorldUp = worldup;\n\tUpdateCameraVectors();\n}\n\nCamera::~Camera()\n{\n\n}\n\nglm::mat4 Camera::GetViewMatrix()\n{\n\treturn glm::lookAt(Position, Position + Front, Up);\n}\n\nvoid Camera::ProcessKeyboard(Camera_Movement direction, float deltaTime) \n{\n\tfloat velocity = MovementSpeed * deltaTime;\n\tif (direction == FORWARD)\n\t\tPosition += Front * velocity;\n\tif (direction == BACKWARD)\n\t\tPosition -= Front * velocity;\n\tif (direction == LEFT)\n\t\tPosition += Right * velocity;\n\tif (direction == RIGHT)\n\t\tPosition -= Right * velocity;\n}\n\nvoid Camera::ProcessMouseScroll(float yoffset)\n{\n\tFov -= yoffset;\n\tif (Fov &lt; 1.0f)\n\t\tFov = 1.0f;\n\tif (Fov > 45.0f)\n\t\tFov = 45.0f;\n}\n\nvoid Camera::ProcessMouseMovement(float xoffset, float yoffset, bool constrainPitch) \n{\n\txoffset *= MouseSensitivity;\n\tyoffset *= MouseSensitivity;\n\n\tYaw += xoffset;\n\tPitch += yoffset;\n\n\tif (constrainPitch)\n\t{\n\t\tif (Pitch > 89.0f)\n\t\t\tPitch = 89.0f;\n\t\tif (Pitch &lt; -89.0f)\n\t\t\tPitch = -89.0f;\n\t}\n\tUpdateCameraVectors();\n}\n\n\nvoid Camera::UpdateCameraVectors()\n{\n\tglm::vec3 front = glm::vec3(0);\n\tfront.x = glm::cos(glm::radians(Yaw)) * glm::cos(glm::radians(Pitch));\n\tfront.y = glm::sin(glm::radians(Pitch));\n\tfront.z = glm::sin(glm::radians(Yaw)) * glm::cos(glm::radians(Pitch));\n\tFront = glm::normalize(front);\n\tRight = glm::normalize(glm::cross(Front, WorldUp));\n\tUp = glm::normalize(glm::cross(Front, Right));\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u5b8c\u6574\u5de5\u7a0b\u4ee3\u7801Github\uff1a<\/p>\n\n\n\n[github repo=\"acgloby\/LearnOpenGL\"]\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u89c2\u5bdf\u7a7a\u95f4\uff08View Space\uff09 Direction \u76f8\u673a\u65b9\u5411 = \u76f8\u673a\u4f4d\u7f6e &#8211; \u76f8\u673a\u76ee\u6807\u4f4d\u7f6e Right \u53f3\u8f74 = \u4e0a\u5411\u91cf x  &#8230;<\/p>\n","protected":false},"author":1,"featured_media":884,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"emotion":"","emotion_color":"","title_style":"","license":"","footnotes":""},"categories":[3],"tags":[],"class_list":["post-842","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-graphics"],"_links":{"self":[{"href":"https:\/\/www.acgloby.com\/index.php\/wp-json\/wp\/v2\/posts\/842","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.acgloby.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.acgloby.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.acgloby.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.acgloby.com\/index.php\/wp-json\/wp\/v2\/comments?post=842"}],"version-history":[{"count":0,"href":"https:\/\/www.acgloby.com\/index.php\/wp-json\/wp\/v2\/posts\/842\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.acgloby.com\/index.php\/wp-json\/wp\/v2\/media?parent=842"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.acgloby.com\/index.php\/wp-json\/wp\/v2\/categories?post=842"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.acgloby.com\/index.php\/wp-json\/wp\/v2\/tags?post=842"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}