摄像机

网友投稿 235 2022-09-06

摄像机

// GLEW#define GLEW_STATIC#include // GLFW#include #include #include "Shader.h"#include #include #include #include void key_callback(GLFWwindow* windows, int key, int scancode, int action, int mode);const GLuint WIDTH = 800, HEIGHT = 600;GLfloat yaw = -90.0f; // Yaw is initialized to -90.0 degrees since a yaw of 0.0 results in a direction vector pointing to the right (due to how Eular angles work) so we initially rotate a bit to the left.GLfloat pitch = 0.0f;GLfloat lastX = WIDTH / 2.0;GLfloat lastY = HEIGHT / 2.0;void mouse_callback(GLFWwindow* window, double xpos, double ypos);//顶点着色器源码:float Offset = 0.1;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);bool keys[1024];GLfloat deltaTime = 0.0f;GLfloat lastFrame = 0.0f;void do_movement(){ // 摄像机控制 GLfloat cameraSpeed = 5.0f * deltaTime; if (keys[GLFW_KEY_W]) cameraPos += cameraSpeed * cameraFront; if (keys[GLFW_KEY_S]) cameraPos -= cameraSpeed * cameraFront; if (keys[GLFW_KEY_A]) cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed; if (keys[GLFW_KEY_D]) cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;}GLfloat fov = 45.0f;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;}int main(){ /* //此部分写变换 glm::vec4 vec(1.0f, 0.0f, 0.0f, 1.0f); glm::mat4 trans; trans = glm::translate(trans, glm::vec3(1.0f, 1.0f, 0.0f)); vec = trans * vec; std::cout << vec.x << vec.y << vec.z << std::endl; //然后是旋转和缩放箱子 glm::mat4 trans; trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0)); trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5)); //因为我们把这个矩阵传递给了GLM的每个函数,GLM会自动将矩阵相乘 //返回的结果是一个包括了多个变换的变换矩阵。 //转换弧度glm::radians(90.0f)将角度转换为弧度。 */ std::cout << "Starting GLFW context, OpenGL 3.3" << std::endl; //这都是初始化GLFW,后面的要看文档 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* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); if (window == nullptr) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window);//通知GLFW将我们窗口的上下文设置为当前线程的主上下文 //不知道回调函数为什么要加在这里?? //glfwSetKeyCallback(window, key_callback2);回调函数只有最下面那个有作用 glfwSetKeyCallback(window, key_callback); glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); //初始化GLEW(管理OpenGL的函数指针) glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { std::cout << "Failed to initialize GLEW" << std::endl; return -1; } glViewport(0, 0, WIDTH, HEIGHT);//前两个控制左下角的位置,后面是窗口宽度高度(像素) //开启深度测试 glEnable(GL_DEPTH_TEST); Shader ourShader("shader.vs", "shader.frag"); //这里省略了颜色值,省的就是位置坐标和纹理坐标 GLfloat vertices[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; GLuint indices[] = { // Note that we start from 0! 0, 1, 3, // First Triangle 1, 2, 3 // Second Triangle }; glm::vec3 cubePositions[] = { glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(2.0f, 5.0f, -15.0f), glm::vec3(-1.5f, -2.2f, -2.5f), glm::vec3(-3.8f, -2.0f, -12.3f), glm::vec3(2.4f, -0.4f, -3.5f), glm::vec3(-1.7f, 3.0f, -7.5f), glm::vec3(1.3f, -2.0f, -2.5f), glm::vec3(1.5f, 2.0f, -2.5f), glm::vec3(1.5f, 0.2f, -1.5f), glm::vec3(-1.3f, 1.0f, -1.5f) }; GLuint VBO, VAO,EBO; //使用glGenBuffers函数和一个缓冲ID生成一个VBO对象?? glGenBuffers(1, &VBO); glGenVertexArrays(1, &VAO); glGenBuffers(1, &EBO); //绑定VAO glBindVertexArray(VAO); //复制顶点数组到缓冲中,glBufferData是一个专门用来把用户定义的数据复制到当前绑定缓冲的函数 glBindBuffer(GL_ARRAY_BUFFER, VBO);//glBindBuffer函数把新创建的缓冲绑定到GL_ARRAY_BUFFER目标上 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//这局是把定义好的顶点数据复制到缓冲的内存中。 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); //设置顶点属性指针,和颜色属性 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); //因为现在是两个属性,需要向右移动步长,6个 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(2); //由于我们添加了额外的顶点属性,我们要告诉OPenGL新的顶点格式。 //生成纹理 GLuint texture1,texture2; glGenTextures(1, &texture1);//?? //glGenTextures(1, &texture2); //glGenTextures函数首先需要输入生成纹理的数量,然后储存在GLuint数组中,让之前任何纹理指令都可以配置当前绑定的纹理。 //下面这一句是绑定纹理。 //glActiveTexture(GL_TEXTURE0);//多个位置时,使用前需要先激活 glBindTexture(GL_TEXTURE_2D, texture1); //glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture1"), 0); //同理设置第二个纹理位置 //glActiveTexture(GL_TEXTURE1);//多个位置时,使用前需要先激活 //glBindTexture(GL_TEXTURE_2D, texture2); //glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture2"), 1); //设置到两个轴上 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); // Set texture wrapping to GL_REPEAT (usually basic wrapping method) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); //上面两句是对S和T轴设置环绕方式,环绕方式为重复纹理图像。 float borderColor[] = { 1.0f, 1.0f, 0.0f, 1.0f }; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); //下面生成纹理。2D纹理,因此纹理目标是GL_TEXTURE_2D //下面两句设置方法和缩小的纹理过滤方式 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //使用SOIL加载图片,自此到循环前都是加载并生成纹理。 int width, height; std::cout << SOIL_last_result() << std::endl; unsigned char* image = SOIL_load_image("container.jpg", &width, &height, 0, SOIL_LOAD_RGB); std::cout << SOIL_last_result() << std::endl; if (image) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); //第一个参数纹理目标Target,会生成与当前绑定纹理对象同样纹理 //设置纹理指定多级渐远纹理级别,0,基本级别 //第三个参数,纹理储存为何种格式,RGB //四五是设置最终的纹理的宽度和高度,就用之前的变量。 //0 //七八位源图的格式和数据类型,使用RGB加载并储存为char(byte)数组 //最后参数为图像的数据 } else { std::cout << "Failed to load texture." << std::endl; } //当前绑定的纹理对象会被附加上纹理图像,然而只有0级别的纹理图像被加载 了,多级的话需要手动设置 //或者可以,在生成纹理之后调用glGenerateMipmap,这会为当前绑定的纹理自动生成所有需要的多级渐远纹理。 glGenerateMipmap(GL_TEXTURE_2D); SOIL_free_image_data(image); glBindTexture(GL_TEXTURE_2D, 0); glGenTextures(1, &texture2); glBindTexture(GL_TEXTURE_2D, texture2); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); // Set texture filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); image = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glGenerateMipmap(GL_TEXTURE_2D); SOIL_free_image_data(image); glBindTexture(GL_TEXTURE_2D, 0); /* //摄像机 glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);//x摄像机位置 //摄像机方向 glm::vec3 cameraTarget = glm::vec3(0.0f, 0.0f, 0.0f); glm::vec3 cameraDirection = glm::normalize(cameraPos - cameraTarget); glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f); glm::vec3 cameraRight = glm::normalize(glm::cross(up, cameraDirection)); //上轴 glm::vec3 cameraUp = glm::cross(cameraDirection, cameraRight); */ /* //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)); */ //防止退出的循环 while (!glfwWindowShouldClose(window)) { glfwPollEvents(); do_movement(); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glClearColor是一个状态设置函数,glClear是一个状态应用函数 //绘图 ourShader.Use(); glUniform1f(glGetUniformLocation(ourShader.Program, "para"), Offset); //坐标系统 //我们将矩阵向我们要进行移动场景的反向移动。,可以把矩阵看摄像机 glActiveTexture(GL_TEXTURE0);//这句是激活。 glBindTexture(GL_TEXTURE_2D, texture1); glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture1"), 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture2); glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture2"), 1); //这里因为要使用第二个纹理,改变一点渲染流程,先绑定两个纹理到对应的纹理单元,然后定义哪个uniform采样器应对哪个纹理单元。 /* 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)); //然后是透视投影矩阵。*/ glm::mat4 view; view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp); glm::mat4 projection; projection = glm::perspective(glm::radians(fov), (GLfloat)WIDTH/ (GLfloat)HEIGHT, 0.1f, 100.f); GLint modelLoc = glGetUniformLocation(ourShader.Program, "model"); GLint viewLoc = glGetUniformLocation(ourShader.Program, "view"); GLint projLoc = glGetUniformLocation(ourShader.Program, "projection"); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); glBindVertexArray(VAO); for (GLuint i = 0; i < 10; i++) { // Calculate the model matrix for each object and pass it to shader before drawing glm::mat4 model; model = glm::translate(model, cubePositions[i]); float angle = 20.0f * i; if (i % 3 == 0) // every 3rd iteration (including the first) we set the angle using GLFW's time function. angle = glfwGetTime() * 25.0f; model = glm::rotate(model, angle, glm::vec3(1.0f, 0.3f, 0.5f)); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glDrawArrays(GL_TRIANGLES, 0, 36); } glBindVertexArray(0); GLfloat currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; glfwSwapBuffers(window); } //回调函数 //释放: glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); glfwTerminate(); //释放/删除之前的分配的所有资源 return 0;}void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode){ std::cout << key << std::endl; //用户按下ESC键,我们设置window窗口WindowShouldClose属性为true //关闭应用程序 if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE); if (key == GLFW_KEY_UP&&action == GLFW_PRESS) { Offset += 0.1; if (Offset >= 1.0f) Offset = 1.0f; } if (key == GLFW_KEY_DOWN&&action == GLFW_PRESS) { Offset -= 0.1; if (Offset <= 0.0f) Offset = 0.0f; } if (action == GLFW_PRESS) keys[key] = true; else if (action == GLFW_RELEASE) keys[key] = false; }bool firstMouse = true;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; // Reversed since y-coordinates go from bottom to left lastX = xpos; lastY = ypos; GLfloat sensitivity = 0.05; // Change this value to your liking xoffset *= sensitivity; yoffset *= sensitivity; yaw += xoffset; pitch += yoffset; // Make sure that when pitch is out of bounds, screen doesn't get flipped 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);}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:全媒派:被C罗挪走的可口可乐,意外成为了反向营销的大赢家!
下一篇:第11章 图论模型与算法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~