• -OPENGL6 FrameBuffer & PostProcessing & CubeMap-


    CP21:FRAMEBUFFER pipeline:

    绘制一幅图,便于理解

    这章我又被贴图单元迷惑了,经过理性的测试,发现一个Frag材质里只有一个贴图.那么绘制如下:

    #version 450 core
    // INCOMING DATA
    layout ( location = 0 ) in vec4 v_position; //  pos
    //layout ( location = 1 ) in vec3 v_normal;   //  norm
    layout ( location = 1 ) in vec2 v_texCoord; //  st
    
    // define out data
    out vec2 f_TexCoord;
    // normal at world matrix, we direct from C++ calcalation
    out vec3 f_Normal;  // to world matrix : mat3( transpose(inverse(model)) ) * v_normal;
    out vec3 f_Pos;
    
    
    // INCOMING THE MATRIX FROM CLIENT to transform the gl point position
    uniform mat4 model;
    uniform mat4 view;
    uniform mat4 projection;
    
    
    
    
    
    void main(){
        // Transform the world matrix to view matrix
        gl_Position = projection *   view * model * v_position;
    
        //f_Normal = mat3(transpose(inverse(model))) * v_normal;  // f_Normal at world matrix
        f_TexCoord = v_texCoord;          // out TexCoord
        f_Pos = vec3(model *v_position);  // out fragment position
    }
    SurfaceShader.vert
    #version 450 core
    // Final Color To export
    out vec4 FragColor;
    
    // from vert shader
    in vec3 f_Normal;
    in vec2 f_TexCoord;
    in vec3 f_Pos; // fragment position
    
    
    uniform sampler2D diffuse_map;
    
    
    void main()
    {
        vec4 df = texture(diffuse_map, f_TexCoord);
        FragColor = df;
    }
    SurfaceShader.frag

    教程中用了个Quad 形状覆盖到整个窗口上的材质:

    #version 450 core
    // INCOMING DATA
    layout (location = 0) in vec2 aPos;
    layout (location = 1) in vec2 aTexCoords;
    
    out vec2 TexCoords;
    
    void main()
    {
        TexCoords = aTexCoords;
        gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
    }
    ScreenShader.vert
    #version 450 core
    out vec4 FragColor;
    
    in vec2 TexCoords;
    
    uniform sampler2D screenTexture;
    
    void main()
    {
        vec3 col = texture2D(screenTexture, TexCoords).rgb;
        FragColor = vec4(col, 1.0);
    }
    ScreenShader.frag

    教程中所展示的: 不用贴图单元是完全可以的:

    #define GLEW_STATIC
    // GLEW
    #include <GL/glew.h>
    #include <cstdlib>
    #undef GLFW_DLL
    // GLFW
    #include <GLFW/glfw3.h>
    #include <iostream>
    #include "ALG_LoadShader.h"
    #include "ALG_LoadTexture.h"
    #include "ALG_GLFWCamera.h"
    #include "ALG_FrameWindow.h"
    #include "ALG_ModelDelegate.h"
    #include "ALG_SceneDelegate.h"
    #include "ALG_DrawGrid.h"
    #include <cmath>
    #include "OGLHelper.h"
    
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    #include <map>
    using namespace AlgebraMaster;
    
    
    const unsigned int SRC_WIDTH = 1400;
    const unsigned int SRC_HEIGHT = 720;
    
    
    
    static LoadShader SurfaceShader;
    static LoadShader ScreenShader;
    void init();
    void display();
    
    
    void processInput(GLFWwindow *window);
    void framebuffer_size_callback(GLFWwindow* window, int width, int height); // framezize
    void mouse_callback(GLFWwindow* window, double xpos, double ypos); // Maya Alt+LeftMouse
    void scroll_callback(GLFWwindow *window, double xoffset, double yoffset);
    
    
    // camera
    static GLFWCamera *camera;
    static float lastX =  float(SRC_WIDTH) / 2.0f;
    static float lastY =  float(SRC_HEIGHT) / 2.0f;
    static bool firstMouse = true;
    static bool firstMiddowMouse = true;
    // timing
    static float deltaTime = 0.0f;    // time between current frame and last frame
    static float lastFrame = 0.0f;
    
    // light define
    static glm::vec3 lightPos(0.0f, 4.0f,-2.0f);
    
    
    
    // Geometry
    
    static DrawGrid grid;
    
    static float cubeVertices[] = {
        // positions          // texture Coords
               -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
    };
    
    
    
    static float planeVertices[] = {
            // positions          // texture Coords
            5.0f, -0.5f,  5.0f,  2.0f, 0.0f,
            -5.0f, -0.5f,  5.0f,  0.0f, 0.0f,
            -5.0f, -0.5f, -5.0f,  0.0f, 2.0f,
    
            5.0f, -0.5f,  5.0f,  2.0f, 0.0f,
            -5.0f, -0.5f, -5.0f,  0.0f, 2.0f,
            5.0f, -0.5f, -5.0f,  2.0f, 2.0f
    };
    static float transparentVertices[] = {
            // positions         // texture Coords (swapped y coordinates because texture is flipped upside down)
            0.0f,  0.5f,  0.0f,  0.0f,  0.0f,
            0.0f, -0.5f,  0.0f,  0.0f,  1.0f,
            1.0f, -0.5f,  0.0f,  1.0f,  1.0f,
    
            0.0f,  0.5f,  0.0f,  0.0f,  0.0f,
            1.0f, -0.5f,  0.0f,  1.0f,  1.0f,
            1.0f,  0.5f,  0.0f,  1.0f,  0.0f
    };
    
    float quadVertices[] = {
        // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
           // positions   // texCoords
           -1.0f,  1.0f,  0.0f, 1.0f,
           -1.0f, -1.0f,  0.0f, 0.0f,
            1.0f, -1.0f,  1.0f, 0.0f,
    
           -1.0f,  1.0f,  0.0f, 1.0f,
            1.0f, -1.0f,  1.0f, 0.0f,
            1.0f,  1.0f,  1.0f, 1.0f
    };
    
    
    
    
    // cube vao vbo
    static unsigned int cubeVAO,cubeVBO;
    static unsigned int planeVAO,planeVBO;
    static unsigned int quadVAO,quadVBO;
    static unsigned int FBO; // frame buffer object
    static unsigned int FBOTextureID; // texture attachment to FBO
    static unsigned int RBO; // render buffer object
    
    
    
    static LoadTexture cubeTex;
    static LoadTexture groundTex;
    
    
    void init(){
        camera = new GLFWCamera;
        camera->pos.y = 1.0f;
        camera->pos.z = 4.0f;
        // GL depth zbuffer
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
        SurfaceShader.load("shaders/SurfaceShader.vert","shaders/SurfaceShader.frag");
        ScreenShader.load("shaders/ScreenShader.vert","shaders/ScreenShader.frag");
    
        glGenVertexArrays(1, &cubeVAO);
        glGenBuffers(1, &cubeVBO);
        glBindVertexArray(cubeVAO);
        glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    
    
        CreateGeometryBuffer(planeVAO, planeVBO);
        glBufferData(GL_ARRAY_BUFFER,sizeof(planeVertices),&planeVertices, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    
    
    
        CreateGeometryBuffer(quadVAO, quadVBO);
        glBufferData(GL_ARRAY_BUFFER,sizeof(quadVertices),&quadVertices, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
    
    
    
        glBindVertexArray(0);
    
        cout << "cube VAO:" << cubeVAO <<endl;
        cubeTex.load("texture/marble.jpg");
        groundTex.load("texture/metal.png");
    
    
    
    
    
        // FBO with texture attchment
        glGenFramebuffers(1, &FBO);
        glBindFramebuffer(GL_FRAMEBUFFER, FBO);
        glGenTextures(1, &FBOTextureID);
        glBindTexture(GL_TEXTURE_2D, FBOTextureID);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SRC_WIDTH, SRC_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, FBOTextureID, 0);
        // render buffer object
        glGenRenderbuffers(1, &RBO);
        glBindRenderbuffer(GL_RENDERBUFFER, RBO);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, SRC_WIDTH, SRC_WIDTH); // use a single renderbuffer object for both a depth AND stencil buffer.
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, RBO); // now actually attach it
        // now that we actually created the framebuffer and added all attachments we want to check if it is actually complete now
        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
           cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl;
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    
        grid.initialize();
    
    
    
    }
    
    // ----------- Render Loop ----------
    void display(){
    
    
        // per-frame time logic
                // --------------------
        float currentFrame = glfwGetTime();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;
    
    
        // bind to framebuffer and draw scene as we normally would to color texture
        glBindFramebuffer(GL_FRAMEBUFFER, FBO);
        glEnable(GL_DEPTH_TEST); // enable depth testing (is disabled for rendering screen-space quad)
    
    
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    
    
    
        // object .vert settings
        glm::mat4 projection = glm::perspective(glm::radians(camera->fov),float(SRC_WIDTH) / float(SRC_HEIGHT),0.1f,  1000.0f);
        glm::mat4 view = camera->GetViewMatrix();
        // object world transformation
        glm::mat4 model = glm::mat4(1.0f);
    
        grid.draw(projection,view);
    
    
    
    
    
        // render cube
        glBindTexture(GL_TEXTURE_2D,cubeTex.textureID);
        SurfaceShader.use();
        SurfaceShader.setInt("diffuse_map", 0);
        SurfaceShader.setMat4("projection", projection);
        SurfaceShader.setMat4("view", view);
        model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));
        SurfaceShader.setMat4("model", model);
    
        glBindVertexArray(cubeVAO);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        model = glm::mat4(1.0f);
        model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f));
        SurfaceShader.setMat4("model", model);
        glDrawArrays(GL_TRIANGLES, 0, 36);
    
    
    
        // floor
        
        glBindTexture(GL_TEXTURE_2D, groundTex.getTextureID());
        SurfaceShader.setInt("diffuse_map", 0);
        glBindVertexArray(planeVAO);
        model = glm::mat4(1.0f);
        SurfaceShader.setMat4("model", model);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    
    
    
        // now bind back to default framebuffer and draw a quad plane with the attached framebuffer color texture
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        // disable depth test so screen-space quad isn't discarded due to depth test.
        glDisable(GL_DEPTH_TEST);
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // set clear color to white (not really necessery actually, since we won't be able to see behind the quad anyways)
        glClear(GL_COLOR_BUFFER_BIT);
    
        ScreenShader.use();
        ScreenShader.setInt("screenTexture",0 );
        glBindVertexArray(quadVAO);
        glBindTexture(GL_TEXTURE_2D, FBOTextureID);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    
    }
    
    
    int main()
    {
        glfwInit();
        FrameWindow FrameWindow(SRC_WIDTH,SRC_HEIGHT);
        glfwSetFramebufferSizeCallback(FrameWindow.getWindow(), framebuffer_size_callback);
        glfwSetCursorPosCallback(FrameWindow.getWindow(),mouse_callback);
        glfwSetScrollCallback(FrameWindow.getWindow(), scroll_callback);
        init();
        // RENDER--------------
        //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        while(!glfwWindowShouldClose(FrameWindow.getWindow())){
            processInput(FrameWindow.getWindow());
            display();
            glfwSwapBuffers(FrameWindow.getWindow());
            glfwPollEvents();
        }
        delete camera;
        glDeleteVertexArrays(1, &cubeVAO);
        glDeleteVertexArrays(1, &planeVAO);
        glDeleteVertexArrays(1, &quadVAO);
        glDeleteBuffers(1, &cubeVBO);
        glDeleteBuffers(1, &planeVBO);
        glDeleteBuffers(1, &quadVBO);
        return 0;
    }
    
    void framebuffer_size_callback(GLFWwindow* window, int width, int height)
    {
        // make sure the viewport matches the new window dimensions; note that width and
        // height will be significantly larger than specified on retina displays.
        glViewport(0, 0, width, height);
    }
    
    void processInput(GLFWwindow *window)
    {
        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(window, true);
        if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
            camera->processKeyboardMove(deltaTime,GLFWCamera::FORWARD);
        if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
            camera->processKeyboardMove(deltaTime,GLFWCamera::BACKWARD);
        if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
            camera->processKeyboardMove(deltaTime,GLFWCamera::LEFT);
        if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
            camera->processKeyboardMove(deltaTime,GLFWCamera::RIGHT);
    }
    
    // ROTATE VIEW DIR
    void mouse_callback(GLFWwindow* window, double xpos, double ypos){
    
        int middow_mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_MIDDLE);
        int mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT);
        int key_state = glfwGetKey(window,GLFW_KEY_LEFT_ALT);
        // set up the camera view
        if( mouse_state == GLFW_PRESS && key_state== GLFW_PRESS)
        {
            if (firstMouse){
                lastX = xpos;
                lastY = ypos;
                firstMouse = false;
            }
            float xoffset = xpos - lastX;
            float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
            lastX = xpos;
            lastY = ypos;
            camera->processMouseMove(xoffset,yoffset);
        }
        if (key_state == GLFW_RELEASE || mouse_state == GLFW_RELEASE){
            firstMouse = true;
        }
    
    
        // Move Camera Position
        if( middow_mouse_state == GLFW_PRESS) {
    
            if (firstMiddowMouse){
                lastX = xpos;
                lastY = ypos;
                firstMiddowMouse = false;
            }
            float xoffset = xpos - lastX;
            float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
            lastX = xpos;
            lastY = ypos;
            camera->pos.x += xoffset*0.01f;
            camera->pos.y += yoffset*0.01f;
    
        }
        if ( middow_mouse_state == GLFW_RELEASE){
            firstMiddowMouse = true;
        }
    
    }
    
    void scroll_callback(GLFWwindow *window, double xoffset, double yoffset){
        camera->processFov(yoffset);
    }
    View Code

    观察下面的Render Cube 和 Render Floor 部分,因为材质只有一个diffuse_map, 

    虽然系统加载了2个贴图,但是每个贴图有个ID,所以:

    只要在渲染立方体时候,绑定立方体的贴图ID

    glBindTexture(GL_TEXTURE_2D,cubeTex.textureID);
    SurfaceShader.setInt("diffuse_map", 0);

    只要在渲染地面时候,绑定地面的贴图ID

    glBindTexture(GL_TEXTURE_2D, groundTex.getTextureID());
    SurfaceShader.setInt("diffuse_map", 0);

    所以系统默认的贴图单元是:

    glActiveTexture(GL_TEXTURE0)

    现在我想强制使用贴图单元控制:

    #define GLEW_STATIC
    // GLEW
    #include <GL/glew.h>
    #include <cstdlib>
    #undef GLFW_DLL
    // GLFW
    #include <GLFW/glfw3.h>
    #include <iostream>
    #include "ALG_LoadShader.h"
    #include "ALG_LoadTexture.h"
    #include "ALG_GLFWCamera.h"
    #include "ALG_FrameWindow.h"
    #include "ALG_ModelDelegate.h"
    #include "ALG_SceneDelegate.h"
    #include "ALG_DrawGrid.h"
    #include <cmath>
    #include "OGLHelper.h"
    
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    #include <map>
    using namespace AlgebraMaster;
    
    
    const unsigned int SRC_WIDTH = 1400;
    const unsigned int SRC_HEIGHT = 720;
    
    
    
    static LoadShader SurfaceShader;
    static LoadShader ScreenShader;
    void init();
    void display();
    
    
    void processInput(GLFWwindow *window);
    void framebuffer_size_callback(GLFWwindow* window, int width, int height); // framezize
    void mouse_callback(GLFWwindow* window, double xpos, double ypos); // Maya Alt+LeftMouse
    void scroll_callback(GLFWwindow *window, double xoffset, double yoffset);
    
    
    // camera
    static GLFWCamera *camera;
    static float lastX =  float(SRC_WIDTH) / 2.0f;
    static float lastY =  float(SRC_HEIGHT) / 2.0f;
    static bool firstMouse = true;
    static bool firstMiddowMouse = true;
    // timing
    static float deltaTime = 0.0f;    // time between current frame and last frame
    static float lastFrame = 0.0f;
    
    // light define
    static glm::vec3 lightPos(0.0f, 4.0f,-2.0f);
    
    
    
    // Geometry
    
    static DrawGrid grid;
    
    static float cubeVertices[] = {
        // positions          // texture Coords
               -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
    };
    
    
    
    static float planeVertices[] = {
            // positions          // texture Coords
            5.0f, -0.5f,  5.0f,  2.0f, 0.0f,
            -5.0f, -0.5f,  5.0f,  0.0f, 0.0f,
            -5.0f, -0.5f, -5.0f,  0.0f, 2.0f,
    
            5.0f, -0.5f,  5.0f,  2.0f, 0.0f,
            -5.0f, -0.5f, -5.0f,  0.0f, 2.0f,
            5.0f, -0.5f, -5.0f,  2.0f, 2.0f
    };
    static float transparentVertices[] = {
            // positions         // texture Coords (swapped y coordinates because texture is flipped upside down)
            0.0f,  0.5f,  0.0f,  0.0f,  0.0f,
            0.0f, -0.5f,  0.0f,  0.0f,  1.0f,
            1.0f, -0.5f,  0.0f,  1.0f,  1.0f,
    
            0.0f,  0.5f,  0.0f,  0.0f,  0.0f,
            1.0f, -0.5f,  0.0f,  1.0f,  1.0f,
            1.0f,  0.5f,  0.0f,  1.0f,  0.0f
    };
    
    float quadVertices[] = {
        // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
           // positions   // texCoords
           -1.0f,  1.0f,  0.0f, 1.0f,
           -1.0f, -1.0f,  0.0f, 0.0f,
            1.0f, -1.0f,  1.0f, 0.0f,
    
           -1.0f,  1.0f,  0.0f, 1.0f,
            1.0f, -1.0f,  1.0f, 0.0f,
            1.0f,  1.0f,  1.0f, 1.0f
    };
    
    
    
    
    // cube vao vbo
    static unsigned int cubeVAO,cubeVBO;
    static unsigned int planeVAO,planeVBO;
    static unsigned int quadVAO,quadVBO;
    static unsigned int FBO; // frame buffer object
    static unsigned int FBOTextureID; // texture attachment to FBO
    static unsigned int RBO; // render buffer object
    
    
    
    static LoadTexture cubeTex;
    static LoadTexture groundTex;
    
    
    void init(){
        camera = new GLFWCamera;
        camera->pos.y = 1.0f;
        camera->pos.z = 4.0f;
        // GL depth zbuffer
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
        SurfaceShader.load("shaders/SurfaceShader.vert","shaders/SurfaceShader.frag");
        ScreenShader.load("shaders/ScreenShader.vert","shaders/ScreenShader.frag");
    
        glGenVertexArrays(1, &cubeVAO);
        glGenBuffers(1, &cubeVBO);
        glBindVertexArray(cubeVAO);
        glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    
    
        CreateGeometryBuffer(planeVAO, planeVBO);
        glBufferData(GL_ARRAY_BUFFER,sizeof(planeVertices),&planeVertices, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    
    
    
        CreateGeometryBuffer(quadVAO, quadVBO);
        glBufferData(GL_ARRAY_BUFFER,sizeof(quadVertices),&quadVertices, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
    
    
    
        glBindVertexArray(0);
    
        cout << "cube VAO:" << cubeVAO <<endl;
        cubeTex.load("texture/marble.jpg");
        groundTex.load("texture/metal.png");
    
    
    
    
    
        // FBO with texture attchment
        glGenFramebuffers(1, &FBO);
        glBindFramebuffer(GL_FRAMEBUFFER, FBO);
        glGenTextures(1, &FBOTextureID);
        glBindTexture(GL_TEXTURE_2D, FBOTextureID);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SRC_WIDTH, SRC_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, FBOTextureID, 0);
        // render buffer object
        glGenRenderbuffers(1, &RBO);
        glBindRenderbuffer(GL_RENDERBUFFER, RBO);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, SRC_WIDTH, SRC_WIDTH); // use a single renderbuffer object for both a depth AND stencil buffer.
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, RBO); // now actually attach it
        // now that we actually created the framebuffer and added all attachments we want to check if it is actually complete now
        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
           cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl;
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    
        grid.initialize();
    
    
    
    }
    
    // ----------- Render Loop ----------
    void display(){
    
    
        // per-frame time logic
                // --------------------
        float currentFrame = glfwGetTime();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;
    
    
        // bind to framebuffer and draw scene as we normally would to color texture
        glBindFramebuffer(GL_FRAMEBUFFER, FBO);
        glEnable(GL_DEPTH_TEST); // enable depth testing (is disabled for rendering screen-space quad)
    
    
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    
    
    
        // object .vert settings
        glm::mat4 projection = glm::perspective(glm::radians(camera->fov),float(SRC_WIDTH) / float(SRC_HEIGHT),0.1f,  1000.0f);
        glm::mat4 view = camera->GetViewMatrix();
        // object world transformation
        glm::mat4 model = glm::mat4(1.0f);
    
        grid.draw(projection,view);
    
    
    
    
    
        // render cube
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D,cubeTex.textureID);
        SurfaceShader.use();
        SurfaceShader.setInt("diffuse_map", 0);
        SurfaceShader.setMat4("projection", projection);
        SurfaceShader.setMat4("view", view);
        model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));
        SurfaceShader.setMat4("model", model);
    
        glBindVertexArray(cubeVAO);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        model = glm::mat4(1.0f);
        model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f));
        SurfaceShader.setMat4("model", model);
        glDrawArrays(GL_TRIANGLES, 0, 36);
    
    
    
        // floor
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, groundTex.getTextureID());
        SurfaceShader.setInt("diffuse_map", 1);
        glBindVertexArray(planeVAO);
        model = glm::mat4(1.0f);
        SurfaceShader.setMat4("model", model);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    
    
    
        // now bind back to default framebuffer and draw a quad plane with the attached framebuffer color texture
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        // disable depth test so screen-space quad isn't discarded due to depth test.
        glDisable(GL_DEPTH_TEST);
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // set clear color to white (not really necessery actually, since we won't be able to see behind the quad anyways)
        glClear(GL_COLOR_BUFFER_BIT);
    
        ScreenShader.use();
        glActiveTexture(GL_TEXTURE2);
        glBindTexture(GL_TEXTURE_2D, FBOTextureID);
        ScreenShader.setInt("screenTexture",2 );
        glBindVertexArray(quadVAO);
    
        glDrawArrays(GL_TRIANGLES, 0, 6);
    
    }
    
    
    int main()
    {
        glfwInit();
        FrameWindow FrameWindow(SRC_WIDTH,SRC_HEIGHT);
        glfwSetFramebufferSizeCallback(FrameWindow.getWindow(), framebuffer_size_callback);
        glfwSetCursorPosCallback(FrameWindow.getWindow(),mouse_callback);
        glfwSetScrollCallback(FrameWindow.getWindow(), scroll_callback);
        init();
        // RENDER--------------
        //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        while(!glfwWindowShouldClose(FrameWindow.getWindow())){
            processInput(FrameWindow.getWindow());
            display();
            glfwSwapBuffers(FrameWindow.getWindow());
            glfwPollEvents();
        }
        delete camera;
        glDeleteVertexArrays(1, &cubeVAO);
        glDeleteVertexArrays(1, &planeVAO);
        glDeleteVertexArrays(1, &quadVAO);
        glDeleteBuffers(1, &cubeVBO);
        glDeleteBuffers(1, &planeVBO);
        glDeleteBuffers(1, &quadVBO);
        return 0;
    }
    
    void framebuffer_size_callback(GLFWwindow* window, int width, int height)
    {
        // make sure the viewport matches the new window dimensions; note that width and
        // height will be significantly larger than specified on retina displays.
        glViewport(0, 0, width, height);
    }
    
    void processInput(GLFWwindow *window)
    {
        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(window, true);
        if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
            camera->processKeyboardMove(deltaTime,GLFWCamera::FORWARD);
        if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
            camera->processKeyboardMove(deltaTime,GLFWCamera::BACKWARD);
        if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
            camera->processKeyboardMove(deltaTime,GLFWCamera::LEFT);
        if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
            camera->processKeyboardMove(deltaTime,GLFWCamera::RIGHT);
    }
    
    // ROTATE VIEW DIR
    void mouse_callback(GLFWwindow* window, double xpos, double ypos){
    
        int middow_mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_MIDDLE);
        int mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT);
        int key_state = glfwGetKey(window,GLFW_KEY_LEFT_ALT);
        // set up the camera view
        if( mouse_state == GLFW_PRESS && key_state== GLFW_PRESS)
        {
            if (firstMouse){
                lastX = xpos;
                lastY = ypos;
                firstMouse = false;
            }
            float xoffset = xpos - lastX;
            float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
            lastX = xpos;
            lastY = ypos;
            camera->processMouseMove(xoffset,yoffset);
        }
        if (key_state == GLFW_RELEASE || mouse_state == GLFW_RELEASE){
            firstMouse = true;
        }
    
    
        // Move Camera Position
        if( middow_mouse_state == GLFW_PRESS) {
    
            if (firstMiddowMouse){
                lastX = xpos;
                lastY = ypos;
                firstMiddowMouse = false;
            }
            float xoffset = xpos - lastX;
            float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
            lastX = xpos;
            lastY = ypos;
            camera->pos.x += xoffset*0.01f;
            camera->pos.y += yoffset*0.01f;
    
        }
        if ( middow_mouse_state == GLFW_RELEASE){
            firstMiddowMouse = true;
        }
    
    }
    
    void scroll_callback(GLFWwindow *window, double xoffset, double yoffset){
        camera->processFov(yoffset);
    }
    View Code

    对于立方体绘制:

    // render cube

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D,cubeTex.textureID);
    SurfaceShader.use();
    SurfaceShader.setInt("diffuse_map", 0);
    SurfaceShader.setMat4("projection", projection);
    SurfaceShader.setMat4("view", view);
    model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));
    SurfaceShader.setMat4("model", model);

    // draw geometry

    glBindVertexArray(cubeVAO);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f));
    SurfaceShader.setMat4("model", model);
    glDrawArrays(GL_TRIANGLES, 0, 36);

    对于地面绘制:

    // floor
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, groundTex.getTextureID());
    SurfaceShader.setInt("diffuse_map", 1);
    glBindVertexArray(planeVAO);
    model = glm::mat4(1.0f);
    SurfaceShader.setMat4("model", model);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    对于屏幕那个方形绘制:

    // now bind back to default framebuffer and draw a quad plane with the attached framebuffer color texture
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    // disable depth test so screen-space quad isn't discarded due to depth test. glDisable(GL_DEPTH_TEST); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // set clear color to white (not really necessery actually, since we won't be able to see behind the quad anyways) glClear(GL_COLOR_BUFFER_BIT); ScreenShader.use(); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, FBOTextureID); ScreenShader.setInt("screenTexture",2 ); glBindVertexArray(quadVAO); glDrawArrays(GL_TRIANGLES, 0, 6);

    教程的目的是自己建立的buffer用来绘制场景,包括深度,模板。

    而自己建立的Quad覆盖到窗口上,是只绘制了Quad,加载了个buffer texture

     

    CP22:

    直接修改ScreenShader.frag, Kernel网络教程比较多,把官网的抄袭下没啥意思。wiki有更多的,或者更大的kernel

    #version 450 core
    out vec4 FragColor;
    in vec2 TexCoords;
    uniform sampler2D screenTexture;
    
    
    const float offset = 1.0 / 300.0;
    
    
    
    
    void main()
    {
    
        vec2 offsets[9] = vec2[](
        vec2(-offset,  offset), // 左上
        vec2( 0.0f,    offset), // 正上
        vec2( offset,  offset), // 右上
        vec2(-offset,  0.0f),   //
        vec2( 0.0f,    0.0f),   //
        vec2( offset,  0.0f),   //
        vec2(-offset, -offset), // 左下
        vec2( 0.0f,   -offset), // 正下
        vec2( offset, -offset)  // 右下
        );
    
        float kernel[9] = float[](
        -1, -1, -1,
        -1,  9, -1,
        -1, -1, -1
        );
    
        vec3 sampleTex[9];
        for(int i = 0; i < 9; i++)
        {
            sampleTex[i] = vec3(texture(screenTexture, TexCoords.st + offsets[i]));
        }
        vec3 col = vec3(0.0);
        for(int i = 0; i < 9; i++)
        col += sampleTex[i] * kernel[i];
    
        FragColor = vec4(col, 1.0);
    }

    CP23:

    首先心里一定要知道6个面的顺序,在for循环中++就可以得到每个面的准确位置。第一个是右,自加一此是左边,再加上.......

    关于SKY BOX和 反射的测试

    要想让Sky box绘制少,就把他的默认Z值永远作为最大。因为深度测试是在vert shading之后,所以在vert把他的z值永远设置为w/w = 1.0f

    #version 450 core
    // INCOMING DATA
    layout (location = 0) in vec2 aPos;
    layout (location = 1) in vec2 aTexCoords;
    out vec2 TexCoords;
    void main()
    {
        TexCoords = aTexCoords;
        gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
    }
    SkyBox.vert
    #version 450 core
    layout (location = 0) in vec3 aPos;
    out vec3 TexCoord;
    
    uniform mat4 projection;
    uniform mat4 view;
    
    void main() {
        vec4 pos = projection*view*vec4(aPos, 1.0);
        gl_Position = pos.xyww;
        TexCoord = aPos;
    }
    SkyBox.frag

    把Draw Sky Box 变成一个类,比较简单的绘制天空盒子

    //
    // Created by Admin on 2020/3/1.
    //
    
    #ifndef TRIANGLE_ALG_DRAWENVBOX_H
    #define TRIANGLE_ALG_DRAWENVBOX_H
    
    #include "ALG_OGLHelper.h"
    #include <iostream>
    #include <string>
    #include <vector>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    #include <map>
    #include "ALG_LoadShader.h"
    #include "ALG_OGLHelper.h"
    #include "ALG_LoadTexture.h"
    
    namespace AlgebraMaster
    {
    using namespace std;
    static float skyboxVertices[] = {
                // positions
                -1.0f,  1.0f, -1.0f,
                -1.0f, -1.0f, -1.0f,
                1.0f, -1.0f, -1.0f,
                1.0f, -1.0f, -1.0f,
                1.0f,  1.0f, -1.0f,
                -1.0f,  1.0f, -1.0f,
    
                -1.0f, -1.0f,  1.0f,
                -1.0f, -1.0f, -1.0f,
                -1.0f,  1.0f, -1.0f,
                -1.0f,  1.0f, -1.0f,
                -1.0f,  1.0f,  1.0f,
                -1.0f, -1.0f,  1.0f,
    
                1.0f, -1.0f, -1.0f,
                1.0f, -1.0f,  1.0f,
                1.0f,  1.0f,  1.0f,
                1.0f,  1.0f,  1.0f,
                1.0f,  1.0f, -1.0f,
                1.0f, -1.0f, -1.0f,
    
                -1.0f, -1.0f,  1.0f,
                -1.0f,  1.0f,  1.0f,
                1.0f,  1.0f,  1.0f,
                1.0f,  1.0f,  1.0f,
                1.0f, -1.0f,  1.0f,
                -1.0f, -1.0f,  1.0f,
    
                -1.0f,  1.0f, -1.0f,
                1.0f,  1.0f, -1.0f,
                1.0f,  1.0f,  1.0f,
                1.0f,  1.0f,  1.0f,
                -1.0f,  1.0f,  1.0f,
                -1.0f,  1.0f, -1.0f,
    
                -1.0f, -1.0f, -1.0f,
                -1.0f, -1.0f,  1.0f,
                1.0f, -1.0f, -1.0f,
                1.0f, -1.0f, -1.0f,
                -1.0f, -1.0f,  1.0f,
                1.0f, -1.0f,  1.0f
        };
    
    
        class DrawEnvBox{
        public:
            void initialize(){
                if(maps.empty()) {
                    cout << "Error initialize EnvBox, no maps loaded
    ";
                    return;
                }
                shader.load("shaders/SkyBox.vert","shaders/Skybox.frag");
    
                // create Cube Map VAO VBO
                CreateGeometryBuffer(VAO, VBO);
                glBufferData(GL_ARRAY_BUFFER,sizeof(skyboxVertices),&skyboxVertices, GL_STATIC_DRAW);
                glEnableVertexAttribArray(0);
                glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    
            }
            void setupMaps(const vector<string> &maps){
                texture.loadCubeMap(maps);
                this->maps = maps;
            }
    
            void draw(glm::mat4 &proj, glm::mat4 &view){
                if(maps.empty()) {
                    cout << "Error initialize EnvBox, no maps loaded
    ";
                    return;
                }
                shader.use();
                shader.setMat4("projection",proj);
                shader.setMat4("view",glm::mat4(glm::mat3(view)) ); // we only want get rotation
                glDepthFunc(GL_LEQUAL);
                glBindTexture(GL_TEXTURE_CUBE_MAP,texture.getTextureID());
                glBindVertexArray(VAO);
                glDrawArrays(GL_TRIANGLES, 0 ,36);
                glDepthFunc(GL_LESS); // set depth function back to default
            }
    
            LoadShader shader;
            LoadTexture texture;
            vector<string> maps;
            unsigned int VAO;
            unsigned int VBO;
    
    
    
        };
    
    }
    
    
    
    
    #endif //TRIANGLE_ALG_DRAWENVBOX_H
    ALG_DrawEnvBox.h

    并且修改ALG_LoadTexture.h增加一个读取天空盒子的函数

    #ifndef LOADTEXTURE_H
    #define LOADTEXTURE_H
    #include <GL/glew.h>
    
    // IMP the stb image loader
    #define STB_IMAGE_IMPLEMENTATION
    #include <stb_image.h>
    #include <iostream>
    #include <vector>
    using namespace std;
    
    namespace AlgebraMaster
    {
    
    class LoadTexture
    {
    public:
        LoadTexture();
        LoadTexture(const char *fileName);
        void load(const char *fileName);
        void loadCubeMap(const vector<string> &maps);
        virtual ~LoadTexture();
        inline GLuint getTextureID()const{return textureID;}
        inline GLuint getImageFormat()const{return format;}
        GLuint textureID;
        GLenum format;
        bool loadStatus;
    };
    
    LoadTexture::LoadTexture() {
        loadStatus = false;
    }
    
    
    
    /*
        GL_TEXTURE_CUBE_MAP_POSITIVE_X    RIGTH
        GL_TEXTURE_CUBE_MAP_NEGATIVE_X    LEFT
        GL_TEXTURE_CUBE_MAP_POSITIVE_Y    TOP
        GL_TEXTURE_CUBE_MAP_NEGATIVE_Y    BOTTOM
        GL_TEXTURE_CUBE_MAP_POSITIVE_Z    BACK
        GL_TEXTURE_CUBE_MAP_NEGATIVE_Z    FRONT
    */
    
    void LoadTexture::loadCubeMap(const vector<string> &maps) {
        glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &textureID);
        glBindTexture(GL_TEXTURE_CUBE_MAP,textureID);
        int width, height, nrchans;
        int i=0;
        for(const auto & map : maps){
            unsigned char *data = stbi_load(map.c_str(),&width, &height, &nrchans,0);
            if(data){
                if (nrchans == 1)
                    format = GL_RED;
                else if (nrchans == 3)
                    format = GL_RGB;
                else if (nrchans == 4)
                    format = GL_RGBA;
                // create opengl image
                glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,0, format, width,height,0, format,GL_UNSIGNED_BYTE, data);
                i++ ;
            }
            else{
                std::cout << "Cube map load failed :" << map << endl;
                stbi_image_free(data);
            }
        } // load the cube maps
        glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    
    }
    
    // Load basis map from stbi_load()
    void LoadTexture::load(const char *fileName)
    {
        glGenTextures(1, &textureID);
        int width, height, nrComponents;
        unsigned char *data = stbi_load(fileName, &width, &height, &nrComponents, 0);
        if (data)
        {
            if (nrComponents == 1)
                format = GL_RED;
            else if (nrComponents == 3)
                format = GL_RGB;
            else if (nrComponents == 4)
                format = GL_RGBA;
    
            glBindTexture(GL_TEXTURE_2D, textureID);
            // create opengl image
            glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
            // gen MipMap
            glGenerateMipmap(GL_TEXTURE_2D);
    
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    
            stbi_image_free(data);
            loadStatus = true;
        }
        else
        {
            loadStatus = false;
            std::cout << "Texture failed to load at path: " << fileName << std::endl;
            stbi_image_free(data);
        }
    
    }
    
    LoadTexture::LoadTexture(const char *fileName){
        loadStatus = false;
        load(fileName);
    }
    LoadTexture::~LoadTexture(){}
    
    }
    #endif // LOADTEXTURE_H
    ALG_LoadTexture.h

    主程序:

    #define GLEW_STATIC
    // GLEW
    #include <GL/glew.h>
    #include <cstdlib>
    #undef GLFW_DLL
    // GLFW
    #include <GLFW/glfw3.h>
    #include <iostream>
    #include "ALG_LoadShader.h"
    #include "ALG_LoadTexture.h"
    #include "ALG_GLFWCamera.h"
    #include "ALG_FrameWindow.h"
    #include "ALG_ModelDelegate.h"
    #include "ALG_SceneDelegate.h"
    #include "ALG_DrawGrid.h"
    #include <cmath>
    #include "ALG_OGLHelper.h"
    
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    #include <map>
    #include "ALG_DrawEnvBox.h"
    
    using namespace AlgebraMaster;
    
    
    const unsigned int SRC_WIDTH = 1400;
    const unsigned int SRC_HEIGHT = 720;
    
    
    
    static LoadShader SurfaceShader;
    static LoadShader ScreenShader;
    static LoadShader SkyBoxShader;
    void init();
    void display();
    
    
    void processInput(GLFWwindow *window);
    void framebuffer_size_callback(GLFWwindow* window, int width, int height); // framezize
    void mouse_callback(GLFWwindow* window, double xpos, double ypos); // Maya Alt+LeftMouse
    void scroll_callback(GLFWwindow *window, double xoffset, double yoffset);
    
    
    
    static float lastX =  float(SRC_WIDTH) / 2.0f;
    static float lastY =  float(SRC_HEIGHT) / 2.0f;
    static bool firstMouse = true;
    static bool firstMiddowMouse = true;
    // timing
    static float deltaTime = 0.0f;    // time between current frame and last frame
    static float lastFrame = 0.0f;
    
    
    
    
    static float cubeVertices[] = {
        // positions          // texture Coords
               -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,   0.0f,  0.0f, -1.0f,
                0.5f, -0.5f, -0.5f,  1.0f, 0.0f,   0.0f,  0.0f, -1.0f,
                0.5f,  0.5f, -0.5f,  1.0f, 1.0f,   0.0f,  0.0f, -1.0f,
                0.5f,  0.5f, -0.5f,  1.0f, 1.0f,   0.0f,  0.0f, -1.0f,
               -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,   0.0f,  0.0f, -1.0f,
               -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,   0.0f,  0.0f, -1.0f,
    
               -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,   0.0f,  0.0f, 1.0f,
                0.5f, -0.5f,  0.5f,  1.0f, 0.0f,   0.0f,  0.0f, 1.0f,
                0.5f,  0.5f,  0.5f,  1.0f, 1.0f,   0.0f,  0.0f, 1.0f,
                0.5f,  0.5f,  0.5f,  1.0f, 1.0f,   0.0f,  0.0f, 1.0f,
               -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,   0.0f,  0.0f, 1.0f,
               -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,   0.0f,  0.0f, 1.0f,
    
               -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,   -1.0f,  0.0f,  0.0f,
               -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,   -1.0f,  0.0f,  0.0f,
               -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,   -1.0f,  0.0f,  0.0f,
               -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,   -1.0f,  0.0f,  0.0f,
               -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,   -1.0f,  0.0f,  0.0f,
               -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,   -1.0f,  0.0f,  0.0f,
    
                0.5f,  0.5f,  0.5f,  1.0f, 0.0f,   1.0f,  0.0f,  0.0f,
                0.5f,  0.5f, -0.5f,  1.0f, 1.0f,   1.0f,  0.0f,  0.0f,
                0.5f, -0.5f, -0.5f,  0.0f, 1.0f,   1.0f,  0.0f,  0.0f,
                0.5f, -0.5f, -0.5f,  0.0f, 1.0f,   1.0f,  0.0f,  0.0f,
                0.5f, -0.5f,  0.5f,  0.0f, 0.0f,   1.0f,  0.0f,  0.0f,
                0.5f,  0.5f,  0.5f,  1.0f, 0.0f,   1.0f,  0.0f,  0.0f,
    
               -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,   0.0f, -1.0f,  0.0f,
                0.5f, -0.5f, -0.5f,  1.0f, 1.0f,   0.0f, -1.0f,  0.0f,
                0.5f, -0.5f,  0.5f,  1.0f, 0.0f,   0.0f, -1.0f,  0.0f,
                0.5f, -0.5f,  0.5f,  1.0f, 0.0f,   0.0f, -1.0f,  0.0f,
               -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,   0.0f, -1.0f,  0.0f,
               -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,   0.0f, -1.0f,  0.0f,
    
               -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,   0.0f,  1.0f,  0.0f,
                0.5f,  0.5f, -0.5f,  1.0f, 1.0f,   0.0f,  1.0f,  0.0f,
                0.5f,  0.5f,  0.5f,  1.0f, 0.0f,   0.0f,  1.0f,  0.0f,
                0.5f,  0.5f,  0.5f,  1.0f, 0.0f,   0.0f,  1.0f,  0.0f,
               -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,   0.0f,  1.0f,  0.0f,
               -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,   0.0f,  1.0f,  0.0f
    };
    
    
    
    static float planeVertices[] = {
            // positions          // texture Coords  // NORMAL
            5.0f, -0.5f,  5.0f,  2.0f, 0.0f,   0.0f,1.0f,0.0f,
            -5.0f, -0.5f,  5.0f,  0.0f, 0.0f,  0.0f,1.0f,0.0f,
            -5.0f, -0.5f, -5.0f,  0.0f, 2.0f,  0.0f,1.0f,0.0f,
    
            5.0f, -0.5f,  5.0f,  2.0f, 0.0f,   0.0f,1.0f,0.0f,
            -5.0f, -0.5f, -5.0f,  0.0f, 2.0f,  0.0f,1.0f,0.0f,
            5.0f, -0.5f, -5.0f,  2.0f, 2.0f,   0.0f,1.0f,0.0f,
    };
    
    float quadVertices[] = {
        // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
           // positions   // texCoords
           -1.0f,  1.0f,  0.0f, 1.0f,
           -1.0f, -1.0f,  0.0f, 0.0f,
            1.0f, -1.0f,  1.0f, 0.0f,
    
           -1.0f,  1.0f,  0.0f, 1.0f,
            1.0f, -1.0f,  1.0f, 0.0f,
            1.0f,  1.0f,  1.0f, 1.0f
    };
    
    
    // cube vao vbo
    static unsigned int cubeVAO,cubeVBO;
    static unsigned int planeVAO,planeVBO;
    static unsigned int quadVAO,quadVBO;
    static unsigned int envCubeVAO,envCubeVBO;
    
    
    static unsigned int FBO; // frame buffer object
    static unsigned int FBOTextureID; // texture attachment to FBO
    static unsigned int RBO; // render buffer object
    
    
    
    // Geometry//
    // camera
    static GLFWCamera *camera;
    // light define
    static glm::vec3 lightPos(0.0f, 4.0f,-2.0f);
    
    static DrawGrid grid;
    static DrawEnvBox envBox;
    
    static LoadTexture cubeTex;
    static LoadTexture groundTex;
    
    
    void init(){
        camera = new GLFWCamera;
        camera->pos.y = 1.0f;
        camera->pos.z = 4.0f;
        // GL depth zbuffer
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
        SurfaceShader.load("shaders/SurfaceShader.vert","shaders/SurfaceShader.frag");
        ScreenShader.load("shaders/ScreenShader.vert","shaders/ScreenShader.frag");
    
    
        glGenVertexArrays(1, &cubeVAO);
        glGenBuffers(1, &cubeVBO);
        glBindVertexArray(cubeVAO);
        glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);
        // pos
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
        // st
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
        // N
        glEnableVertexAttribArray(2);
        glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(5 * sizeof(float)));
    
    
    
        CreateGeometryBuffer(planeVAO, planeVBO);
        glBufferData(GL_ARRAY_BUFFER,sizeof(planeVertices),&planeVertices, GL_STATIC_DRAW);
        // pos
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
        // st
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
        // N
        glEnableVertexAttribArray(2);
        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(5 * sizeof(float)));
    
    
    
        CreateGeometryBuffer(quadVAO, quadVBO);
        glBufferData(GL_ARRAY_BUFFER,sizeof(quadVertices),&quadVertices, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
    
        // create Cube Map VAO VBO
        CreateGeometryBuffer(envCubeVAO, envCubeVBO);
        glBufferData(GL_ARRAY_BUFFER,sizeof(skyboxVertices),&skyboxVertices, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    
    
    
        glBindVertexArray(0);
    
        cout << "cube VAO:" << cubeVAO <<endl;
        cubeTex.load("texture/marble.jpg");
        groundTex.load("texture/metal.png");
    
    
        // load cube map
        vector <string> envMaps{
                "texture/skybox/right.jpg",
                "texture/skybox/left.jpg",
                "texture/skybox/top.jpg",
                "texture/skybox/bottom.jpg",
                "texture/skybox/front.jpg",
                "texture/skybox/back.jpg"
        };
        envBox.setupMaps(envMaps);
        envBox.initialize();
    
    
        // FBO with texture attchment
        CreateFrameBufferTextured(SRC_WIDTH,SRC_HEIGHT,FBO,FBOTextureID);
        // Render buffer object
        CreateRenderBufferObject(SRC_WIDTH,SRC_HEIGHT,RBO);
    
    
        grid.initialize();
    
    
    
    }
    
    // ----------- Render Loop ----------
    void display(){
    
    
        // per-frame time logic
                // --------------------
        float currentFrame = glfwGetTime();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;
    
    
    
    
    
        // object .vert settings
        glm::mat4 projection = glm::perspective(glm::radians(camera->fov),float(SRC_WIDTH) / float(SRC_HEIGHT),0.1f,  1000.0f);
        glm::mat4 view = camera->GetViewMatrix();
        // object world transformation
        glm::mat4 model = glm::mat4(1.0f);
    
    
        // bind to framebuffer and draw scene as we normally would to color texture
        glBindFramebuffer(GL_FRAMEBUFFER, FBO);
        glEnable(GL_DEPTH_TEST); // enable depth testing (is disabled for rendering screen-space quad)
    
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    
        // draw grid
        //grid.draw(projection,view);
    
        SurfaceShader.use();
        SurfaceShader.setMat4("projection", projection);
        SurfaceShader.setMat4("view", view);
        SurfaceShader.setVec3("cameraPos",camera->pos);
    
        // ------------------------TEXTURE UNIT -------------------
        // box map 0
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D,cubeTex.textureID);
    
        // ground map  1
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D,groundTex.getTextureID());
    
        // CUBE map  2
        glActiveTexture(GL_TEXTURE2);
        glBindTexture(GL_TEXTURE_CUBE_MAP,envBox.texture.textureID);
        // set FBO TextureID 3
        glActiveTexture(GL_TEXTURE3);
        glBindTexture(GL_TEXTURE_2D, FBOTextureID);
        // ------------------------TEXTURE UNIT -------------------
    
        // draw BOX
        SurfaceShader.setInt("diffuse_map", 0);
        SurfaceShader.setInt("skybox", 2);
        model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));
        SurfaceShader.setMat4("model", model);
        glBindVertexArray(cubeVAO);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        model = glm::mat4(1.0f);
        model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f));
        SurfaceShader.setMat4("model", model);
        glDrawArrays(GL_TRIANGLES, 0, 36);
    
    
        // Draw Plane
        SurfaceShader.setInt("diffuse_map", 1);
        glBindVertexArray(planeVAO);
        model = glm::mat4(1.0f);
        SurfaceShader.setMat4("model", model);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    
        // draw Env Cube Map
        envBox.draw(projection,view);
    
    
    
        // now bind back to default framebuffer and draw a quad plane with the attached framebuffer color texture
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        // disable depth test so screen-space quad isn't discarded due to depth test.
        glDisable(GL_DEPTH_TEST);
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // set clear color to white (not really necessery actually, since we won't be able to see behind the quad anyways)
        glClear(GL_COLOR_BUFFER_BIT);
        ScreenShader.use();
        ScreenShader.setInt("screenTexture",3);
        glBindVertexArray(quadVAO);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    
    }
    
    
    int main()
    {
        glfwInit();
        FrameWindow FrameWindow(SRC_WIDTH,SRC_HEIGHT);
        glfwSetFramebufferSizeCallback(FrameWindow.getWindow(), framebuffer_size_callback);
        glfwSetCursorPosCallback(FrameWindow.getWindow(),mouse_callback);
        glfwSetScrollCallback(FrameWindow.getWindow(), scroll_callback);
        init();
        // RENDER--------------
        //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        while(!glfwWindowShouldClose(FrameWindow.getWindow())){
            processInput(FrameWindow.getWindow());
            display();
            glfwSwapBuffers(FrameWindow.getWindow());
            glfwPollEvents();
        }
        delete camera;
        glDeleteVertexArrays(1, &cubeVAO);
        glDeleteVertexArrays(1, &planeVAO);
        glDeleteVertexArrays(1, &quadVAO);
        glDeleteBuffers(1, &cubeVBO);
        glDeleteBuffers(1, &planeVBO);
        glDeleteBuffers(1, &quadVBO);
        return 0;
    }
    
    void framebuffer_size_callback(GLFWwindow* window, int width, int height)
    {
        // make sure the viewport matches the new window dimensions; note that width and
        // height will be significantly larger than specified on retina displays.
        glViewport(0, 0, width, height);
    }
    
    void processInput(GLFWwindow *window)
    {
        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(window, true);
        if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
            camera->processKeyboardMove(deltaTime,GLFWCamera::FORWARD);
        if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
            camera->processKeyboardMove(deltaTime,GLFWCamera::BACKWARD);
        if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
            camera->processKeyboardMove(deltaTime,GLFWCamera::LEFT);
        if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
            camera->processKeyboardMove(deltaTime,GLFWCamera::RIGHT);
    }
    
    // ROTATE VIEW DIR
    void mouse_callback(GLFWwindow* window, double xpos, double ypos){
    
        int middow_mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_MIDDLE);
        int mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT);
        int key_state = glfwGetKey(window,GLFW_KEY_LEFT_ALT);
        // set up the camera view
        if( mouse_state == GLFW_PRESS && key_state== GLFW_PRESS)
        {
            if (firstMouse){
                lastX = xpos;
                lastY = ypos;
                firstMouse = false;
            }
            float xoffset = xpos - lastX;
            float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
            lastX = xpos;
            lastY = ypos;
            camera->processMouseMove(xoffset,yoffset);
        }
        if (key_state == GLFW_RELEASE || mouse_state == GLFW_RELEASE){
            firstMouse = true;
        }
    
    
        // Move Camera Position
        if( middow_mouse_state == GLFW_PRESS) {
    
            if (firstMiddowMouse){
                lastX = xpos;
                lastY = ypos;
                firstMiddowMouse = false;
            }
            float xoffset = xpos - lastX;
            float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
            lastX = xpos;
            lastY = ypos;
            camera->pos.x += xoffset*0.01f;
            camera->pos.y += yoffset*0.01f;
    
        }
        if ( middow_mouse_state == GLFW_RELEASE){
            firstMiddowMouse = true;
        }
    
    }
    
    void scroll_callback(GLFWwindow *window, double xoffset, double yoffset){
        camera->processFov(yoffset);
    }
    main.cpp

    主程序里有贴图单元,因为我在测试的时候,平面和立方体用了一个贴图,现在加入一个环境盒子贴图,所以用了贴图单元。

    #version 450 core
    // Final Color To export
    out vec4 FragColor;
    
    // from vert shader
    in vec3 f_Normal;
    in vec2 f_TexCoord;
    in vec3 f_Pos; // fragment position
    
    uniform vec3 cameraPos;
    uniform sampler2D diffuse_map;
    uniform samplerCube skybox;
    
    void main()
    {
        vec3 I = normalize(f_Pos - cameraPos);     // this is not wi, wi = I - P
        vec3 R = reflect(I, normalize(f_Normal));    // get reflect dir
        vec4 reflectEnv = vec4(texture(skybox, R).rgb,1.0f);  // sample reflect box
        vec4 df = texture(diffuse_map, f_TexCoord);
        FragColor =  df*0.8 + reflectEnv*0.4f;
    }
    SurfaceShader.frag
    #version 450 core
    // INCOMING DATA
    layout ( location = 0 ) in vec4 v_position; //  pos
    layout ( location = 1 ) in vec2 v_texCoord; //  st
    layout ( location = 2 ) in vec3 v_normal; //  st
    
    // define out data
    out vec2 f_TexCoord;
    // normal at world matrix, we direct from C++ calcalation
    out vec3 f_Normal;  // to world matrix : mat3( transpose(inverse(model)) ) * v_normal;
    out vec3 f_Pos;
    
    
    // INCOMING THE MATRIX FROM CLIENT to transform the gl point position
    uniform mat4 model;
    uniform mat4 view;
    uniform mat4 projection;
    
    
    
    
    void main(){
        // Transform the world matrix to view matrix
        gl_Position = projection *   view * model * v_position;
        f_Normal = mat3(transpose(inverse(model))) * v_normal;  // f_Normal at world matrix
        f_TexCoord = v_texCoord;          // out TexCoord
        f_Pos = vec3(model *v_position);  // out fragment position
    }
    SurfaceShader.vert
  • 相关阅读:
    Java实现 LeetCode 413 等差数列划分
    Java实现 LeetCode 413 等差数列划分
    Java实现 LeetCode 412 Fizz Buzz
    简单字符设备驱动程序
    fork与vfork的区别
    进程创建函数fork()、vfork() ,以及excel()函数
    区分execl与system——应用程序中执行命令
    CMOS Sensor的调试经验分享
    嵌入式ARM-Linux开发工具下载地址合集
    嵌入式 linux 查看内存
  • 原文地址:https://www.cnblogs.com/gearslogy/p/12378518.html
Copyright © 2020-2023  润新知