åã®ã¬ãã¹ã³ã§ã¯ããã¥ãŒãããªãã¯ã¹ãšãããã䜿çšããŠã·ãŒã³å
ãç§»åããæ¹æ³ã«ã€ããŠèª¬æããŸããïŒèгå¯è
ã®èŠç¹ãå°ãç§»åããŸããïŒã OpenGLã«ã¯ã«ã¡ã©ã®æŠå¿µã¯ãããŸããããã·ãŒã³å
ã®ãã¹ãŠã®ãªããžã§ã¯ãã芳å¯è
ãšã¯åå¯Ÿã®æ¹åã«ç§»åããããšã§ã·ãã¥ã¬ãŒãããããã«ãã£ãŠç§»åããŠãããããªé¯èŠãäœæã§ããŸãã
ãã®ãã¥ãŒããªã¢ã«ã§ã¯ãOpenGLã§ã«ã¡ã©ãäœæããæ¹æ³ã«ã€ããŠèª¬æããŸãã FPSïŒãã¡ãŒã¹ãããŒãœã³ã·ã¥ãŒã¿ãŒïŒã®ãããªã«ã¡ã©ã«ã€ããŠèª¬æããŸããFPSã䜿çšãããšã3次å
ã®ã·ãŒã³ãèªç±ã«ç§»åã§ããŸãã ããã«ãããŒããŒããšããŠã¹ã®å
¥åã«ã€ããŠèª¬æããæçµçã«ç¬èªã®C ++ã«ã¡ã©ã¯ã©ã¹ãäœæããŸãã
ã«ã¡ã©/ãã¥ãŒã¹ããŒã¹
ã«ã¡ã©/ãã¥ãŒã¹ããŒã¹ã«ã€ããŠè©±ããšããã«ã¡ã©ã®èŠç¹ããã®ãã¹ãŠã®é ç¹ã®ãã¥ãŒãæå³ããŸãããã®ã¹ããŒã¹å
ã®äœçœ®ã¯åç¹ã®åºç¹ã§ãããã¥ãŒãããªãã¯ã¹ã¯ãã«ã¡ã©ã®äœçœ®ãšæ¹åã«å¯ŸããŠæž¬å®ãããã¯ãŒã«ã座æšããã¥ãŒåº§æšã«å€æããŸãã ã«ã¡ã©ã®æç¢ºãªæ°åŠçèšè¿°ã«ã¯ãã¯ãŒã«ã空éã§ã®äœçœ®ãã«ã¡ã©ãèŠãŠããæ¹åãæ£ããæ¹åã瀺ããã¯ãã«ãããã³äžæ¹åã瀺ããã¯ãã«ãå¿
èŠã§ãã æ³šææ·±ãèªè
ã§ããã°ãå®éã«ã¯ã3ã€ã®åçŽè»žãšã«ã¡ã©ã®äœçœ®ãåºæºç¹ãšãã座æšç³»ãäœæããããšããŠããããšã«æ°ä»ããããããŸããã
1.ã«ã¡ã©ã®äœçœ®
ã«ã¡ã©ã®äœçœ®ãååŸããã®ã¯ç°¡åã§ãã ã«ã¡ã©ã®äœçœ®ã¯ãã¯ãŒã«ã空éã§ã®ã«ã¡ã©ã®åº§æšãå«ããã¯ãã«ã§ãã åã®ã¬ãã¹ã³ã§èšçœ®ããã®ãšåãå Žæã«ã«ã¡ã©ãé
眮ããŸãã
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
Zè»žã®æ£ã®æ¹åãç»é¢ã®é¢ãããªãã®æ¹ãžééããããšãå¿ããªãã§ãã ããããããã£ãŠãã«ã¡ã©ãåŸæ¹ã«ç§»åããããå Žåã¯ãæ£ã®Zè»žã«æ²¿ã£ãŠç§»åããŸãã
2.ã«ã¡ã©ã®æ¹å
次ã«å¿
èŠãªãã¯ãã«ã¯ã«ã¡ã©ã®æ¹åãã¯ãã«ã§ãã ãããŸã§ã®ãšãããã«ã¡ã©ã¯ã·ãŒã³ã®åºç¹ïŒ0,0,0ïŒã«åããããŠããŸãã 2ã€ã®ãã¯ãã«ãäºãã«æžç®ãããšãå
ã®ãã¯ãã«ã®å·®ã§ãããã¯ãã«ãåŸãããããšãå¿ããŠããŸãããïŒ åç¹ããã«ã¡ã©äœçœ®ãã¯ãã«ãåŒããšãã«ã¡ã©æ¹åãã¯ãã«ãåŸãããŸãã ã«ã¡ã©ã¯Z軞ã®è² ã®æ¹åã«åãã£ãŠããããšãç¥ã£ãŠãããã«ã¡ã©èªäœã®æ£ã®Zè»žã«æ²¿ã£ããã¯ãã«ãå¿
èŠã§ãã æžç®ãããšãã«åŒæ°ã®é åºã倿Žãããšãã«ã¡ã©ã®Zè»žã®æ£ã®æ¹åãæããã¯ãã«ãåŸãããŸãã
glm::vec3 cameraTarget = glm::vec3(0.0f, 0.0f, 0.0f); glm::vec3 cameraDirection = glm::normalize(cameraPos - cameraTarget);
ã æ¹åãã¯ãã«ããšããååã¯ããã®ãã¯ãã«ãå®éã«ã«ã¡ã©ã®æ¹åãšåå¯Ÿã®æ¹åãæããŠãããããå®å
šã«é©åã§ã¯ãããŸããã
3.å³è»ž
ãããªãã§ã¯ã§ããªããã1ã€ã®ãã¯ãã«ã¯ã å³ãæããã«ã¡ã©ã®Xè»žã®æ£ã®æ¹åã衚ããã¯ãã«ã§ãã ãã®ãã¯ãã«ãèšç®ããã«ã¯ãã¡ãã£ãšããããªãã¯ãè¡ããŸãããã®ããã«ããŸãäžæ¹åïŒã¯ãŒã«ã空éå
ïŒã瀺ããã¯ãã«ãèšå®ããŸãã æ¬¡ã«ãã¹ããã2ã§èšç®ããã«ã¡ã©ã®æ¹åãšäžåãã®ãã¯ãã«ããã¯ãã«ã§ä¹ç®ããŸãã ãã¯ãã«ç©ã®çµæã¯å
ã®ãã¯ãã«ã«åçŽãªãã¯ãã«ã§ãããããXè»žã®æ£ã®æ¹åãæããã¯ãã«ãåŸãããŸãïŒå åã亀æãããšãX軞ã®è² ã®æ¹åãæããã¯ãã«ãåŸãããŸãïŒã
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f); glm::vec3 cameraRight = glm::normalize(glm::cross(up, cameraDirection));
4.軞ãäžã«
2ã€ã®è»žXãšZã®ãã¯ãã«ãã§ããã®ã§ãã«ã¡ã©ã®è»žYã®æ£ã®æ¹åãæããã¯ãã«ãååŸããã®ã¯éåžžã«ç°¡åã§ããå³ã®ãã¯ãã«ãšã«ã¡ã©ã®æ¹åãã¯ãã«ã®ãã¯ãã«ä¹ç®ãè¡ããŸãã
glm::vec3 cameraUp = glm::cross(cameraDirection, cameraRight);
ãã¯ãã«ç©ãšå°ããªããªãã¯ã®å©ããåããŠãã«ã¡ã©/ãã¥ãŒã¹ããŒã¹ãå®çŸ©ãããã¹ãŠã®ãã¯ãã«ãèšç®ããããšãã§ããŸããã æ°åŠã®èªè
ã«ãšã£ãŠããæŽç·Žãããç·åœ¢ä»£æ°ã®ãã®ã¢ã«ãŽãªãºã ã¯ãGram-Schmidtããã»ã¹ãšããŠç¥ãããŠããŸãã ãããã®ãã¯ãã«ã䜿çšããŠã LookAtãããªãã¯ã¹ãäœæã§ããŸããããã¯ãã«ã¡ã©ã®äœæã«éåžžã«åœ¹ç«ã¡ãŸãã
Lookat
ãããªãã¯ã¹ã®æ³šç®ãã¹ãç¹æ§ã®1ã€ã¯ã3ã€ã®åçŽïŒãŸãã¯ç·åœ¢ç¬ç«ïŒè»žã䜿çšããŠåº§æšç©ºéãå®çŸ©ããå Žåããããã®è»žã®ãã¯ãã«ãšè¿œå ã®å€äœãã¯ãã«ãããä»»æã®ãã¯ãã«ãããã«å€æãããããªãã¯ã¹ã圢æã§ããããšã§ã座æšç©ºéã ããã¯ãŸãã«LookAtãããªãã¯ã¹ãè¡ãããšã§ãããã«ã¡ã©/ãã¥ãŒã¹ããŒã¹ãã€ãŸã 3ã€ã®åçŽè»žãšã«ã¡ã©äœçœ®ãã¯ãã«ã䜿çšããŠãç¬èªã®LookAtãããªãã¯ã¹ãäœæã§ããŸãã
ããã§ã Rã¯å³ãã¯ãã«ã Uã¯äžåãã®ãã¯ãã«ã Dã¯ã«ã¡ã©ã®æ¹åãã¯ãã«ã Pã¯ã«ã¡ã©ã®äœçœ®ã§ãã æåŸã«ã«ã¡ã©ã®åããšã¯åå¯Ÿã®æ¹åã«ã¯ãŒã«ã座æšãã·ãããããããã«ã¡ã©ã®äœçœ®ãã¯ãã«ãå転ããããšã«æ³šæããŠãã ããã LookAtãããªãã¯ã¹ããã¥ãŒãããªãã¯ã¹ãšããŠäœ¿çšãããšããã¹ãŠã®ã¯ãŒã«ã座æšãæå®ããã¹ããŒã¹ã«å¹ççã«å€æã§ããŸãã LookAtãããªãã¯ã¹ã¯ããã®ååã瀺ããšããã«æ©èœããŸããæå®ãããã¿ãŒã²ãããèŠããã¥ãŒãããªãã¯ã¹ãäœæããŸãã
幞ããªããšã«ãGLMã©ã€ãã©ãªã¯ãã®äœæ¥ããã¹ãŠè¡ããŸãã ã«ã¡ã©ã®äœçœ®ãã¿ãŒã²ããã®åº§æšãäžåãã®ã¯ãŒã«ã空éå
ã®ãã¯ãã«ïŒæ£ãããã¯ãã«ãèšç®ããããã«äœ¿çšããè£å©ãã¯ãã«ïŒãæå®ããã ãã§ãã ãããã®ããŒã¿ã«åºã¥ããŠãGLMã¯ç¬ç«ããŠLookAtãããªãã¯ã¹ãäœæããæ¬¡ã®åœ¢åŒã®ãããªãã¯ã¹ãšããŠäœ¿çšã§ããŸãã
glm::mat4 view; view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glm :: LookAt颿°ã«ã¯ãã«ã¡ã©äœçœ®ãã¿ãŒã²ãã座æšãäžåããã¯ãã«ã®ãã©ã¡ãŒã¿ãŒãå¿
èŠã§ãã ãã®é¢æ°ã¯ãåã®ã¬ãã¹ã³ã§äœ¿çšãããã®ãšåããã¥ãŒè¡åãèšç®ããŸãã
ãŠãŒã¶ãŒå
¥åã®åé¡ãæãäžããåã«ãããã€ãã®æ¥œãã¿ãæã¡ãã«ã¡ã©ãã·ãŒã³ã®åšãã§å転ãããŸãããã ç°¡åã«ããããã«ãã«ã¡ã©ãåžžã«ãã€ã³ãïŒ0,0,0ïŒã«åããŸãã
ã«ã¡ã©ã®äœçœ®ãèšç®ããããã«ãå°ããªäžè§æ³ãé©çšããåãã¬ãŒã ã®X座æšãšZ座æšãèšç®ããŸããX座æšãšZ座æšã¯ãå圢ãã¹äžã«ãããã€ã³ãã«ãªããŸãã åãã¬ãŒã ã®X座æšãšZ座æšãåèšç®ããŠãåã®ãã¹ãŠã®ãã€ã³ãã調ã¹ãŸãããããã£ãŠãã«ã¡ã©ã¯ã·ãŒã³ã®åšããå転ããŸãã ãã®åã®ãµã€ãºãååŸã®äžå®å€ãšããŠèšå®ããGLFWã©ã€ãã©ãªã®glfwGetTime颿°ã䜿çšããŠãã²ãŒã ã«ãŒãã®åå埩ã«å¯ŸããŠæ¬¡ã®åœ¢åŒã®æ°ããè¡åãèšç®ããŸãã
GLfloat radius = 10.0f; GLfloat camX = sin(glfwGetTime()) * radius; GLfloat camZ = cos(glfwGetTime()) * radius; glm::mat4 view; view = glm::lookAt(glm::vec3(camX, 0.0, camZ), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0));
ãã®ã³ãŒããå®è¡ãããšã次ã®ãããªãã®ã衚瀺ãããŸãã
ããŠããã®å°ããªã³ãŒãã§ãã«ã¡ã©ã¯ã·ãŒã³ãäžå¿ã«å転ããŸãã LookAtã®ä»çµã¿ãçè§£ããããã«ãååŸãšäœçœ®/æ¹åã®ãã©ã¡ãŒã¿ãŒãèªç±ã«è©ŠããŠãã ããã ããŸããããªãå Žåã¯ãã³ãŒãããœãŒã¹ã³ãŒããšæ¯èŒããã·ã§ãŒããŒãé ç¹ã·ã§ãŒããŒãšãã©ã°ã¡ã³ãã·ã§ãŒããŒã®ããã¹ããšæ¯èŒããŸãã
æ£æ©ãã
ã·ãŒã³ã®åšãã§ã«ã¡ã©ãå転ãããããšã¯ç¢ºãã«æ¥œããã§ããããã£ãšé¢çœãã®ã¯èªåã§ãããåããããšã§ãïŒ ãŸããã«ã¡ã©ã®ãã€ã³ãã©ã¹ãã©ã¯ãã£ããäœæããå¿
èŠããããŸãããã®ãããããã°ã©ã ã®æåã«ããã€ãã®å€æ°ãå®çŸ©ããŸãããã
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f); glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f); glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
LookAt颿°ã®åŒã³åºãã¯æ¬¡ã®ããã«ãªããŸãã
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
ãŸããã«ã¡ã©ã®äœçœ®ãcameraPos倿°ã«æ ŒçŽãããŠããäœçœ®ã«ã«ã¡ã©ãèšå®ããŸãã ã«ã¡ã©ã®æ¹åã¯ãçŸåšã®äœçœ®+ cameraFrontãã¯ãã«ãšããŠèšç®ãããŸããããã¯ãå
ã»ã©çºè¡šãåæåãããã®ã§ãã ããã«ãããã«ã¡ã©ãåããŠããŠããåžžã«ã¿ãŒã²ããã®æ¹åãèŠãããšãã§ããŸãã ããŒã¹ãããŒã¯ã§cameraPosãã¯ãã«ã倿ŽããŠããããã®å€æ°ãå°ã詊ããŠã¿ãŸãããã
ã¬ãã¹ã³1.3ã§ã¯ã GLFWããããŒããŒãå
¥åãåä¿¡ããããã«å¿
èŠãªkey_callbackã³ãŒã«ããã¯é¢æ°ãäœæããŸããã æ¬¡ã« ãç¹å®ã®ãã¿ã³ãæŒãéã«ããã€ãã®æ°ãããã§ãã¯ã远å ããŸãããã
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) { ... GLfloat cameraSpeed = 0.05f; if(key == GLFW_KEY_W) cameraPos += cameraSpeed * cameraFront; if(key == GLFW_KEY_S) cameraPos -= cameraSpeed * cameraFront; if(key == GLFW_KEY_A) cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed; if(key == GLFW_KEY_D) cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed; }
WASDããŒã®ãããããæŒããã³ã«ãã«ã¡ã©ã®äœçœ®ã¯æ°ãã座æšã«åŸã£ãп޿°ãããŸãã åæ¹ãŸãã¯åŸæ¹ã«ç§»åããå Žåã¯ãã«ã¡ã©äœçœ®ãã¯ãã«ã«æ¹åãã¯ãã«ã远å ãŸãã¯æžç®ããŸãã æšªæ¹åã«ç§»åãããšãããã¯ãã«ç©ã䜿çšããŠãå³ã«åãããããã¯ãã«ãèŠã€ããããã«æ²¿ã£ãŠç§»åããŸãã æšªæ¹åã®ã«ã¡ã©ã·ããã«ãããã²ãŒããŒã«ãªãã¿ã®ããã¹ãã©ãã§å¹æãäœæããŸãã
çµæã®å³ãã¯ãã«ãæ£èŠåããããšã«æ³šæããŠãã ããã ãããè¡ããªãã£ãå Žåã cameraFrontã®å€ã«å¿ããŠããã¯ãã«ç©ã®çµæã¯ç°ãªãé·ãã®ãã¯ãã«ã«ãªãå¯èœæ§ããããŸãã é©åãªãã¯ãã«ãæ£èŠåããªããšãã«ã¡ã©ã®é床ã¯äžå®ã§ã¯ãªããã«ã¡ã©ã®æ¹åãå€ãããšå éãŸãã¯æžéããŸãã
ãã®ã³ãŒãã§key_callback颿°ãè£å®ãããš ãã·ãŒã³ãååŸã«ç§»åããããååŸã«ç§»åãããã§ããŸãã
ãã®ã·ã³ãã«ãªã«ã¡ã©å¶åŸ¡ã·ã¹ãã ãæ¥œããã§ãããšããããã2æ¹åã«åæã«ç§»åããããšã¯ã§ããªãããšã«æ°ã¥ããã§ãããïŒæãã«ç§»åããŸãïŒãããŒã®1ã€ãä¿æãããšãæåã«1ååäœãããã®åŸå°ãé
ããŠéå§ããŸãé£ç¶çãªåãã ããã¯ãã»ãšãã©ã®å
¥åã·ã¹ãã ã«ã察å¿ãããã³ãã©ãŒãåŒã³åºãããŒã¹ãããŒã¯ãäžåºŠã«1ã€ããåŠçã§ããªãã€ãã³ãé§ååã¢ãŒããã¯ãã£ïŒEDAïŒãããããã§ãã ããã¯å€ãã®GUIã·ã¹ãã ã§ããŸãæ©èœããŸãããã¹ã ãŒãºãªã«ã¡ã©ã®åãã«ã¯ããŸãé©ããŠããŸããã ãã®åé¡ã解決ããããã®ã¡ãã£ãšããããªãã¯ã玹ä»ããŸãã
ç§Theã¯ã key_callbackã³ãŒã«ããã¯é¢æ°ã§ã©ã®ããŒãæŒããããã é¢ããããã远跡ããããšã§ãã æ¬¡ã«ãã²ãŒã ã«ãŒãã§ãããã®å€ãèæ
®ããã¢ã¯ãã£ããªããŒã確èªãããã®ç¶æ
ã«åºã¥ããŠã cameraPos倿°ã®å€ãé©å®å€æŽããŸãã ãããã£ãŠããã³ãã©ãŒé¢æ°ã§ã¯ãã©ã®ããŒãæŒããããããŸãã¯é¢ããããã«é¢ããæ
å ±ãä¿åããã ãã§ãã²ãŒã ã«ãŒãã§æ¢ã«ãããã®ç¶æ
ã«å¿çããŸãã ãŸããããŒã®æŒãããç¶æ
ãŸãã¯é¢ãããç¶æ
ã衚ãããŒã«å€æ°ã®é
åãäœæããŸãããã
bool keys[1024];
ãã®åŸã key_callback颿°ã§ãæŒãããããŒãtrueã« ããªãªãŒã¹ãããããŒãfalseã«èšå®ããå¿
èŠããããŸãã
if(action == GLFW_PRESS) keys[key] = true; else if(action == GLFW_RELEASE) keys[key] = false;
ãããŠã do_movementãåŒã³åºãæ°ãã颿°ãäœæããŸãããã®é¢æ°ã§ã¯ãæŒãããããŒã®ç¶æ
ã«å¿ããŠã«ã¡ã©åº§æšãæŽæ°ããŸãã
void do_movement() {
åã®ã»ã¯ã·ã§ã³ã®ã³ãŒããdo_movement颿°ã«ç§»æ€ãããŸããã ããŒèå¥åã®GLFWåæã¯åãªãæŽæ°ã§ããããããããã䜿çšããŠé
åã®ã€ã³ããã¯ã¹ãäœæã§ããŸãã
æåŸã«ãã²ãŒã ã«ãŒãã®æ¬äœã«æ°ãã颿°åŒã³åºãã远å ããå¿
èŠããããŸãã
while(!glfwWindowShouldClose(window)) {
ããã§ã2ã€ã®æ¹åã«åæã«ç§»åã§ããããã«ãªããããŒãæŒããçŽåŸã«é£ç¶çãªç§»åãéå§ãããŸãã äœãã«ãã ãã£ãŠããå Žåã¯ãã³ãŒãããœãŒã¹ã³ãŒããšèªç±ã«æ¯èŒããŠãã ããã
ç§»åé床
çŸåšãã«ã¡ã©ãç§»åãããšãã®ç§»åé床ã®å®æ°å€ã䜿çšããŸãã çè«çã«ã¯ããã¯æ®éã®ããã«èŠããŸãããå®éã«ã¯ãŠãŒã¶ãŒã«ãã£ãŠèšç®èœåã倧ããç°ãªãããã®çµæãäžéšã®ã³ã³ãã¥ãŒã¿ãŒã§ã¯åæã«ä»ã®ã³ã³ãã¥ãŒã¿ãŒãããã¯ããã«å€ãã®ãã¬ãŒã ãæç»ãããŸãã ãŸãããããŠãŒã¶ãŒãå¥ã®ãŠãŒã¶ãŒãããå€ãã®ãã¬ãŒã ãæç»ãããšã do_movement颿°ãããé »ç¹ã«åŒã³åºãããŸãã
ãã®çµæãã³ã³ãã¥ãŒã¿ãŒã®æ§æã«å¿ããŠãäžéšã®ãŠãŒã¶ãŒã¯ã·ãŒã³å
ãéåžžã«ãã°ããç§»åããä»ã®ãŠãŒã¶ãŒã¯éåžžã«é
ããªããŸãã ããããããã°ã©ã ãé
åžããå Žåã¯ãããããã©ã®ããŒããŠã§ã¢ã§ãåãããã«åäœããããã§ãããã
ã°ã©ãã£ãã¯ã¢ããªã±ãŒã·ã§ã³ãšã²ãŒã ã¯éåžžãç¹å¥ãªå€æ°deltaTimeã䜿çšããŸãã ãã®å€æ°ã«ã¯ã衚瀺ãããæåŸã®ãã¬ãŒã ãã¬ã³ããªã³ã°ããã®ã«ããã£ãæéãæ ŒçŽãããŸãã ãããŠãã²ãŒã ã§æå®ããããã¹ãŠã®é床ã«ãã®deltaTimeå€ãä¹ç®ãããŸãã ãã®çµæããã¬ãŒã åºåã«å€ãã®æéããããã deltaTimeå€ã倧ããå Žåããã®å€æ°ãæããé床ã倧ãããªããå
šäœçãªããã©ãŒãã³ã¹ã®ãã©ã³ã¹ãåããŸãã ãã®ã¢ãããŒãã䜿çšãããšãã³ã³ãã¥ãŒã¿ãŒã®é»åã¯ããã°ã©ã ã®åäœã«åœ±é¿ãäžããªããªããŸããã³ã³ãã¥ãŒã¿ãŒãé
ããéåžžã«éããã¯é¢ä¿ãããŸãããã«ã¡ã©ã®é床ã¯ãããã«ããŠã調æŽããããã¹ãŠã®ãŠãŒã¶ãŒãåãçµæã«ãªããŸãã
deltaTimeå€ãèšç®ããã«ã¯ã2ã€ã®ã°ããŒãã«å€æ°ãå¿
èŠã§ãã
GLfloat deltaTime = 0.0f;
次ã«ãåãã¬ãŒã ã§ãåŸã§äœ¿çšããããã«æ°ããdeltaTimeå€ãèšç®ããŸãã
GLfloat currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame;
deltaTimeãã§ããã®ã§ãé床ãèšç®ãããšãã«ãã®å€ãèæ
®ããããšãã§ããŸãã
void do_movement() { GLfloat cameraSpeed = 5.0f * deltaTime; ... }
åã®ã»ã¯ã·ã§ã³ã®ã³ãŒããšäžç·ã«ãã·ãŒã³å
ã§ã«ã¡ã©ãç§»åããããã®ããã¹ã ãŒãºã§äžè²«ããã·ã¹ãã ãååŸããå¿
èŠããããŸãã
ãããŠä»ãã©ã®ã·ã¹ãã ã§ãåãé床ã§åãã«ã¡ã©ããããŸãã äœãã倱æããå Žåã¯ã ãœãŒã¹ã³ãŒããå床確èªããŠãã ããã åŸã§ã deltaTimeå€ããé床ãšåãã«é¢é£ããã³ãŒãã§é »ç¹ã«è¡šç€ºãããããšã確èªããŸãã
ã芧ãã ãã
ããŒããŒãã ãã䜿çšããŠç§»åããããšã¯ãããŸãé¢çœããªãã§ãã ããã«ãæ¹å転æããèœåã®æ¬ åŠã«ãããç§ãã¡ã®åãã¯ããªãå¶çŽãããŸãã ããã¯ããŠã¹ã䟿å©ã«ãªããšããã§ãïŒ
ã·ãŒã³ãèªç±ã«æ€æ»ããã«ã¯ãããŠã¹å
¥åã«ãã£ãŠã¬ã€ããããã«ã¡ã©cameraFrontã®æ¹åãã¯ãã«ã倿Žããå¿
èŠããããŸãã ãã ããããŠã¹ã®å転ã«åºã¥ããŠæ¹åãã¯ãã«ã倿Žãããšãç¹å®ã®å°é£ãçããäžè§æ³ã«é¢ããããçšåºŠã®ç¥èãå¿
èŠã«ãªããŸãã äžè§æ³ãããããªããŠãå¿é
ããå¿
èŠã¯ãããŸããã ãœãŒã¹ã³ãŒããããã»ã¯ã·ã§ã³ã«ç§»åããŠããã°ã©ã ã«è²Œãä»ããã ãã§ã詳现ãç¥ãããå Žåã¯ãã€ã§ãæ»ãããšãã§ããŸãã
ãªã€ã©ãŒè§
ãªã€ã©ãŒè§ã¯ã1700幎代é ã«ã¬ããŒããªã€ã©ãŒã«ãã£ãŠèšè¿°ããã3ã€ã®éã§ããã3次å
空éã§ã®ä»»æã®å転ã衚ãããšãã§ããŸãã ãªã€ã©ãŒè§ã«ã¯ã ããã ã ãšãŒ ã ããŒã«ã® 3ã€ããããŸãã æ¬¡ã®å³ã«æç¢ºã«ç€ºãããŠããŸãã
æåã®ç»åã§ãããããã«ã ãããã¯ãã«ãã®äžäžã®éãç¹åŸŽä»ããè§åºŠã§ãã 2çªç®ã®ç»åã¯ãå·Šå³ã®å転éã§ãããšãŒã瀺ããŠããŸãã ããŒã«ã¯ãçžŠè»žã«æ²¿ã£ãŠå転ãèšå®ããéåžžãããŸããŸãªãã©ã€ãã·ãã¥ã¬ãŒã¿ã§ãã䜿çšãããŸãã åãªã€ã©ãŒè§ã¯1ã€ã®ã¹ã«ã©ãŒéã§å®çŸ©ããã3ã€ãã¹ãŠã®è§åºŠã®çµã¿åããã«ããã3次å
空éã§ä»»æã®å転ãã¯ãã«ãèšç®ã§ããŸãã
ã«ã¡ã©å¶åŸ¡ã·ã¹ãã ã§ã¯ããšãŒè§ãšãããè§ã®ã¿ã䜿çšãããããããã§ã¯ããŒã«å€ã«ã€ããŠã¯èª¬æããŸããã ãšãŒãšãããã䜿çšããŠã3Dã«ã¡ã©ã®æ¹åãã¯ãã«ã«å€æã§ããŸãã ãšãŒãšããããæ¹åãã¯ãã«ã«å€æããããã»ã¹ã«ã¯ãå°ãã®äžè§èšç®ãå¿
èŠã§ãã ç°¡åãªäŸããå§ããŸãããïŒ

æèŸºã®é·ãã1ã«èšå®ãããšãäž»ãªäžè§é¢ä¿ããïŒsoh cah toaïŒSine Opposite HypotenuseãCosine Adjacent HypotenuseãTangent Opposite Adjacentãã€ãŸããæ£åŒŠã¯æèŸºã«å¯Ÿããå察åŽã®æ¯ã§ãããäœåŒŠã¯æèŸºã«å¯Ÿãã飿¥åŽã®æ¯ã§ããæ¥ç·ã¯å察åŽãšé£æ¥åŽã®æ¯ã§ãïŒé£æ¥ããåŽã®é·ãã¯cos X / h = cos X / 1 = cos Xã§ãããå察åŽã®é·ãã¯sin Y / h = sin Y / 1 = sin Yã§ããããšãç¥ãããŠããŸã ãããã®åŒã¯ãäžããããè§åºŠã®X軞ãšY軞äžã®æèŸºã®æåœ±ã®é·ããèšç®ããæ©äŒãäžããŠãããŸãã ãããã䜿çšããŠãã«ã¡ã©æ¹åãã¯ãã«ã®ã³ã³ããŒãã³ããèšç®ããŸãã

ãã®äžè§åœ¢ã¯ãåã®å³ã®äžè§åœ¢ã«äŒŒãŠããŸã.XZå¹³é¢äžã«ãããY軞ãèŠããšãæåã®äžè§åœ¢ã«äžããããåŒã«åŸã£ãŠæ¹åãã¯ãã«ã®Yæåã®å€ãèšç®ã§ããŸãïŒæ¹åãäžäžã«èšå®ïŒã ãã®å³ã¯ãäžãããããããè§sinÎã«å¯ŸããYã®å€ã瀺ããŠããŸãã
direction.y = sin(glm::radians(pitch));
ããã§ã¯ãYã®å€ã®ã¿ãèšç®ããŸãããæ¬¡ã«ãã³ã³ããŒãã³ãXãšZãèšç®ããå¿
èŠããããŸããäžè§åœ¢ã®ç»åãèŠããšãå€ãçããããšãããããŸãã
direction.x = cos(glm::radians(pitch)); direction.z = cos(glm::radians(pitch));
ãšãŒè§ã®æ¹åãã¯ãã«ã®å¯Ÿå¿ããã³ã³ããŒãã³ããèŠã€ããæ¹æ³ãèŠãŠã¿ãŸãããã
ãããè§ã«å¯ŸããŠäœæãããäžè§åœ¢ã®å³ã®ããã«ããã®å³ã¯cosïŒãšãŒïŒã®å€ã«å¯ŸããXæåã®äŸåæ§ãšãsinïŒãšãŒïŒã®Zæåã®äŸåæ§ã瀺ããŠããŸãã ãããã®å€ããããè§ã«å¯ŸããŠèšç®ãããçµæãšçµã¿åããããšãããããšãšãŒã®2ã€ã®å転è§ã§æ§ç¯ãããæçµçãªã«ã¡ã©æ¹åãã¯ãã«ãåŸãããŸãã
direction.x = cos(glm::radians(pitch)) * cos(glm::radians(yaw)); direction.y = sin(glm::radians(pitch)); direction.z = cos(glm::radians(pitch)) * sin(glm::radians(yaw));
ããã«ããããããè§ãšãšãŒè§ã3次å
ã®æ¹åãã¯ãã«ã«å€æããããã®åŒãåŸãããŸããããã䜿çšããŠãã«ã¡ã©ã®åããæ±ºããããšãã§ããŸãã ãããããã§ã«è³ªåããããŠããã§ãããïŒãšãŒè§ãšãããè§ãã©ã®ããã«ååŸããã®ã§ããïŒ
ããŠã¹å¶åŸ¡
ãããè§ãšãšãŒè§ã¯ãããŠã¹ïŒãŸãã¯ã²ãŒã ã³ã³ãããŒã©/ãžã§ã€ã¹ãã£ãã¯ïŒã®åãã«å¿ããŠå€ãå€åããŸãã ããŠã¹ã®æšªæ¹åã®åãã¯ãšãŒè§ã«åœ±é¿ããååŸã®åãã¯ãããè§ã«åœ±é¿ããŸãã ããã¯ãæåŸã®ãã¬ãŒã ã®ããŠã¹åº§æšãä¿åããçŸåšã®ãã¬ãŒã ã§ããããæ°ãã座æšãšæ¯èŒããŠãããŠã¹ãã€ã³ã¿ãŒãç§»åãããã¯ã»ã«æ°ãèšç®ãããšãããã®ã§ãã ãã®ã·ããã倧ããã»ã©ããããããã³/ãŸãã¯ãšãŒã®å€ã倧ããå€åããããã«å¿ããŠã«ã¡ã©ããã倧ããªè§åºŠã«ãªããŸãã
ãŸããGLFWã©ã€ãã©ãªã«ãã«ãŒãœã«ãã€ããã§ããŠã¹ãã€ã³ã¿ãŒãé衚瀺ã«ããããã«æç€ºããŸãã ã«ãŒãœã«ããã£ããã£ãããšã¯ãã¢ããªã±ãŒã·ã§ã³ãå
¥åãã©ãŒã«ã¹ãåãåã£ãåŸãã«ãŒãœã«ããŠã£ã³ããŠå
ã«æ®ãããšãæå³ããŸãïŒã¢ããªã±ãŒã·ã§ã³ããã©ãŒã«ã¹ã倱ãããäœæ¥ãå®äºãããŸã§ïŒã 1ã€ã®ç°¡åãªèšå®åŒã³åºãã§ãããè¡ãããšãã§ããŸãã
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
ãã®åŒã³åºãã®åŸãããŠã¹ãã©ãã«ç§»åããŠãããã®ãã€ã³ã¿ãŒã¯è¡šç€ºãããããŠã£ã³ããŠã®å¢çãè¶ããããšã¯ã§ããŸããã ããã¯ãFPSãªã©ã®ã²ãŒã ã§ã«ã¡ã©ãå¶åŸ¡ããã®ã«æé©ã§ãã
, , GLFW, . ( ), :
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
xpos ypos . , GLFW mouse_callback , :
glfwSetCursorPosCallback(window, mouse_callback);
FPS, , :
- .
- .
- / /
. - . , ( 800 600):
GLfloat lastX = 400, lastY = 300;
:
GLfloat yaw = -90.0f; GLfloat pitch = 0.0f;
, :
GLfloat xoffset = xpos - lastX; GLfloat yoffset = lastY - ypos;
, sensitivity (). , ; .
pitch yaw :
yaw += xoffset; pitch += yoffset;
, ( ). , 89 ( 90 , 89), -89 . , . :
if(pitch > 89.0f) pitch = 89.0f; if(pitch < -89.0f) pitch = -89.0f;
, , . , , , .
, :
glm::vec3 front; front.x = cos(glm::radians(pitch)) * cos(glm::radians(yaw)); front.y = sin(glm::radians(pitch)); front.z = cos(glm::radians(pitch)) * sin(glm::radians(yaw)); cameraFront = glm::normalize(front);
, . cameraFront glm::lookAt , .
, , , . , mouse_callback xpos ypos . , , , . - bool , , xpos ypos ; , :
if (firstMouse)
:
void mouse_callback(GLFWwindow* window, double xpos, double ypos) { if(firstMouse) { lastX = xpos; lastY = ypos; firstMouse = false; } GLfloat xoffset = xpos - lastX; GLfloat yoffset = lastY - ypos; lastX = xpos; lastY = ypos; GLfloat sensitivity = 0.05; xoffset *= sensitivity; yoffset *= sensitivity; yaw += xoffset; pitch += yoffset; if(pitch > 89.0f) pitch = 89.0f; if(pitch < -89.0f) pitch = -89.0f; glm::vec3 front; front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch)); front.y = sin(glm::radians(pitch)); front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch)); cameraFront = glm::normalize(front); }
! , 3D-! - , .
: , firstMouse , glfwSetCursorPos â lastX lastY glfwGetCursorPos .
. , fov . , , . . , , :
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { if(fov >= 1.0f && fov <= 45.0f) fov -= yoffset; if(fov <= 1.0f) fov = 1.0f; if(fov >= 45.0f) fov = 45.0f; }
yoffset , . scroll_callback , fov . fov 45.0f, 1.0f 45.0f.
, - fov , , :
projection = glm::perspective(fov, (GLfloat)WIDTH/(GLfloat)HEIGHT, 0.1f, 100.0f);
, , :
glfwSetScrollCallback(window, scroll_callback);
, , . , .
, - , .
: , , . . , .
Camera
. , , , , . , , ( ) , , .
, Shader, Camera . Camera . . , .
FPS- , , . , . , FPS- 90 , (0,1,0) , .
Camera .
æŒç¿
- , , FPS-, c , , XZ: .
- LookAt , , . glm::LookAt , : .