AlgebraMaster

Modern C++ 创造非凡 . 改变世界

导航

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----------------------------------\n";
    }
    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 << "\n";
            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----------------------------------\n";
    }
    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----------------------------------\n";
    }
    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----------------------------------\n";
    }
    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

 

posted on 2020-05-20 16:41  gearslogy  阅读(275)  评论(0编辑  收藏  举报