用glew,glfw,FreeImag实现opengl画图->第五课 摄像机
来源:互联网 发布:深圳软件行业协会电话 编辑:程序博客网 时间:2024/06/05 13:25
这篇文章是参考教程点击打开链接 摄像机一节 我觉得这个教程非常好所以把上面的例程都在本地实现
下面是教程的第一部分,箱子旋转,摄像机不动。具体原理教程里很清楚。这里是我实现的代码 着色器程序代码 在源码链接点击打开链接 里面的文件夹shader6中
头文件shader.h camera.h下面是shader.h的内容 前面的 文章相同
#ifndef SHADER_H#define SHADER_H#include<string>#include<fstream>#include<sstream>#include<iostream>#include<GL/glew.h>using namespace std;class Shader{public://程序的IDGLuint Program;//读取渲染程序并创建ShaderShader(const GLchar * vertexSourcePath,const GLchar *fragmentSource);{//1.从文件路径获得vertex/fragment源码string vertexCode;string fragmentCode;try{//打开文件Open filesifstream vShaderFile(vertexPath);ifstream fShaderFile(fragmentPath);stringstream vShaderStream,fShaderStream;//读取文件缓冲到流、vShaderStream<<vShaderFile.rdbuf();fShaderStream<<fShaderFile.rdbuf();//关闭文件句柄vShaderFile.close();fShaderFile.close();//将流转为GLchar数组 vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); }catch(std::exception e) { std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl; }const GLchar* vShaderCode = vertexCode.c_str(); const GLchar * fShaderCode = fragmentCode.c_str(); // 2.编译着色器 GLuint vertex, fragment; GLint success; GLchar infoLog[512]; // 顶点着色器 vertex = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex, 1, &vShaderCode, NULL); glCompileShader(vertex); // 打印着色器是否错误 glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertex, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } // 片段着色器 fragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment, 1, &fShaderCode, NULL); glCompileShader(fragment); // 打印是否有任何错误 glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragment, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } // 着色器程序 this->Program = glCreateProgram(); glAttachShader(this->Program, vertex); glAttachShader(this->Program, fragment); glLinkProgram(this->Program); // 打印是否有错误 glGetProgramiv(this->Program, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(this->Program, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } // 删除着色器程序 glDeleteShader(vertex); glDeleteShader(fragment);}//使用Programvoid Use();{glUseProgram(this->Program);}}#endif
下面是camera.h的代码
#pragma once#include<vector>//GL 包含#include <GL/glew.h>#include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>//定义几个可能关于摄像机移动的操作,利用这个抽象的去保存window系统的几种输入enum Camera_Movement{ FORWARD, BACKWARD, LEFT, RIGHT};//默认的摄像机的数值onst GLfloat YAW = -90.0f;//左右移动的角度const GLfloat PITCH = 0.0f;//上下移动的角度const GLfloat SPEED = 3.0f;//速度const GLfloat SENSITIVTY = 0.25f;const GLfloat ZOOM = 45.0f;//放大//一个抽象的摄像机的类,这个处理输入和计算欧文角度,opengl的向量和矩阵来使用class Camera{public: // Camera Attributes 照相机的属性 glm::vec3 Position;//位置 glm::vec3 Front;//方向 glm::vec3 Up;//上向量 glm::vec3 Right;//右向量 glm::vec3 WorldUp;//世界坐标的上向量 // Eular Angles 欧文角度 GLfloat Yaw;//左右的角度 GLfloat Pitch;//上下的角度 // Camera options 摄像机的操作 GLfloat MovementSpeed; //移动的速度 GLfloat MouseSensitivity;//鼠标的感应位置 GLfloat Zoom;//放大 // Constructor with vectors 构建向量 Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), GLfloat yaw = YAW, GLfloat pitch = PITCH) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVTY), Zoom(ZOOM) { this->Position = position; this->WorldUp = up; this->Yaw = yaw; this->Pitch = pitch; this->updateCameraVectors(); //更新相机的向量 } // Constructor with scalar values 构建标量值 Camera(GLfloat posX, GLfloat posY, GLfloat posZ, GLfloat upX, GLfloat upY, GLfloat upZ, GLfloat yaw, GLfloat pitch) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVTY), Zoom(ZOOM) { this->Position = glm::vec3(posX, posY, posZ); this->WorldUp = glm::vec3(upX, upY, upZ); this->Yaw = yaw; this->Pitch = pitch; this->updateCameraVectors(); } // Returns the view matrix calculated using Eular Angles and the LookAt Matrix//返回通过欧文角度计算的视图矩阵和lookat矩阵 glm::mat4 GetViewMatrix() { return glm::lookAt(this->Position, this->Position + this->Front, this->Up); } // Processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUM (to abstract it from windowingsystems)//处理输入的按键 void ProcessKeyboard(Camera_Movement direction, GLfloat deltaTime) { GLfloat velocity = this->MovementSpeed * deltaTime; //使更新后变化相同 if (direction == FORWARD) this->Position += this->Front * velocity; if (direction == BACKWARD) this->Position -= this->Front * velocity; if (direction == LEFT) this->Position -= this->Right * velocity; if (direction == RIGHT) this->Position += this->Right * velocity; } // Processes input received from a mouse input system. Expects the offset value in both the x and y direction.//把鼠标系统输入处理成标准的输入 ,期望x和y的方向,x和y的值被抵消 鼠标控制物体的旋转 void ProcessMouseMovement(GLfloat xoffset, GLfloat yoffset, constrainPitch = true) { xoffset *= this->MouseSensitivity; yoffset *= this->MouseSensitivity; this->Yaw += xoffset; this->Pitch += yoffset; // Make sure that when pitch is out of bounds, screen doesn't get flipped//确定当pitch(倾斜)超过边界屏幕是不过翻转 if (constrainPitch) { if (this->Pitch > 89.0f) this->Pitch = 89.0f; if (this->Pitch < -89.0f) this->Pitch = -89.0f; } // Update Front, Right and Up Vectors using the updated Eular angles//更新前面,右边和上边的向量 用来更新欧文角度 this->updateCameraVectors(); } // Processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axis//处理输入的放大和缩小,仅要求顶点轴转动 void ProcessMouseScroll(GLfloat yoffset) { if (this->Zoom >= 1.0f && this->Zoom <= 45.0f) this->Zoom -= yoffset; if (this->Zoom <= 1.0f) this->Zoom = 1.0f; if (this->Zoom >= 45.0f) this->Zoom = 45.0f; }private: // Calculates the front vector from the Camera's (updated) Eular Angles//计算方向向量从摄像机更新后的欧文角度 void updateCameraVectors() { // Calculate the new Front vector 计算新的方向向量 glm::vec3 front; front.x = cos(glm::radians(this->Yaw)) * cos(glm::radians(this->Pitch)); front.y = sin(glm::radians(this->Pitch)); front.z = sin(glm::radians(this->Yaw)) * cos(glm::radians(this->Pitch)); this->Front = glm::normalize(front); // Also re-calculate the Right and Up vector 重新计算右向量和上向量 this->Right = glm::normalize(glm::cross(this->Front, this->WorldUp)); // Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement. this->Up = glm::normalize(glm::cross(this->Right, this->Front)); }};
下面是camera..cpp 实现的是物品的旋转,然后摄像机不动
//自动摄像机旋转#include <iostream>#include <cmath>// GLEW#define GLEW_STATIC#include <GL/glew.h>// GLFW#include <GLFW/glfw3.h>// Other Libs#include <FreeImage.h>// GLM Mathematics#include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>#include <glm/gtc/type_ptr.hpp>// Other includes#include <Shader.h>// Function prototypes 函数的原型void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);// Window dimensions windows的尺寸const GLuint WIDTH = 800, HEIGHT = 600;// The MAIN function, from here we start the application and run the game loopint main(){ // Init GLFW 初始化 glfwInit(); // Set all the required options for GLFW 设置GLFW要求设置的选项 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); // Create a GLFWwindow object that we can use for GLFW's functions 创造一个GLFW窗口 对象这样我们利用GLFW的功能 GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); glfwMakeContextCurrent(window); // Set the required callback functions 建立回调函数 glfwSetKeyCallback(window, key_callback); // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions glewExperimental = GL_TRUE; // Initialize GLEW to setup the OpenGL Function pointers 初始化GLEW去设置opengl的指针功能呢 glewInit(); // Define the viewport dimensions 定义视图的尺寸 glViewport(0, 0, WIDTH, HEIGHT); glEnable(GL_DEPTH_TEST); //开启深度测试 // Build and compile our shader program 构建和编译我们的渲染程序 Shader ourShader("D:/C语言/openglflew/shader6/shader.vs", "D:/C语言/openglflew/shader6/shader.frag"); // Set up vertex data (and buffer(s)) and attribute pointers 建立顶点数据和属性指针 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 }; 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) };//创建 VBO,VAO GLuint VBO, VAO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Position attribute 位置属性 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); // TexCoord attribute 纹理属性 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glBindVertexArray(0); // Unbind VAO 解绑VAO// Load, create texture and generate mipmaps 加载,创建纹理并且形成译码 //image format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;FREE_IMAGE_FORMAT fifmt;int width, height;FIBITMAP *dib(0);//1 获取图片格式 fifmt = FreeImage_GetFileType("D:/C语言/openglflew/wall.png", 0);//2 加载图片 if(FreeImage_FIFSupportsReading(fifmt)) dib = FreeImage_Load(fifmt, "D:/C语言/openglflew/wall.png",0); printf("bit: %d\n", FreeImage_GetBPP(dib));//灰度 printf("type: %d\n",FreeImage_GetImageType(dib));//返回类型 printf("bit: %d\n",FreeImage_GetColorsUsed(dib));//调色板的大小 printf("bit: %d\n",FreeImage_GetDIBSize(dib));//大小 //if the image failed to load, return failure if(!dib) cout<<55<<endl;//3 转化为rgb 24色dib = FreeImage_ConvertTo24Bits(dib);//4 获取数据指针BYTE *pixels = (BYTE*)FreeImage_GetBits(dib); width = FreeImage_GetWidth(dib); height = FreeImage_GetHeight(dib); cout<<"width:"<<width<<endl; cout<<"height:"<<height<<endl; ///----------------------------------------加载第二个纹理图片----FREE_IMAGE_FORMAT fif1 = FIF_UNKNOWN;FREE_IMAGE_FORMAT fifmt1;int width1, height1;FIBITMAP *dib1(0); //1 获取图片格式 fifmt1 = FreeImage_GetFileType("D:/C语言/openglflew/face.png", 0);//2 加载图片 if(FreeImage_FIFSupportsReading(fifmt1)) dib1 = FreeImage_Load(fifmt1, "D:/C语言/openglflew/face.png",0); printf("bit: %d\n", FreeImage_GetBPP(dib1));//灰度 printf("type: %d\n",FreeImage_GetImageType(dib1));//返回类型 printf("bit: %d\n",FreeImage_GetColorsUsed(dib1));//调色板的大小 printf("bit: %d\n",FreeImage_GetDIBSize(dib1));//大小 //if the image failed to load, return failure if(!dib1) cout<<55<<endl;//3 转化为rgb 24色dib1= FreeImage_ConvertTo24Bits(dib1);//4 获取数据指针BYTE *pixels1 = (BYTE*)FreeImage_GetBits(dib1); width1 = FreeImage_GetWidth(dib1); height1 = FreeImage_GetHeight(dib1); cout<<"width1:"<<width1<<endl; cout<<"height1:"<<height1<<endl; // Load and create a texture 加载和创建纹理 GLuint texture1; GLuint texture2; // ==================== // Texture 1 纹理1 // ==================== glGenTextures(1, &texture1); glBindTexture(GL_TEXTURE_2D, texture1); // All upcoming GL_TEXTURE_2D operations now have effect on our texture object // Set our texture parameters 设置我们的纹理参数 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);// Set texture wrapping to GL_REPEAT glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering 设置纹理过滤 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Load, create texture and generate mipmaps glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); // Unbind texture when done, so we won't accidentily mess up our texture. // =================== // Texture 2 // =================== glGenTextures(1, &texture2); glBindTexture(GL_TEXTURE_2D, texture2); // Set our texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Load, create texture and generate mipmaps glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width1, height1, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels1); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); // Game loop while (!glfwWindowShouldClose(window)) { // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); // Render 渲染 // Clear the colorbuffer 清楚颜色缓存和深度缓存 glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Bind Textures using texture units 帮点纹理使用的的纹理单元 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); // Activate shader ourShader.Use(); // Camera/View transformation 相机/视图 变换 glm::mat4 view; //设置视图//我们每一帧都创建x轴坐标和z轴坐标,这要使用一个点的三角形的知识,//x和y表示一个在一个圆圈上的一点,我们会使用它作为摄像机机的位置,通过计算x和z的坐标//便利所有圆圈上的点,这样摄像机就会绕场景旋转了。我们预先定义这个圆的半径,使用//glfwGetTime函数不断增加它的值,每次循环创建迭代创建新的视图矩阵 GLfloat radius = 10.0f; GLfloat camX = sin(glfwGetTime()) * radius; GLfloat camZ = cos(glfwGetTime()) * radius;//我们定义一个相机的位置,一个目标位置和一个表示上向量的世界空间中的向量(我们用上向量计算右向量)。接种GLM//就会创建一个LookAt矩阵,我们可以可以把它当作我们的视图矩阵 view = glm::lookAt(glm::vec3(camX, 0.0f, camZ), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f)); // Projection 投影 glm::mat4 projection; projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f); // Get the uniform locations 得到uniform位置 GLint modelLoc = glGetUniformLocation(ourShader.Program, "model"); GLint viewLoc = glGetUniformLocation(ourShader.Program, "view"); GLint projLoc = glGetUniformLocation(ourShader.Program, "projection"); // Pass the matrices to the shader 通过矩阵把数据传给着色器 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]); GLfloat angle = 20.0f * i; 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); // Swap the screen buffers glfwSwapBuffers(window); } // Properly de-allocate all resources once they've outlived their purpose glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); // Terminate GLFW, clearing any resources allocated by GLFW. glfwTerminate();//清除FreeImage_Unload(dib); FreeImage_DeInitialise();FreeImage_Unload(dib1); FreeImage_DeInitialise(); return 0;}// Is called whenever a key is pressed/released via GLFWvoid key_callback(GLFWwindow* window, int key, int scancode, int action, int mode){ if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE);}
可以把camera.cpp更换 头文件不变实现教程其他的内容 我这里是camera1.cpp实现按键控制摄像机移动 按键wasd分别实现前左后右的移动
camera1.cpp代码
//按键移动摄像机#include <iostream>#include <cmath>// GLEW#define GLEW_STATIC#include <GL/glew.h>// GLFW#include <GLFW/glfw3.h>// Other Libs#include <FreeImage.h>// GLM Mathematics#include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>#include <glm/gtc/type_ptr.hpp>// Other includes#include <Shader.h>// Function prototypesvoid key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);void do_movement();// Window dimensionsconst GLuint WIDTH = 800, HEIGHT = 600;// Camera 相机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];// Deltatime 处理时间 因为不同的设备可能处理能力不一样绘制的时间也不一样导致速度不一样,为了解决这个问题//图形和游戏应用通常有回跟踪一个deltaTime变量,它储存渲染上一帧所用的时间。//我们把所有速度都去乘以deltaTime值。当我们的deltaTime变大时意味着上一帧渲染花了更多时间,所以这一帧使用这个更大的deltaTime的值乘以速度,会获得更高的速度,这样就与上一帧平衡了。使用这种方法时,//无论你的机器快还是慢,摄像机的速度都会保持一致,这样每个用户的体验就都一样了。GLfloat deltaTime = 0.0f;// Time between current frame and last frame 当前帧和上一个帧的时间差GLfloat lastFrame = 0.0f; // Time of last frame 上次帧的时间// The MAIN function, from here we start the application and run the game loopint main(){ // Init GLFW glfwInit(); // Set all the required options for GLFW 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); // Create a GLFWwindow object that we can use for GLFW's functions GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); glfwMakeContextCurrent(window); // Set the required callback functions glfwSetKeyCallback(window, key_callback); // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions glewExperimental = GL_TRUE; // Initialize GLEW to setup the OpenGL Function pointers glewInit(); // Define the viewport dimensions glViewport(0, 0, WIDTH, HEIGHT); glEnable(GL_DEPTH_TEST); // Build and compile our shader program Shader ourShader("D:/C语言/openglflew/shader6/shader.vs", "D:/C语言/openglflew/shader6/shader.frag"); // Set up vertex data (and buffer(s)) and attribute pointers 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 }; 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; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); // TexCoord attribute glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glBindVertexArray(0); // Unbind VAO// Load, create texture and generate mipmaps 加载,创建纹理并且形成译码 //image format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;FREE_IMAGE_FORMAT fifmt;int width, height;FIBITMAP *dib(0);//1 获取图片格式 fifmt = FreeImage_GetFileType("D:/C语言/openglflew/wall.png", 0);//2 加载图片 if(FreeImage_FIFSupportsReading(fifmt)) dib = FreeImage_Load(fifmt, "D:/C语言/openglflew/wall.png",0); printf("bit: %d\n", FreeImage_GetBPP(dib));//灰度 printf("type: %d\n",FreeImage_GetImageType(dib));//返回类型 printf("bit: %d\n",FreeImage_GetColorsUsed(dib));//调色板的大小 printf("bit: %d\n",FreeImage_GetDIBSize(dib));//大小 //if the image failed to load, return failure if(!dib) cout<<55<<endl;//3 转化为rgb 24色dib = FreeImage_ConvertTo24Bits(dib);//4 获取数据指针BYTE *pixels = (BYTE*)FreeImage_GetBits(dib); width = FreeImage_GetWidth(dib); height = FreeImage_GetHeight(dib); cout<<"width:"<<width<<endl; cout<<"height:"<<height<<endl; ///----------------------------------------加载第二个纹理图片----FREE_IMAGE_FORMAT fif1 = FIF_UNKNOWN;FREE_IMAGE_FORMAT fifmt1;int width1, height1;FIBITMAP *dib1(0); //1 获取图片格式 fifmt1 = FreeImage_GetFileType("D:/C语言/openglflew/face.png", 0);//2 加载图片 if(FreeImage_FIFSupportsReading(fifmt1)) dib1 = FreeImage_Load(fifmt1, "D:/C语言/openglflew/face.png",0); printf("bit: %d\n", FreeImage_GetBPP(dib1));//灰度 printf("type: %d\n",FreeImage_GetImageType(dib1));//返回类型 printf("bit: %d\n",FreeImage_GetColorsUsed(dib1));//调色板的大小 printf("bit: %d\n",FreeImage_GetDIBSize(dib1));//大小 //if the image failed to load, return failure if(!dib1) cout<<55<<endl;//3 转化为rgb 24色dib1= FreeImage_ConvertTo24Bits(dib1);//4 获取数据指针BYTE *pixels1 = (BYTE*)FreeImage_GetBits(dib1); width1 = FreeImage_GetWidth(dib1); height1 = FreeImage_GetHeight(dib1); cout<<"width1:"<<width1<<endl; cout<<"height1:"<<height1<<endl; // Load and create a texture GLuint texture1; GLuint texture2; // ==================== // Texture 1 // ==================== glGenTextures(1, &texture1); glBindTexture(GL_TEXTURE_2D, texture1); // All upcoming GL_TEXTURE_2D operations now have effect on our texture object // Set our texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);// Set texture wrapping to GL_REPEAT glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Load, create texture and generate mipmaps glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); // Unbind texture when done, so we won't accidentily mess up our texture. // =================== // Texture 2 // =================== glGenTextures(1, &texture2); glBindTexture(GL_TEXTURE_2D, texture2); // Set our texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Load, create texture and generate mipmaps glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width1, height1, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels1); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); // Game loop while (!glfwWindowShouldClose(window)) {// Calculate deltatime of current frame 计算当前图形处理时间 GLfloat currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); do_movement(); // Render // Clear the colorbuffer glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Bind Textures using texture units 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); // Activate shader ourShader.Use(); // Camera/View transformation glm::mat4 view;//首先我们设置之前定义的的camepos为摄像机的位置,方向(direction)是当前的位置//加上我们刚刚定义的方向向量,这样保证无论我们这么移动,摄像机都都注视着目标我//在按下某个按钮时更新camerapos向量 view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp); // Projection glm::mat4 projection; projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f); // Get the uniform locations GLint modelLoc = glGetUniformLocation(ourShader.Program, "model"); GLint viewLoc = glGetUniformLocation(ourShader.Program, "view"); GLint projLoc = glGetUniformLocation(ourShader.Program, "projection"); // Pass the matrices to the shader 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]); GLfloat angle = 20.0f * i; 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); // Swap the screen buffers glfwSwapBuffers(window); } // Properly de-allocate all resources once they've outlived their purpose glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); // Terminate GLFW, clearing any resources allocated by GLFW. glfwTerminate();//清除FreeImage_Unload(dib); FreeImage_DeInitialise();FreeImage_Unload(dib1); FreeImage_DeInitialise(); return 0;}// Is called whenever a key is pressed/released via GLFWvoid key_callback(GLFWwindow* window, int key, int scancode, int action, int mode){ if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE); if (key >= 0 && key < 1024) { if (action == GLFW_PRESS) keys[key] = true; else if (action == GLFW_RELEASE) keys[key] = false; }}void do_movement(){ // Camera controls GLfloat cameraSpeed = 2.5f*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;}camera2.cpp在camera1的基础上加入了鼠标对摄像机拍摄方向的控制,焦点被锁定在窗口中,可能无法退出,可以按 window+d 直接回到主桌面
//鼠标控制移动物体#include <iostream>#include <cmath>// GLEW#define GLEW_STATIC#include <GL/glew.h>// GLFW#include <GLFW/glfw3.h>// Other Libs#include <FreeImage.h>// GLM Mathematics#include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>#include <glm/gtc/type_ptr.hpp>// Other includes#include <Shader.h>// Function prototypes 函数的原型void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); //键盘void mouse_callback(GLFWwindow* window, double xpos, double ypos);//监听鼠标的移动时间void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);void do_movement();//具体键盘的那个按键// Window dimensions 窗口的尺寸大小const GLuint WIDTH = 800, HEIGHT = 600;// Cameraglm::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);//上向量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.//Yaw 是被初始化为-90.0度因为一个yaw 为0.0会导致一个方向向量指向右边(为了决定于这欧拉角怎么工作) 所以我们初始化向左旋转一点GLfloat pitch = 0.0f;GLfloat lastX = WIDTH / 2.0; //初始的时候鼠标在屏幕的中间GLfloat lastY = HEIGHT / 2.0;GLfloat fov = 45.0f;bool keys[1024];// Deltatime 模型绘制的时间GLfloat deltaTime = 0.0f;// Time between current frame and last frame 当前模型和上次之间的时间GLfloat lastFrame = 0.0f; // Time of last frame 上次时间// The MAIN function, from here we start the application and run the game loopint main(){ // Init GLFW glfwInit(); // Set all the required options for GLFW 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); // Create a GLFWwindow object that we can use for GLFW's functions GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); glfwMakeContextCurrent(window); // Set the required callback functions 注册这些函数 glfwSetKeyCallback(window, key_callback);//调用注册的按键函数 glfwSetCursorPosCallback(window, mouse_callback);//调用鼠标移动的函数 glfwSetScrollCallback(window, scroll_callback);//调用注册的缩放函数 // GLFW Options//首先告诉GLFW,应该隐藏光标,并 glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions glewExperimental = GL_TRUE; // Initialize GLEW to setup the OpenGL Function pointers glewInit(); // Define the viewport dimensions glViewport(0, 0, WIDTH, HEIGHT); glEnable(GL_DEPTH_TEST); // Build and compile our shader program Shader ourShader("D:/C语言/openglflew/shader6/shader.vs", "D:/C语言/openglflew/shader6/shader.frag"); // Set up vertex data (and buffer(s)) and attribute pointers 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 }; 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; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); // TexCoord attribute glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glBindVertexArray(0); // Unbind VAO// Load, create texture and generate mipmaps 加载,创建纹理并且形成译码 //image format FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;FREE_IMAGE_FORMAT fifmt;int width, height;FIBITMAP *dib(0);//1 获取图片格式 fifmt = FreeImage_GetFileType("D:/C语言/openglflew/wall.png", 0);//2 加载图片 if(FreeImage_FIFSupportsReading(fifmt)) dib = FreeImage_Load(fifmt, "D:/C语言/openglflew/wall.png",0); printf("bit: %d\n", FreeImage_GetBPP(dib));//灰度 printf("type: %d\n",FreeImage_GetImageType(dib));//返回类型 printf("bit: %d\n",FreeImage_GetColorsUsed(dib));//调色板的大小 printf("bit: %d\n",FreeImage_GetDIBSize(dib));//大小 //if the image failed to load, return failure if(!dib) cout<<55<<endl;//3 转化为rgb 24色dib = FreeImage_ConvertTo24Bits(dib);//4 获取数据指针BYTE *pixels = (BYTE*)FreeImage_GetBits(dib); width = FreeImage_GetWidth(dib); height = FreeImage_GetHeight(dib); cout<<"width:"<<width<<endl; cout<<"height:"<<height<<endl; ///----------------------------------------加载第二个纹理图片----FREE_IMAGE_FORMAT fif1 = FIF_UNKNOWN;FREE_IMAGE_FORMAT fifmt1;int width1, height1;FIBITMAP *dib1(0); //1 获取图片格式 fifmt1 = FreeImage_GetFileType("D:/C语言/openglflew/face.png", 0);//2 加载图片 if(FreeImage_FIFSupportsReading(fifmt1)) dib1 = FreeImage_Load(fifmt1, "D:/C语言/openglflew/face.png",0); printf("bit: %d\n", FreeImage_GetBPP(dib1));//灰度 printf("type: %d\n",FreeImage_GetImageType(dib1));//返回类型 printf("bit: %d\n",FreeImage_GetColorsUsed(dib1));//调色板的大小 printf("bit: %d\n",FreeImage_GetDIBSize(dib1));//大小 //if the image failed to load, return failure if(!dib1) cout<<55<<endl;//3 转化为rgb 24色dib1= FreeImage_ConvertTo24Bits(dib1);//4 获取数据指针BYTE *pixels1 = (BYTE*)FreeImage_GetBits(dib1); width1 = FreeImage_GetWidth(dib1); height1 = FreeImage_GetHeight(dib1); cout<<"width1:"<<width1<<endl; cout<<"height1:"<<height1<<endl; // Load and create a texture GLuint texture1; GLuint texture2; // ==================== // Texture 1 // ==================== glGenTextures(1, &texture1); glBindTexture(GL_TEXTURE_2D, texture1); // All upcoming GL_TEXTURE_2D operations now have effect on our texture object // Set our texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);// Set texture wrapping to GL_REPEAT glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); // Unbind texture when done, so we won't accidentily mess up our texture. // =================== // Texture 2 // =================== glGenTextures(1, &texture2); glBindTexture(GL_TEXTURE_2D, texture2); // Set our texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width1, height1, 0,GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels1); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); // Game loop while (!glfwWindowShouldClose(window)) { // Calculate deltatime of current frame GLfloat currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; //绘制所用的时间 lastFrame = currentFrame; // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); do_movement(); // Render // Clear the colorbuffer glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Bind Textures using texture units 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); // Activate shader ourShader.Use(); // Camera/View transformation glm::mat4 view; view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp); // Projection glm::mat4 projection; projection = glm::perspective(fov, (GLfloat)WIDTH/(GLfloat)HEIGHT, 0.1f, 100.0f); // Get the uniform locations GLint modelLoc = glGetUniformLocation(ourShader.Program, "model"); GLint viewLoc = glGetUniformLocation(ourShader.Program, "view"); GLint projLoc = glGetUniformLocation(ourShader.Program, "projection"); // Pass the matrices to the shader 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]); GLfloat angle = 20.0f * i; 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); // Swap the screen buffers glfwSwapBuffers(window); } // Properly de-allocate all resources once they've outlived their purpose glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); // Terminate GLFW, clearing any resources allocated by GLFW. glfwTerminate();//清除FreeImage_Unload(dib); FreeImage_DeInitialise();FreeImage_Unload(dib1); FreeImage_DeInitialise(); return 0;}// Is called whenever a key is pressed/released via GLFWvoid key_callback(GLFWwindow* window, int key, int scancode, int action, int mode){ if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE); if (key >= 0 && key < 1024) { if (action == GLFW_PRESS) keys[key] = true; else if (action == GLFW_RELEASE) keys[key] = false; }}void do_movement(){ // Camera controls 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;}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 设置不能超越90度 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);}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;}
0 0
- 用glew,glfw,FreeImag实现opengl画图->第五课 摄像机
- 用glew,glfw实现opengl-学习笔记3着色器
- 用glew,glfw实现opengl学习笔记5课纹理(2)
- 用glew,glfw实现opengl绘制3D学习笔记1-实现一个窗口
- 用glew,glfw实现的opengl 学习笔记2画一个四方形
- 用glew,glfw,FreeImage实现opengl学习笔记6坐标变换
- vs2010 OpenGL+glfw+glew+glm
- VS2015配置OpenGL(glfw,glew)
- VS 2008 OpenGL+glfw+glew+glm 配置
- 使用glew和glfw进行opengl编程
- OpenGL,glut,glew,glfw,mesa等
- OpenGL-vs2012-glfw-glew 测试环境搭建
- 使用glew、glfw配置OpenGL开发环境
- 使用glew、glfw配置OpenGL开发环境
- OpenGL,glut,glew,glfw,mesa等
- VS2013+GLFW+GLEW 配置OpenGL开发环境
- glew,glfw实现最新的opengl-学习笔记4实现纹理
- OpenGL: Configuring GLFW and GLEW in Visual C++ Express
- session高级(session入库)
- 使用Maven构建Web项目
- 第一本十五章买家电
- C#小程序实现闰年判断、月份的天数以及所属季度的判断(完善1)
- 如何从Workflow Monitor中移除废弃的集成服务
- 用glew,glfw,FreeImag实现opengl画图->第五课 摄像机
- js DOM与jQuery对象互相转换
- 大素数统计1e11以内 【数论】
- Array数组对象
- 职场人士如何减压-压力下工作的八个放松法则
- lombok-实现java代码简洁化
- 使用Maven构建Web项目-测试
- TIPS
- 设计模式【1】:简单工厂模式