zoukankan      html  css  js  c++  java
  • - 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();

  • 相关阅读:
    JS BOM对象 History对象 Location对象
    JS 字符串对象 数组对象 函数对象 函数作用域
    JS 引入方式 基本数据类型 运算符 控制语句 循环 异常
    Pycharm Html CSS JS 快捷方式创建元素
    CSS 内外边距 float positio属性
    CSS 颜色 字体 背景 文本 边框 列表 display属性
    【Android】RxJava的使用(三)转换——map、flatMap
    【Android】RxJava的使用(二)Action
    【Android】RxJava的使用(一)基本用法
    【Android】Retrofit 2.0 的使用
  • 原文地址:https://www.cnblogs.com/gearslogy/p/12442373.html
Copyright © 2011-2022 走看看