• - OPENGL8


    CP27抗锯齿:

     

    方法1:最简单得就用GLFW: MSAA

    glfwWindowHint(GLFW_SAMPLES, 4);
    glEnable(GL_MULTISAMPLE);

    方法2:离屏MSAA

    第一种是直接生成MultiSampled Framebuffer 直接拷贝到 default Framebuffer.

    //
    // Created by admin on 2020/2/27.
    //
    
    #ifndef TRIANGLE_ALG_OGLHELPER_H
    #define TRIANGLE_ALG_OGLHELPER_H
    #include <iostream>
    #define GLEW_STATIC
    #include <GL/glew.h>
    
    
    namespace AlgebraMaster{
        // --------------------- function declaration ----------------------------------------
        // * create VAO and VBO, but not contain any data /
        void CreateGeometryBuffer(GLuint &VAO, GLuint &VBO);
    
        // * Create framebuffer that can attach a texture/
        void CreateFrameBufferTextured(int width, int height, GLuint &framebufferID, GLuint &attachTextureID);
        // * create RenderBuffer object that can render depth, stent
        void CreateRenderBufferObject(int width, int height, GLuint &renderBufferID);
    
        // * Create multiSampled frame buffer that attached a texture /
        void CreateMultiSampledFrameBufferTextured(int width, int height, GLuint &framebufferID, GLuint &attachTextureID, int samples=4);
        // * Create multiSampled RenderBuffer /
        void CreateMultiSampledRenderBufferObject(int width, int height, GLuint &renderBufferID,int samples = 4);
    
        //* from src buffer to des buffer , if des buffer=0 , that copy to screen
        void CopyFrameBuffer(const GLuint &srcBufferID, const GLuint &desBufferID, int width, int height, bool copyDepth=false, bool copyStencil= false );
    
        // --------------------- function declaration ----------------------------------------
    
    
    
        // --------------------- function definition ----------------------------------------
        void CreateGeometryBuffer(GLuint &VAO, GLuint &VBO){
            glCreateVertexArrays(1, &VAO);
            glCreateBuffers(1,&VBO);
            glBindVertexArray(VAO);
            glBindBuffer(GL_ARRAY_BUFFER, VBO);
    
        }
    
        // create frame buffer that attached a texture
        void CreateFrameBufferTextured(int width, int height ,GLuint &framebufferID,
                                       GLuint &attachTextureID){
    
            glGenFramebuffers(1, &framebufferID);
            glBindFramebuffer(GL_FRAMEBUFFER, framebufferID);
    
            glGenTextures(1, &attachTextureID);
            glBindTexture(GL_TEXTURE_2D, attachTextureID);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, 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, attachTextureID, 0);
        }
    
        // create render buffer that can render DEPTH/STENCIL
        void CreateRenderBufferObject(int width, int height, GLuint &renderBufferID)
        {
            glGenRenderbuffers(1, &renderBufferID);
            glBindRenderbuffer(GL_RENDERBUFFER, renderBufferID);
            glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); // use a single renderbuffer object for both a depth AND stencil buffer.
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBufferID); // 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);
        }
    
        // a multi sampled frame buffer with a multi sampled texture
        void CreateMultiSampledFrameBufferTextured(int width, int height, GLuint &framebufferID, GLuint &attachTextureID, int samples){
            glCreateFramebuffers(1,&framebufferID);
            glBindFramebuffer(GL_FRAMEBUFFER, framebufferID);
            glGenTextures(1,&attachTextureID);
            glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,attachTextureID);
            glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,samples,GL_RGB,width,height,GL_TRUE);
            glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
            glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D_MULTISAMPLE,attachTextureID,0);
    
        }
        // Multi sampled render buffer
        void CreateMultiSampledRenderBufferObject(int width, int height, GLuint &renderBufferID,int samples ){
            glGenRenderbuffers(1, &renderBufferID);
            glBindRenderbuffer(GL_RENDERBUFFER, renderBufferID);
            glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH24_STENCIL8, width,height);
            glBindRenderbuffer(GL_RENDERBUFFER, 0);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBufferID); // now actually attach it
            if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
                cout << "ERROR::MULTI_FRAMEBUFFER:: Framebuffer is not complete!" << endl;
            glBindFramebuffer(GL_FRAMEBUFFER, 0);
        }
    
        //* from src buffer to des buffer , if des buffer=0 , that copy to screen
        void CopyFrameBuffer(const GLuint &srcBufferID, const GLuint &desBufferID, int width, int height, bool copyDepth, bool copyStencil )
        {
            glBindFramebuffer(GL_READ_FRAMEBUFFER, srcBufferID);
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, desBufferID);
            glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
            if (copyDepth)
                glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
            if (copyStencil)
                glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
        }
    
    
        // --------------------- function definition ----------------------------------------
    } // end of namespace
    
    
    
    
    
    
    
    
    
    #endif //TRIANGLE_ALG_OGLHELPER_H
    ALG_OGLHelper.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 "ALG_DrawOriginGnomon.h"
    #include "ALG_DrawCube.h"
    #include <cmath>
    
    #include "ALG_Random.h"
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    using namespace AlgebraMaster;
    
    
    const unsigned int SRC_WIDTH = 1400;
    const unsigned int SRC_HEIGHT = 720;
    
    
    static GLuint cubeVAO,VBO;
    static GLuint lightVAO;  //VBO stays the same; the vertices are the same for the light object which is also a 3D cube
    
    
    static LoadShader SurfaceShader;
    
    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);
    
    static Scene scene;
    static DrawGrid grid;
    static DrawOriginGnomon gnomon;
    const int amount = 100;
    
    // framebuffer
    static GLuint multiFBO;
    static GLuint multiFBOTexture;
    static GLuint multiRBO;
    // PostProcessing Buffer
    static GLuint  postFrameBufferID;
    
    
    
    void init(){
    
    
    
        camera = new GLFWCamera;
        camera->pos.y = 0.5f;
        camera->pos.z = 2.0f;
        // GL depth zbuffer
        glEnable(GL_DEPTH_TEST);
    
    
    
        SurfaceShader.load("shaders/standard_surface/SurfaceShader.vert","shaders/standard_surface/SurfaceShader.frag");
    
    
        scene.read("scene/scene.json");
        scene.parseInitialize();
        scene.parseModel();
        scene.parseMats();
        scene.parseAssignMats();
    
        grid.initialize();
        gnomon.initialize();
    
    
        // Instance Array building:
    
        auto *modelMatrices = new glm::mat4[amount];
    
        RandomN1P1 xPosSet(amount, 1);
        RandomN1P1 zPosSet(amount, 2);
        RandomN1P1 rotAmount(amount,3);
        Random01 scaleAmount(amount,4);
        //cout << scaleAmount <<endl;
    
        for(int i=0;i<amount;i++)
        {
            // new translate
            glm::mat4 model(1.0f);
            model = glm::translate(model,glm::vec3(xPosSet[i]*20, 0.0, zPosSet[i]*20  )  );
            // new rot
            glm::mat4 rot(1.0f);
            rot = glm::rotate(rot,glm::radians(rotAmount[i]*360) , glm::vec3(0.0,1.0,0.0));
            // R S T order
            glm::mat4 scale(1.0f);
            scale = glm::scale(  scale,glm::vec3(scaleAmount[i])  );
    
            modelMatrices[i] = model * scale * rot  ;
        }
        //object share one mem buffer of instance
        unsigned int buffer;
        glCreateBuffers(1, &buffer);
        glBindBuffer(GL_ARRAY_BUFFER, buffer);
        glBufferData(GL_ARRAY_BUFFER, amount * sizeof(glm::mat4), &modelMatrices[0], GL_STATIC_DRAW);
    
        for(auto &model: scene.allModels){
            for(auto &loc: model->locations)
            {
                glBindVertexArray(loc->mesh->VAO);
    
                glEnableVertexAttribArray(10);
                glVertexAttribPointer(10, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)0);
    
                glEnableVertexAttribArray(11);
                glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(sizeof(glm::vec4)));
    
                glEnableVertexAttribArray(12);
                glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(2 * sizeof(glm::vec4)));
    
                glEnableVertexAttribArray(13);
                glVertexAttribPointer(13, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(3 * sizeof(glm::vec4)));
    
                glVertexAttribDivisor(10, 1);
                glVertexAttribDivisor(11, 1);
                glVertexAttribDivisor(12, 1);
                glVertexAttribDivisor(13, 1);
                glBindVertexArray(0);
            }
        }
        delete [] modelMatrices;
        const int samplers = 32;
        // Create MultiSampler Framebuffer with attached texture
        CreateMultiSampledFrameBufferTextured(SRC_WIDTH, SRC_HEIGHT, multiFBO, multiFBOTexture, samplers);
        // Create MultiSampler render buffer
        CreateMultiSampledRenderBufferObject(SRC_WIDTH, SRC_HEIGHT, multiRBO, samplers);
    
    }
    
    // object .vert settings
    
    // ----------- Render Loop ----------
    void display(){
    
        // per-frame time logic
                // --------------------
        float currentFrame = glfwGetTime();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;
    
    
        glm::mat4 view = camera->GetViewMatrix();
        glm::mat4 projection = glm::perspective(glm::radians(camera->fov),float(SRC_WIDTH) / float(SRC_HEIGHT),0.1f,  1000.0f);
        // object world transformation
        glm::mat4 model = glm::mat4(1.0f);
        scene.setMatrix(projection,view,model);
    
        // 1. draw scene as normal in multisampled buffers
        glBindFramebuffer(GL_FRAMEBUFFER, multiFBO);
        glClearColor(0.1f, 0.2f, 0.4f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glEnable(GL_DEPTH_TEST);
    
    
        for(auto &m: scene.allModels){
            for(auto &loc: m->locations){
                glBindVertexArray(loc->mesh->VAO);
    
                loc->mesh->shader.use();
                loc->mesh->shader.setInt("useInstance", 1);
                loc->mesh->shader.setMatrix(model,view,projection);
                loc->mesh->allocateTextureChannelFromShader(loc->mesh->shader);
                //glDrawElements(GL_TRIANGLES, loc->mesh->indices.size(), GL_UNSIGNED_INT, 0);
                glDrawElementsInstanced(GL_TRIANGLES, loc->mesh->indices.size(), GL_UNSIGNED_INT, 0, amount);
                glBindVertexArray(0);
            }
        }
    
    
    
    
        grid.draw(projection,view);
        gnomon.draw(projection,view);
    
    
    
    
    
    
        // copy multi buffer to our default screen buffer
        CopyFrameBuffer(multiFBO,0,SRC_WIDTH,SRC_HEIGHT,true);
    
    
    
    
    }
    
    
    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--------------
        while(!glfwWindowShouldClose(FrameWindow.getWindow())){
            processInput(FrameWindow.getWindow());
            display();
            glfwSwapBuffers(FrameWindow.getWindow());
            glfwPollEvents();
        }
        delete camera;
        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

    上面OGLHelper.h里有3个函数:

     // a multi sampled frame buffer with a multi sampled texture
        void CreateMultiSampledFrameBufferTextured(int width, int height, GLuint &framebufferID, GLuint &attachTextureID, int samples){
            glCreateFramebuffers(1,&framebufferID);
            glBindFramebuffer(GL_FRAMEBUFFER, framebufferID);
            glGenTextures(1,&attachTextureID);
            glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,attachTextureID);
            glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,samples,GL_RGB,width,height,GL_TRUE);
            glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
            glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D_MULTISAMPLE,attachTextureID,0);
    
        }
        // Multi sampled render buffer
        void CreateMultiSampledRenderBufferObject(int width, int height, GLuint &renderBufferID,int samples ){
            glGenRenderbuffers(1, &renderBufferID);
            glBindRenderbuffer(GL_RENDERBUFFER, renderBufferID);
            glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH24_STENCIL8, width,height);
            glBindRenderbuffer(GL_RENDERBUFFER, 0);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBufferID); // now actually attach it
            if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
                cout << "ERROR::MULTI_FRAMEBUFFER:: Framebuffer is not complete!" << endl;
            glBindFramebuffer(GL_FRAMEBUFFER, 0);
        }
    
        //* from src buffer to des buffer , if des buffer=0 , that copy to screen
        void CopyFrameBuffer(const GLuint &srcBufferID, const GLuint &desBufferID, int width, int height, bool copyDepth, bool copyStencil )
        {
            glBindFramebuffer(GL_READ_FRAMEBUFFER, srcBufferID);
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, desBufferID);
            glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
            if (copyDepth)
                glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
            if (copyStencil)
                glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
        }

    所以main中逻辑就是:

    void init()
    {
    ...
    // Create MultiSampler Framebuffer with attached texture
        CreateMultiSampledFrameBufferTextured(SRC_WIDTH, SRC_HEIGHT, multiFBO, multiFBOTexture, samplers);
        // Create MultiSampler render buffer
        CreateMultiSampledRenderBufferObject(SRC_WIDTH, SRC_HEIGHT, multiRBO, samplers);
    }
    
    void display(){
    
     // 1. draw scene as normal in multisampled buffers
        glBindFramebuffer(GL_FRAMEBUFFER, multiFBO);
        glClearColor(0.1f, 0.2f, 0.4f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glEnable(GL_DEPTH_TEST);
        // RenderYour Objs.........
    
    
        // copy multi buffer to our default screen buffer
        CopyFrameBuffer(multiFBO,0,SRC_WIDTH,SRC_HEIGHT,true);
    }

    这种情况下的材质是没改变的。

    如果要改变成 自定义多采样材质算法,参考https://www.cnblogs.com/chandler00x/p/3888139.html

    注意这样对拷有个问题,是因为直接从MultiSampledBuffer->DefaultSampledBuffer.会导致屏幕放大,并没有适配。

    但是下面的带有PostProcessingBuffer不会。

    第二种带有Post processing的framebuffer

    两幅图来展示:

    注意第二幅图中间copy的过程,glBlitFrameBuffer()我没有copy depth, copy stencil, 因为这个imtermediateFBO 是一个only color attached texture buffer.

     

    //
    // Created by admin on 2020/3/9.
    //
    
    #ifndef TRIANGLE_ALG_DRAWPOSTPOCESSINGQUAD_H
    #define TRIANGLE_ALG_DRAWPOSTPOCESSINGQUAD_H
    
    #include "ALG_LoadShader.h"
    #include "ALG_OGLHelper.h"
    namespace AlgebraMaster{
    
        static float __postQuadVertices__[] = {
                // 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
        };
    
    
        class DrawPostProcessingQuad{
        public:
            void initialize(){
                glGenVertexArrays(1, &VAO);
                glGenBuffers(1, &VBO);
                glBindVertexArray(VAO);
                glBindBuffer(GL_ARRAY_BUFFER, VBO);
                glBufferData(GL_ARRAY_BUFFER, sizeof(__postQuadVertices__), &__postQuadVertices__, GL_STATIC_DRAW);
                // pos
                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)));
    
                shader.fromSrc(vertexShaderSource,fragmentShaderSource);
                CreateFrameBufferTextured(mWidth,mHeight,FBO,FBOTexture);
    
            }
    
            void setupWidthHeight(int width,int height){
                mWidth = width;
                mHeight = height;
            }
            void draw(){
                shader.use();
                glBindVertexArray(VAO);
                glActiveTexture(GL_TEXTURE0);
                glBindTexture(GL_TEXTURE_2D,FBOTexture ); // use the now resolved color attachment as the quad's texture
                glDrawArrays(GL_TRIANGLES, 0, 6);
            }
    
    
            const char* fragmentShaderSource = "#version 450 core
    "
                                               "out vec4 FragColor;
    "
                                               "in vec2 TexCoords;
    "
                                               "uniform sampler2D screenTexture;
    "
                                               "void main()
    "
                                               "{
    "
                                               "vec3 col = texture(screenTexture, TexCoords).rgb;
    "
                                               "float grayscale = 0.2126 * col.r + 0.7152 * col.g + 0.0722 * col.b;
    "
                                               "FragColor = vec4(vec3(grayscale), 1.0);
    "
                                               "}
    ";
    
            const char* vertexShaderSource = "#version 450 core
    "
                                             "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);
    "
                                             "}
    ";
    
            unsigned int VAO,VBO,FBO,FBOTexture;
            LoadShader shader;
            int mWidth;
            int mHeight;
    
        };
    
    
    }
    
    
    
    
    
    #endif //TRIANGLE_ALG_DRAWPOSTPOCESSINGQUAD_H
    ALG_DrawPostPocessingQuad.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 "ALG_DrawOriginGnomon.h"
    #include "ALG_DrawCube.h"
    #include "ALG_DrawPostPocessingQuad.h"
    #include <cmath>
    
    #include "ALG_Random.h"
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    using namespace AlgebraMaster;
    
    
    const unsigned int SRC_WIDTH = 1400;
    const unsigned int SRC_HEIGHT = 720;
    
    
    static GLuint cubeVAO,VBO;
    static GLuint lightVAO;  //VBO stays the same; the vertices are the same for the light object which is also a 3D cube
    
    
    static LoadShader SurfaceShader;
    
    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);
    
    static Scene scene;
    static DrawGrid grid;
    static DrawOriginGnomon gnomon;
    static DrawPostProcessingQuad quad;
    const int amount = 100;
    
    // framebuffer
    static GLuint multiFBO;
    static GLuint multiFBOTexture;
    static GLuint multiRBO;
    // PostProcessing Buffer
    
    
    
    
    void init(){
    
    
    
        camera = new GLFWCamera;
        camera->pos.y = 0.5f;
        camera->pos.z = 2.0f;
        // GL depth zbuffer
        glEnable(GL_DEPTH_TEST);
    
    
    
        SurfaceShader.load("shaders/standard_surface/SurfaceShader.vert","shaders/standard_surface/SurfaceShader.frag");
    
    
        scene.read("scene/scene.json");
        scene.parseInitialize();
        scene.parseModel();
        scene.parseMats();
        scene.parseAssignMats();
    
        grid.initialize();
        gnomon.initialize();
        quad.setupWidthHeight(SRC_WIDTH,SRC_HEIGHT);
        quad.initialize();
    
        // Instance Array building:
    
        auto *modelMatrices = new glm::mat4[amount];
    
        RandomN1P1 xPosSet(amount, 1);
        RandomN1P1 zPosSet(amount, 2);
        RandomN1P1 rotAmount(amount,3);
        Random01 scaleAmount(amount,4);
        //cout << scaleAmount <<endl;
    
        for(int i=0;i<amount;i++)
        {
            // new translate
            glm::mat4 model(1.0f);
            model = glm::translate(model,glm::vec3(xPosSet[i]*20, 0.0, zPosSet[i]*20  )  );
            // new rot
            glm::mat4 rot(1.0f);
            rot = glm::rotate(rot,glm::radians(rotAmount[i]*360) , glm::vec3(0.0,1.0,0.0));
            // R S T order
            glm::mat4 scale(1.0f);
            scale = glm::scale(  scale,glm::vec3(scaleAmount[i])  );
    
            modelMatrices[i] = model * scale * rot  ;
        }
        //object share one mem buffer of instance
        unsigned int buffer;
        glCreateBuffers(1, &buffer);
        glBindBuffer(GL_ARRAY_BUFFER, buffer);
        glBufferData(GL_ARRAY_BUFFER, amount * sizeof(glm::mat4), &modelMatrices[0], GL_STATIC_DRAW);
    
        for(auto &model: scene.allModels){
            for(auto &loc: model->locations)
            {
                glBindVertexArray(loc->mesh->VAO);
    
                glEnableVertexAttribArray(10);
                glVertexAttribPointer(10, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)0);
    
                glEnableVertexAttribArray(11);
                glVertexAttribPointer(11, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(sizeof(glm::vec4)));
    
                glEnableVertexAttribArray(12);
                glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(2 * sizeof(glm::vec4)));
    
                glEnableVertexAttribArray(13);
                glVertexAttribPointer(13, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(3 * sizeof(glm::vec4)));
    
                glVertexAttribDivisor(10, 1);
                glVertexAttribDivisor(11, 1);
                glVertexAttribDivisor(12, 1);
                glVertexAttribDivisor(13, 1);
                glBindVertexArray(0);
            }
        }
        delete [] modelMatrices;
        const int samplers = 1;
        // Create MultiSampler Framebuffer with attached texture
        CreateMultiSampledFrameBufferTextured(SRC_WIDTH, SRC_HEIGHT, multiFBO, multiFBOTexture, samplers);
        // Create MultiSampler render buffer
        CreateMultiSampledRenderBufferObject(SRC_WIDTH, SRC_HEIGHT, multiRBO, samplers);
    
        // FBO
    }
    
    // object .vert settings
    
    // ----------- Render Loop ----------
    void display(){
    
        // per-frame time logic
                // --------------------
        float currentFrame = glfwGetTime();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;
    
    
    
    
        // render
        // ------
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        // 1. draw scene as normal in multisampled buffers
        glBindFramebuffer(GL_FRAMEBUFFER, multiFBO);
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glEnable(GL_DEPTH_TEST);
    
    
        glm::mat4 view = camera->GetViewMatrix();
        glm::mat4 projection = glm::perspective(glm::radians(camera->fov),float(SRC_WIDTH) / float(SRC_HEIGHT),0.1f,  1000.0f);
        // object world transformation
        glm::mat4 model = glm::mat4(1.0f);
        scene.setMatrix(projection,view,model);
    
    
    
    
        for(auto &m: scene.allModels){
            for(auto &loc: m->locations){
                glBindVertexArray(loc->mesh->VAO);
    
                loc->mesh->shader.use();
                loc->mesh->shader.setInt("useInstance", 1);
                loc->mesh->shader.setMatrix(model,view,projection);
                loc->mesh->allocateTextureChannelFromShader(loc->mesh->shader);
                //glDrawElements(GL_TRIANGLES, loc->mesh->indices.size(), GL_UNSIGNED_INT, 0);
                glDrawElementsInstanced(GL_TRIANGLES, loc->mesh->indices.size(), GL_UNSIGNED_INT, 0, amount);
                glBindVertexArray(0);
            }
        }
    
        grid.draw(projection,view);
        gnomon.draw(projection,view);
    
        // copy multi buffer to our default screen buffer
    
        CopyFrameBuffer(multiFBO,quad.FBO,SRC_WIDTH,SRC_HEIGHT);
    
    
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        quad.draw();
    
    
    }
    
    
    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--------------
        while(!glfwWindowShouldClose(FrameWindow.getWindow())){
            processInput(FrameWindow.getWindow());
            display();
            glfwSwapBuffers(FrameWindow.getWindow());
            glfwPollEvents();
        }
        delete camera;
        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

    可以看到main中最后使用了一个Renderbuffer.方法就是从MultiSampledBuffer->PostProcessingBuffer

     // copy multi buffer to our default screen buffer
        ......
    
        CopyFrameBuffer(multiFBO,quad.FBO,SRC_WIDTH,SRC_HEIGHT);
    
    
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        quad.draw();

  • 相关阅读:
    hash表学习笔记
    【学习笔记-集合】HashMap 源码浅析
    java 同步
    学习SpringBoot了
    记录一些好的 学习网站
    Idea 的页面布局设定,tomcat及普通web项目设定
    Spring 札记
    java面试题(基础+非基础)[不定期更新]
    maven 使用
    ant 生成报告时报错,Errors while applying transformations: Fatal error during transformation
  • 原文地址:https://www.cnblogs.com/gearslogy/p/12442373.html
Copyright © 2020-2023  润新知