zoukankan      html  css  js  c++  java
  • OpenGL Instance Advanced

    1, General Method

    #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_DrawPostPocessingQuad.h"
    #include "ALG_DrawPlane.h"
    #include "ALG_DepthShadow.h"
    #include "ALG_OGLHelper.h"
    #include "ALG_DirLight.h"
    #include "ALG_SceneLocation.h"
    #include <cmath>
    #include "ALG_Random.h"
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    #include "ALG_FPS.h"
    
    using namespace AlgebraMaster;
    const unsigned int SRC_WIDTH = 900;
    const unsigned int SRC_HEIGHT = 900;
    
    
    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;
    
    
    static FrameWindow *frameWindow ;
    
    // per geometry verticles
    static float verticles[] = {
            -0.1f,  0.1f,
            -0.1f, -0.1f,
    
            0.1f, -0.1f,
            0.1f,  0.1f
    };
    static GLuint indices[] = {
            0 , 1 , 2,
            0 , 2 , 3
    };
    
    static GLuint VAO,VBO,EBO;
    static GLuint INST_COLOR_BUFFER, INST_MAT_BUFFER;
    static int INSTANCE_COUNT = 300;
    static LoadShader shader;
    void init(){
    
        glViewport(0,0,SRC_WIDTH,SRC_HEIGHT);
        if(!CheckExtension("GL_ARB_shading_language_include")){
            cout << "---------------ERROR:: SHADER DO NOT SUPPORT INCLUDE SHADER----------------------------------
    ";
        }
        AddCommonShaderFile("shaders/common/material_interface.glsl");
        AddCommonShaderFile("shaders/common/light_interface.glsl");
        AddCommonShaderFile("shaders/common/shadow.glsl");
        AddCommonShaderFile("shaders/common/utils.glsl");
        AddCommonShaderFile("shaders/common/postprocess.glsl");
    
        shader.load("shaders/advanced_instance/part1/surface.vert","shaders/advanced_instance/part1/surface.frag");
    
        camera = new GLFWCamera;
        camera->pos.y = 0.5f;
        camera->pos.z = 2.0f;
    
        // Create VAO
        glCreateVertexArrays(1,&VAO);
        glBindVertexArray(VAO);
    
        // set vertex buffer object data
        glCreateBuffers(1,&VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER,sizeof(verticles),verticles,GL_STATIC_DRAW );
        // local position
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);  // stride = 0 , offset = void* 0
    
    
    
    
    
        // create element buffer object
        glCreateBuffers(1,&EBO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices), indices, GL_STATIC_DRAW);
    
    
        // create color [-1,1] , but in this default buffer not support HDR , just ignore it
        RandomN1P1 r(INSTANCE_COUNT, 1321);
        RandomN1P1 g(INSTANCE_COUNT, 321321);
        RandomN1P1 b(INSTANCE_COUNT,231);
        glm::vec3 *colors = new glm::vec3[INSTANCE_COUNT];
        for(int i=0;i<INSTANCE_COUNT;i++){
            colors[i].r = r[i];
            colors[i].g = g[i];
            colors[i].b = b[i];
        }
        glCreateBuffers(1,&INST_COLOR_BUFFER);
        glBindBuffer(GL_ARRAY_BUFFER,INST_COLOR_BUFFER);
        glBufferData(GL_ARRAY_BUFFER,sizeof(glm::vec3) * INSTANCE_COUNT, &colors[0],GL_STATIC_DRAW);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0);
        glVertexAttribDivisor(1, 1);
    
    
        // create matrix
        glCreateBuffers(1,&INST_COLOR_BUFFER);
        glBindBuffer(GL_ARRAY_BUFFER,INST_COLOR_BUFFER);
        glm::mat4 *mats = new glm::mat4[INSTANCE_COUNT];
        // generator [-1,1] range
        RandomN1P1 xPosSet(INSTANCE_COUNT, 2312);
        RandomN1P1 yPosSet(INSTANCE_COUNT, 42);
        RandomN1P1 zPosSet(INSTANCE_COUNT, 31513);
        RandomN1P1 rotAmount(INSTANCE_COUNT,523);
        Random01 scaleAmount(INSTANCE_COUNT,3213);
        for(int i=0;i<INSTANCE_COUNT;i++){
            // new translate
            glm::mat4 model(1.0f);
            model = glm::translate(model,glm::vec3(xPosSet[i], yPosSet[i], zPosSet[i]  )  );
            // new rot
            glm::mat4 rot(1.0f);
            rot = glm::rotate(rot,glm::radians(rotAmount[i]*360) , glm::vec3(0.0,0.0,1.0));
            // R S T order
            glm::mat4 scale(1.0f);
            scale = glm::scale(  scale,glm::vec3(scaleAmount[i])  );
            mats[i] = model * scale * rot  ;
        }
        glCreateBuffers(1,&INST_MAT_BUFFER);
        glBindBuffer(GL_ARRAY_BUFFER,INST_MAT_BUFFER);
        glBufferData(GL_ARRAY_BUFFER,sizeof(glm::mat4) * INSTANCE_COUNT, &mats[0],GL_STATIC_DRAW);
    
        // first column
        glEnableVertexAttribArray(2);
        glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)0);
        // second column
        glEnableVertexAttribArray(3);
        glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(sizeof(glm::vec4)));
        // third column
        glEnableVertexAttribArray(4);
        glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(2 * sizeof(glm::vec4)));
        // fourth column
        glEnableVertexAttribArray(5);
        glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(3 * sizeof(glm::vec4)));
        glVertexAttribDivisor(2, 1);
        glVertexAttribDivisor(3, 1);
        glVertexAttribDivisor(4, 1);
        glVertexAttribDivisor(5, 1);
    
    }
    
    
    
    // ----------- Render Loop ----------
    void display(){
    
        int display_w, display_h;
        glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h);
    
        // Rendering objs Loop
        ClearAllBufferColor();
    
        glBindVertexArray(VAO);
        shader.use();
        glDrawElementsInstanced(GL_TRIANGLES,6, GL_UNSIGNED_INT, nullptr, INSTANCE_COUNT);  // 6 is our indices num
        //glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT, 0);
    }
    
    
    int main()
    {
    
        glfwInit();
        frameWindow = new FrameWindow(SRC_WIDTH,SRC_HEIGHT);
        glfwSetFramebufferSizeCallback(frameWindow->getWindow(), framebuffer_size_callback);
        glfwSetCursorPosCallback(frameWindow->getWindow(),mouse_callback);
        glfwSetScrollCallback(frameWindow->getWindow(), scroll_callback);
    
        init();
    
    
        //double lastTime  = glfwGetTime();
        //double targetFps = 60.0f;
    
        FPSLimit fpsLimit;
        fpsLimit.targetFps = 60.02f;
        FPSGet fpsGet;
    
    
    
        //double previousTime = glfwGetTime();
        //double frameCount = 0;
    
        // RENDER--------------
        // draw as wireframe
        //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        while(!glfwWindowShouldClose(frameWindow->getWindow())){
    
    
            processInput(frameWindow->getWindow());
            fpsLimit.limitFPS();
            fpsGet.updateFPS(frameWindow->getWindow());
    
    
    
            display();
            // Rendering objs Loop
    
    
            int display_w, display_h;
            glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h);
            glViewport(0, 0, display_w, display_h);
    
    
            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
    #version 450 core
    layout ( location = 0 ) in vec2 vPosition; // c++ pos
    layout ( location = 1 ) in vec3 vColor;       // instance color
    layout ( location = 2 ) in mat4 vModelMatrix; // instance matrix , 2,3,4,5
    
    out VERTEX{
        vec3 color;
    }vertex;
    
    
    void main(){
        gl_Position = vModelMatrix * vec4(vPosition.x, vPosition.y, 0.0, 1.0);
        vertex.color = vColor;
    }
    surface.vert
    #version 450 core
    out vec4 FragColor;
    
    in VERTEX{
        vec3 color;
    }vertex;
    
    void main()
    {
        FragColor = vec4(vertex.color,1.0); // set alle 4 vector values to 1.0
    }
    surface.frag
    //
    // Created by Admin on 2020/3/7.
    //
    
    #ifndef TRIANGLE_ALG_RANDOM_H
    #define TRIANGLE_ALG_RANDOM_H
    
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    #include <random>
    #include <iostream>
    #include <vector>
    
    
    
    #include <iostream>
    #include <limits>
    #include <random>
    
    namespace AlgebraMaster {
        using namespace std;
    
        // ------------- Float 0-1 Random gen------------------------
        struct RandomFloatBase{
            explicit RandomFloatBase(int num, int seed=1){
            }
    
            // datas
            vector<float> values;
            default_random_engine e;
            uniform_real_distribution<double> u;
            float operator[] (int index)const{
                return values[index];
            }
            float &operator[] (int index){
                return values[index];
            }
            friend ostream & operator << (ostream &os , const RandomFloatBase &rv){
                for(auto &v:rv.values){
                    cout << v <<" ";
                }
                cout << "
    ";
                return os;
            }
    
        };
    
    
    
    
        struct Random01:public RandomFloatBase{
            Random01(int num,int seed=1);
    
        };
    
        Random01::Random01(int num,int seed): RandomFloatBase(num, seed){
            e.seed(seed);
            u = uniform_real_distribution<double>(0.0,1.0);
            for(int i=0;i<num;i++){
                values.emplace_back(u(e));
            }
        }
    
        // ------------- Float 0-1 Random gen------------------------
    
        // ------------- Float -1 - 1 Random gen------------------------
        struct RandomN1P1:public RandomFloatBase{
            explicit RandomN1P1(int num,int seed=1);
        };
    
        RandomN1P1::RandomN1P1(int num,int seed): RandomFloatBase(num, seed){
            e.seed(seed);
            u = uniform_real_distribution<double>(-1.0,1.0);
            for(int i=0;i<num;i++){
                values.emplace_back(u(e));
            }
        }
    
    
    
    } // namespace end
    
    
    
    
    
    #endif //TRIANGLE_ALG_RANDOM_H
    C++random.h

     这里面最后要释放color和mats这两个数组。

    主要的绘制命令就:

    // ----------- Render Loop ----------
    void display(){
        int display_w, display_h;
        glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h);
        // Rendering objs Loop
        ClearAllBufferColor();
        glBindVertexArray(VAO);
        shader.use();
        glDrawElementsInstanced(GL_TRIANGLES,6, GL_UNSIGNED_INT, nullptr, INSTANCE_COUNT);  // 6 is our indices num
        //glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT, 0);
    }

    2,General Method With glMapBuffer()

    这里直接映射glBufferData(),首先设置数据为NULL,但是要在glBufferData()开辟正常的大小。然后glMapBuffer(),最后再glUnmapBuffer()

    这个方法按道理效率更高点,省的new()出来这些内存,后面还要析构这些内存

    这个方法也不用改材质

    #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_DrawPostPocessingQuad.h"
    #include "ALG_DrawPlane.h"
    #include "ALG_DepthShadow.h"
    #include "ALG_OGLHelper.h"
    #include "ALG_DirLight.h"
    #include "ALG_SceneLocation.h"
    #include <cmath>
    #include "ALG_Random.h"
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    #include "ALG_FPS.h"
    
    using namespace AlgebraMaster;
    const unsigned int SRC_WIDTH = 900;
    const unsigned int SRC_HEIGHT = 900;
    
    
    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;
    
    
    static FrameWindow *frameWindow ;
    
    // per geometry verticles
    static float verticles[] = {
            -0.1f,  0.1f,
            -0.1f, -0.1f,
    
            0.1f, -0.1f,
            0.1f,  0.1f
    };
    static GLuint indices[] = {
            0 , 1 , 2,
            0 , 2 , 3
    };
    
    static GLuint VAO,VBO,EBO;
    static GLuint INST_COLOR_BUFFER, INST_MAT_BUFFER;
    static int INSTANCE_COUNT = 300;
    static LoadShader shader;
    void init(){
    
        glViewport(0,0,SRC_WIDTH,SRC_HEIGHT);
        if(!CheckExtension("GL_ARB_shading_language_include")){
            cout << "---------------ERROR:: SHADER DO NOT SUPPORT INCLUDE SHADER----------------------------------
    ";
        }
        AddCommonShaderFile("shaders/common/material_interface.glsl");
        AddCommonShaderFile("shaders/common/light_interface.glsl");
        AddCommonShaderFile("shaders/common/shadow.glsl");
        AddCommonShaderFile("shaders/common/utils.glsl");
        AddCommonShaderFile("shaders/common/postprocess.glsl");
    
        shader.load("shaders/advanced_instance/part2/surface.vert","shaders/advanced_instance/part2/surface.frag");
    
        camera = new GLFWCamera;
        camera->pos.y = 0.5f;
        camera->pos.z = 2.0f;
    
        // Create VAO
        glCreateVertexArrays(1,&VAO);
        glBindVertexArray(VAO);
    
        // set vertex buffer object data
        glCreateBuffers(1,&VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER,sizeof(verticles),verticles,GL_STATIC_DRAW );
        // local position
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);  // stride = 0 , offset = void* 0
    
    
    
    
    
        // create element buffer object
        glCreateBuffers(1,&EBO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices), indices, GL_STATIC_DRAW);
    
    
    
    
        // create color [-1,1] , but in this default buffer not support HDR , just ignore it
        glCreateBuffers(1,&INST_COLOR_BUFFER);
        glBindBuffer(GL_ARRAY_BUFFER,INST_COLOR_BUFFER);
        glBufferData(GL_ARRAY_BUFFER,sizeof(glm::vec3) * INSTANCE_COUNT, nullptr,GL_STATIC_DRAW);  // default we set null data
    
        glm::vec3 *colors = (glm::vec3*) glMapBuffer(GL_ARRAY_BUFFER,GL_WRITE_ONLY);
        // construct instance color data
        RandomN1P1 r(INSTANCE_COUNT, 1321);
        RandomN1P1 g(INSTANCE_COUNT, 321321);
        RandomN1P1 b(INSTANCE_COUNT,231);
        //glm::vec3 *colors = new glm::vec3[INSTANCE_COUNT];
        for(int i=0;i<INSTANCE_COUNT;i++){
            colors[i].r = r[i];
            colors[i].g = g[i];
            colors[i].b = b[i];
        }
        glUnmapBuffer(GL_ARRAY_BUFFER); // !IMPORTANT unmap the GL_ARRAY_BUFFER
        // send color instance to shader
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0);
        glVertexAttribDivisor(1, 1);
    
    
        glCreateBuffers(1,&INST_MAT_BUFFER);
        glBindBuffer(GL_ARRAY_BUFFER,INST_MAT_BUFFER);
        glBufferData(GL_ARRAY_BUFFER,sizeof(glm::mat4) * INSTANCE_COUNT, nullptr,GL_STATIC_DRAW);
        glm::mat4 *mats = (glm::mat4*) glMapBuffer(GL_ARRAY_BUFFER,GL_WRITE_ONLY);
        // generator [-1,1] range
        RandomN1P1 xPosSet(INSTANCE_COUNT, 2312);
        RandomN1P1 yPosSet(INSTANCE_COUNT, 42);
        RandomN1P1 zPosSet(INSTANCE_COUNT, 31513);
        RandomN1P1 rotAmount(INSTANCE_COUNT,523);
        Random01 scaleAmount(INSTANCE_COUNT,3213);
        for(int i=0;i<INSTANCE_COUNT;i++){
            // new translate
            glm::mat4 model(1.0f);
            model = glm::translate(model,glm::vec3(xPosSet[i], yPosSet[i], zPosSet[i]  )  );
            // new rot
            glm::mat4 rot(1.0f);
            rot = glm::rotate(rot,glm::radians(rotAmount[i]*360) , glm::vec3(0.0,0.0,1.0));
            // R S T order
            glm::mat4 scale(1.0f);
            scale = glm::scale(  scale,glm::vec3(scaleAmount[i])  );
            mats[i] = model * scale * rot  ;
        }
        glUnmapBuffer(GL_ARRAY_BUFFER);
    
        // first column
        glEnableVertexAttribArray(2);
        glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)0);
        // second column
        glEnableVertexAttribArray(3);
        glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(sizeof(glm::vec4)));
        // third column
        glEnableVertexAttribArray(4);
        glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(2 * sizeof(glm::vec4)));
        // fourth column
        glEnableVertexAttribArray(5);
        glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(3 * sizeof(glm::vec4)));
        glVertexAttribDivisor(2, 1);
        glVertexAttribDivisor(3, 1);
        glVertexAttribDivisor(4, 1);
        glVertexAttribDivisor(5, 1);
    
    }
    
    
    
    // ----------- Render Loop ----------
    void display(){
    
        int display_w, display_h;
        glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h);
    
        // Rendering objs Loop
        ClearAllBufferColor();
    
        glBindVertexArray(VAO);
        shader.use();
        glDrawElementsInstanced(GL_TRIANGLES,6, GL_UNSIGNED_INT, nullptr, INSTANCE_COUNT);  // 6 is our indices num
        //glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT, 0);
    }
    
    
    int main()
    {
    
        glfwInit();
        frameWindow = new FrameWindow(SRC_WIDTH,SRC_HEIGHT);
        glfwSetFramebufferSizeCallback(frameWindow->getWindow(), framebuffer_size_callback);
        glfwSetCursorPosCallback(frameWindow->getWindow(),mouse_callback);
        glfwSetScrollCallback(frameWindow->getWindow(), scroll_callback);
    
        init();
    
    
        //double lastTime  = glfwGetTime();
        //double targetFps = 60.0f;
    
        FPSLimit fpsLimit;
        fpsLimit.targetFps = 60.02f;
        FPSGet fpsGet;
    
    
    
        //double previousTime = glfwGetTime();
        //double frameCount = 0;
    
        // RENDER--------------
        // draw as wireframe
        //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        while(!glfwWindowShouldClose(frameWindow->getWindow())){
    
    
            processInput(frameWindow->getWindow());
            fpsLimit.limitFPS();
            fpsGet.updateFPS(frameWindow->getWindow());
    
    
    
            display();
            // Rendering objs Loop
    
    
            int display_w, display_h;
            glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h);
            glViewport(0, 0, display_w, display_h);
    
    
            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);
    }
    View Code

    3,TBO 

    1,路线就是先创建GL_TEXTURE_BUFFER类型的buffer, 而不是GL_ARRAY_BUFFER,

    2,创建纹理

    3,然后用glTexBuffer()绑定纹理 到 Buffer上。在GLSL材质中一定是用贴图单元的方式加载。

    glCreateBuffers(1,&INST_COLOR_BUFFER);
    glBindBuffer(GL_TEXTURE_BUFFER,INST_COLOR_BUFFER);
    glBufferData(GL_TEXTURE_BUFFER, sizeof(glm::vec4)* INSTANCE_COUNT, &colors[0], GL_STATIC_DRAW);
    glTexBuffer(GL_TEXTURE_BUFFER,GL_RGBA32F,INST_COLOR_BUFFER);

    所有的代码:

    #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_DrawPostPocessingQuad.h"
    #include "ALG_DrawPlane.h"
    #include "ALG_DepthShadow.h"
    #include "ALG_OGLHelper.h"
    #include "ALG_DirLight.h"
    #include "ALG_SceneLocation.h"
    #include <cmath>
    #include "ALG_Random.h"
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    #include "ALG_FPS.h"
    
    using namespace AlgebraMaster;
    const unsigned int SRC_WIDTH = 900;
    const unsigned int SRC_HEIGHT = 900;
    
    
    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;
    
    
    static FrameWindow *frameWindow ;
    
    // per geometry verticles
    static float verticles[] = {
            -0.1f,  0.1f,
            -0.1f, -0.1f,
    
            0.1f, -0.1f,
            0.1f,  0.1f
    };
    static GLuint indices[] = {
            0 , 1 , 2,
            0 , 2 , 3
    };
    
    static GLuint VAO,VBO,EBO;
    
    static const int INSTANCE_COUNT = 300;
    
    
    static GLuint INST_COLOR_TBO, INST_MAT_TBO;
    static GLuint INST_COLOR_BUFFER, INST_MAT_BUFFER;
    static LoadShader shader;
    void init(){
    
        glViewport(0,0,SRC_WIDTH,SRC_HEIGHT);
        if(!CheckExtension("GL_ARB_shading_language_include")){
            cout << "---------------ERROR:: SHADER DO NOT SUPPORT INCLUDE SHADER----------------------------------
    ";
        }
        AddCommonShaderFile("shaders/common/material_interface.glsl");
        AddCommonShaderFile("shaders/common/light_interface.glsl");
        AddCommonShaderFile("shaders/common/shadow.glsl");
        AddCommonShaderFile("shaders/common/utils.glsl");
        AddCommonShaderFile("shaders/common/postprocess.glsl");
    
        shader.load("shaders/advanced_instance/part2/surface.vert","shaders/advanced_instance/part2/surface.frag");
    
        camera = new GLFWCamera;
        camera->pos.y = 0.5f;
        camera->pos.z = 2.0f;
    
        // Create VAO
        glCreateVertexArrays(1,&VAO);
        glBindVertexArray(VAO);
    
        // set vertex buffer object data
        glCreateBuffers(1,&VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER,sizeof(verticles),verticles,GL_STATIC_DRAW );
        // local position
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);  // stride = 0 , offset = void* 0
    
    
    
    
    
        // create element buffer object
        glCreateBuffers(1,&EBO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices), indices, GL_STATIC_DRAW);
    
    
    
    
        // -----------create color [-1,1] , but in this default buffer not support HDR , just ignore it-----------------------
    
        //glGenTextures(1, &INST_COLOR_TBO);
        glCreateTextures(GL_TEXTURE_BUFFER , 1 , &INST_COLOR_TBO);
        glBindTexture(GL_TEXTURE_BUFFER, INST_COLOR_TBO);
    
        glm::vec4 colors[INSTANCE_COUNT];
        // construct instance color data
        RandomN1P1 r(INSTANCE_COUNT, 1321);
        RandomN1P1 g(INSTANCE_COUNT, 321321);
        RandomN1P1 b(INSTANCE_COUNT,231);
        //glm::vec3 *colors = new glm::vec3[INSTANCE_COUNT];
        for(int i=0;i<INSTANCE_COUNT;i++){
            colors[i] = glm::vec4(r[i],g[i],b[i],1);
        }
        glCreateBuffers(1,&INST_COLOR_BUFFER);
        glBindBuffer(GL_TEXTURE_BUFFER,INST_COLOR_BUFFER);
        glBufferData(GL_TEXTURE_BUFFER, sizeof(glm::vec4)* INSTANCE_COUNT, &colors[0], GL_STATIC_DRAW);
        glTexBuffer(GL_TEXTURE_BUFFER,GL_RGBA32F,INST_COLOR_BUFFER);
    
    
    
    // -------------------- Matrix Buffer with a texture ----------------------------
        glGenTextures(1,&INST_MAT_TBO);
        glBindTexture(GL_TEXTURE_BUFFER, INST_MAT_TBO);
    
        glm::mat4 mats[INSTANCE_COUNT];
        // generator [-1,1] range
        RandomN1P1 xPosSet(INSTANCE_COUNT, 2312);
        RandomN1P1 yPosSet(INSTANCE_COUNT, 42);
        RandomN1P1 zPosSet(INSTANCE_COUNT, 31513);
        RandomN1P1 rotAmount(INSTANCE_COUNT,523);
        Random01 scaleAmount(INSTANCE_COUNT,3213);
        for(int i=0;i<INSTANCE_COUNT;i++){
            // new translate
            glm::mat4 model(1.0f);
            model = glm::translate(model,glm::vec3(xPosSet[i], yPosSet[i], zPosSet[i]  )  );
            // new rot
            glm::mat4 rot(1.0f);
            rot = glm::rotate(rot,glm::radians(rotAmount[i]*360) , glm::vec3(0.0,0.0,1.0));
            // R S T order
            glm::mat4 scale(1.0f);
            scale = glm::scale(  scale,glm::vec3(scaleAmount[i])  );
            mats[i] = model * scale * rot  ;
        }
    
        glCreateBuffers(1,&INST_MAT_BUFFER);
        glBindBuffer(GL_TEXTURE_BUFFER,INST_MAT_BUFFER);
        glBufferData(GL_TEXTURE_BUFFER,sizeof(glm::mat4) * INSTANCE_COUNT, &mats[0],GL_STATIC_DRAW);
        glTexBuffer(GL_TEXTURE_BUFFER,GL_RGBA32F,INST_MAT_BUFFER);
    
        glActiveTexture(GL_TEXTURE0);
    
        shader.use();
        shader.setInt("color_tbo",0);
        shader.setInt("model_matrix_tbo",1);
    
    }
    
    
    
    // ----------- Render Loop ----------
    void display(){
    
        int display_w, display_h;
        glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h);
    
        // Rendering objs Loop
        ClearAllBufferColor();
        
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_BUFFER, INST_COLOR_TBO);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_BUFFER, INST_MAT_TBO);
        
        shader.use();
        glBindVertexArray(VAO);
        glDrawElementsInstanced(GL_TRIANGLES,6, GL_UNSIGNED_INT, nullptr, INSTANCE_COUNT);  // 6 is our indices num
        //glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT, 0);
    }
    
    
    int main()
    {
    
        glfwInit();
        frameWindow = new FrameWindow(SRC_WIDTH,SRC_HEIGHT);
        glfwSetFramebufferSizeCallback(frameWindow->getWindow(), framebuffer_size_callback);
        glfwSetCursorPosCallback(frameWindow->getWindow(),mouse_callback);
        glfwSetScrollCallback(frameWindow->getWindow(), scroll_callback);
    
        init();
    
    
        //double lastTime  = glfwGetTime();
        //double targetFps = 60.0f;
    
        FPSLimit fpsLimit;
        fpsLimit.targetFps = 60.02f;
        FPSGet fpsGet;
    
    
    
        //double previousTime = glfwGetTime();
        //double frameCount = 0;
    
        // RENDER--------------
        // draw as wireframe
        //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        while(!glfwWindowShouldClose(frameWindow->getWindow())){
    
    
            processInput(frameWindow->getWindow());
            fpsLimit.limitFPS();
            fpsGet.updateFPS(frameWindow->getWindow());
    
    
    
            display();
            // Rendering objs Loop
    
    
            int display_w, display_h;
            glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h);
            glViewport(0, 0, display_w, display_h);
    
    
            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
    #version 450 core
    layout ( location = 0 ) in vec2 vPosition; // c++ pos
    
    uniform samplerBuffer color_tbo;
    uniform samplerBuffer model_matrix_tbo;
    
    out VERTEX{
        vec3 color;
    }vertex;
    
    void main(){
    
        // instance color
        vec4 inst_color = texelFetch(color_tbo, gl_InstanceID);
        //vec4 inst_color = vec4(1.0,0.0,0,1);
        // get instance matrix column
        vec4 col1 = texelFetch(model_matrix_tbo, gl_InstanceID * 4);
        vec4 col2 = texelFetch(model_matrix_tbo, gl_InstanceID * 4 + 1);
        vec4 col3 = texelFetch(model_matrix_tbo, gl_InstanceID * 4 + 2);
        vec4 col4 = texelFetch(model_matrix_tbo, gl_InstanceID * 4 + 3);
        mat4 model_matrix = mat4(col1,col2,col3,col4);
        gl_Position =  model_matrix * vec4(vPosition.x, vPosition.y, 0.0, 1.0);
        vertex.color = inst_color.rgb;
    }

    3, TBO with glMapBuffer()

    只修改了mat方法,同样按照这个逻辑用于修改colors

    #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_DrawPostPocessingQuad.h"
    #include "ALG_DrawPlane.h"
    #include "ALG_DepthShadow.h"
    #include "ALG_OGLHelper.h"
    #include "ALG_DirLight.h"
    #include "ALG_SceneLocation.h"
    #include <cmath>
    #include "ALG_Random.h"
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    #include "ALG_FPS.h"
    
    using namespace AlgebraMaster;
    const unsigned int SRC_WIDTH = 900;
    const unsigned int SRC_HEIGHT = 900;
    
    
    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;
    
    
    static FrameWindow *frameWindow ;
    
    // per geometry verticles
    static float verticles[] = {
            -0.1f,  0.1f,
            -0.1f, -0.1f,
    
            0.1f, -0.1f,
            0.1f,  0.1f
    };
    static GLuint indices[] = {
            0 , 1 , 2,
            0 , 2 , 3
    };
    
    static GLuint VAO,VBO,EBO;
    
    static const int INSTANCE_COUNT = 300;
    
    
    static GLuint INST_COLOR_TBO, INST_MAT_TBO;
    static GLuint INST_COLOR_BUFFER, INST_MAT_BUFFER;
    static LoadShader shader;
    void init(){
    
        glViewport(0,0,SRC_WIDTH,SRC_HEIGHT);
        if(!CheckExtension("GL_ARB_shading_language_include")){
            cout << "---------------ERROR:: SHADER DO NOT SUPPORT INCLUDE SHADER----------------------------------
    ";
        }
        AddCommonShaderFile("shaders/common/material_interface.glsl");
        AddCommonShaderFile("shaders/common/light_interface.glsl");
        AddCommonShaderFile("shaders/common/shadow.glsl");
        AddCommonShaderFile("shaders/common/utils.glsl");
        AddCommonShaderFile("shaders/common/postprocess.glsl");
    
        shader.load("shaders/advanced_instance/part2/surface.vert","shaders/advanced_instance/part2/surface.frag");
    
        camera = new GLFWCamera;
        camera->pos.y = 0.5f;
        camera->pos.z = 2.0f;
    
        // Create VAO
        glCreateVertexArrays(1,&VAO);
        glBindVertexArray(VAO);
    
        // set vertex buffer object data
        glCreateBuffers(1,&VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER,sizeof(verticles),verticles,GL_STATIC_DRAW );
        // local position
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);  // stride = 0 , offset = void* 0
    
    
    
    
    
        // create element buffer object
        glCreateBuffers(1,&EBO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices), indices, GL_STATIC_DRAW);
    
    
    
    
        // -----------create color [-1,1] , but in this default buffer not support HDR , just ignore it-----------------------
    
        //glGenTextures(1, &INST_COLOR_TBO);
        glCreateTextures(GL_TEXTURE_BUFFER , 1 , &INST_COLOR_TBO);
        glBindTexture(GL_TEXTURE_BUFFER, INST_COLOR_TBO);
    
        glm::vec4 colors[INSTANCE_COUNT];
        // construct instance color data
        RandomN1P1 r(INSTANCE_COUNT, 1321);
        RandomN1P1 g(INSTANCE_COUNT, 321321);
        RandomN1P1 b(INSTANCE_COUNT,231);
        //glm::vec3 *colors = new glm::vec3[INSTANCE_COUNT];
        for(int i=0;i<INSTANCE_COUNT;i++){
            colors[i] = glm::vec4(r[i],g[i],b[i],1);
        }
        glCreateBuffers(1,&INST_COLOR_BUFFER);
        glBindBuffer(GL_TEXTURE_BUFFER,INST_COLOR_BUFFER);
        glBufferData(GL_TEXTURE_BUFFER, sizeof(glm::vec4)* INSTANCE_COUNT, &colors[0], GL_STATIC_DRAW);
        glTexBuffer(GL_TEXTURE_BUFFER,GL_RGBA32F,INST_COLOR_BUFFER);
    
    
    
    // -------------------- Matrix Buffer with a texture ----------------------------
        glGenTextures(1,&INST_MAT_TBO);
        glBindTexture(GL_TEXTURE_BUFFER, INST_MAT_TBO);
    
    
        glCreateBuffers(1,&INST_MAT_BUFFER);
        glBindBuffer(GL_TEXTURE_BUFFER,INST_MAT_BUFFER);
        glBufferData(GL_TEXTURE_BUFFER,sizeof(glm::mat4) * INSTANCE_COUNT, nullptr,GL_STATIC_DRAW);
    
        glm::mat4 *mats = (glm::mat4*)glMapBuffer(GL_TEXTURE_BUFFER, GL_WRITE_ONLY);
        // generator [-1,1] range
        RandomN1P1 xPosSet(INSTANCE_COUNT, 2312);
        RandomN1P1 yPosSet(INSTANCE_COUNT, 42);
        RandomN1P1 zPosSet(INSTANCE_COUNT, 31513);
        RandomN1P1 rotAmount(INSTANCE_COUNT,523);
        Random01 scaleAmount(INSTANCE_COUNT,3213);
        for(int i=0;i<INSTANCE_COUNT;i++){
            // new translate
            glm::mat4 model(1.0f);
            model = glm::translate(model,glm::vec3(xPosSet[i], yPosSet[i], zPosSet[i]  )  );
            // new rot
            glm::mat4 rot(1.0f);
            rot = glm::rotate(rot,glm::radians(rotAmount[i]*360) , glm::vec3(0.0,0.0,1.0));
            // R S T order
            glm::mat4 scale(1.0f);
            scale = glm::scale(  scale,glm::vec3(scaleAmount[i])  );
            mats[i] = model * scale * rot  ;
        }
        glUnmapBuffer(GL_TEXTURE_BUFFER);
        glTexBuffer(GL_TEXTURE_BUFFER,GL_RGBA32F,INST_MAT_BUFFER);
        glActiveTexture(GL_TEXTURE0);
    
        shader.use();
        shader.setInt("color_tbo",0);
        shader.setInt("model_matrix_tbo",1);
    
    }
    
    
    
    // ----------- Render Loop ----------
    void display(){
    
        int display_w, display_h;
        glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h);
    
        // Rendering objs Loop
        ClearAllBufferColor();
    
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_BUFFER, INST_COLOR_TBO);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_BUFFER, INST_MAT_TBO);
    
        shader.use();
        glBindVertexArray(VAO);
        glDrawElementsInstanced(GL_TRIANGLES,6, GL_UNSIGNED_INT, nullptr, INSTANCE_COUNT);  // 6 is our indices num
        //glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT, 0);
    }
    
    
    int main()
    {
    
        glfwInit();
        frameWindow = new FrameWindow(SRC_WIDTH,SRC_HEIGHT);
        glfwSetFramebufferSizeCallback(frameWindow->getWindow(), framebuffer_size_callback);
        glfwSetCursorPosCallback(frameWindow->getWindow(),mouse_callback);
        glfwSetScrollCallback(frameWindow->getWindow(), scroll_callback);
    
        init();
    
    
        //double lastTime  = glfwGetTime();
        //double targetFps = 60.0f;
    
        FPSLimit fpsLimit;
        fpsLimit.targetFps = 60.02f;
        FPSGet fpsGet;
    
    
    
        //double previousTime = glfwGetTime();
        //double frameCount = 0;
    
        // RENDER--------------
        // draw as wireframe
        //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        while(!glfwWindowShouldClose(frameWindow->getWindow())){
    
    
            processInput(frameWindow->getWindow());
            fpsLimit.limitFPS();
            fpsGet.updateFPS(frameWindow->getWindow());
    
    
    
            display();
            // Rendering objs Loop
    
    
            int display_w, display_h;
            glfwGetFramebufferSize(frameWindow->getWindow(), &display_w, &display_h);
            glViewport(0, 0, display_w, display_h);
    
    
            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);
    }
    View Code
  • 相关阅读:
    gulp教程、gulp-less安装
    vue学习总结
    javascript数组去重
    【操作系统】操作系统高频面试考点总结
    【面经系列】一线互联网大厂前端面试技巧深入浅出总结
    【编程题与分析题】Javascript 之继承的多种实现方式和优缺点总结
    【计算机网络】TCP基础知识详解
    【操作系统】操作系统面试基础知识点总结
    【数据结构与算法】数据结构基础知识总结(面试考点)
    【前端知识体系-JS相关】JS-Web-API总结
  • 原文地址:https://www.cnblogs.com/gearslogy/p/12924486.html
Copyright © 2011-2022 走看看