用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
原创粉丝点击