OpenGL实例化渲染绘制一个三角形 [英] OpenGL Instanced Rendering drawing one triangle

查看:73
本文介绍了OpenGL实例化渲染绘制一个三角形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建体素引擎,为此,我必须创建成千上万的体素,我希望可以使用实例渲染.但是,该图是非常出乎意料的.我主要遵循的是

但是,使用实例渲染时...

另一个角度...

我正试图大块渲染体素,所以这是我的代码:

voxel.hpp

  #pragma一次#include< stdio.h>#include< iostream>#include< vector>#include< glad/glad.h>#include< GLFW/glfw3.h>#define GLM_ENABLE_EXPERIMENTAL#include< glm/glm.hpp>#include< glm/gtc/matrix_transform.hpp>使用std :: vector;使用glm :: mat4;使用glm :: vec3;Voxel类{浮动半径布尔可见;vec3 centerPoint;上市:未签名的int VBO,VAO,EBO;Voxel(vec3中心,浮点大小,bool vis =假,bool single =假);无效setMVP(mat4 mvp);void setVisible(bool v);void generateElement();}; 

voxel.cpp

  #include"voxel.hpp";Voxel :: Voxel(vec3中心,浮动大小,bool vis,bool single){可见=可见;centerPoint = center;半径=大小;generateElement();}无效的Voxel :: setVisible(bool v){可见= v;}无效的Voxel :: generateElement(){//这次我们需要所有8个顶点和一个长度为36的索引数组vec3 maxV(centerPoint.x +半径,centerPoint.y +半径,centerPoint.z +半径);vec3 minV(centerPoint.x-半径,centerPoint.y-半径,centerPoint.z-半径);浮点顶点[24] = {maxV.x,maxV.y,maxV.z,maxV.x,maxV.y,minV.z,maxV.x,minV.y,minV.z,maxV.x,minV.y,maxV.z,minV.x,minV.y,maxV.z,minV.x,maxV.y,maxV.z,minV.x,maxV.y,minV.z,minV.x,minV.y,minV.z,};无符号整数索引[36] = {0,2,1,//maxV.x0、2、3,2,6,1,//minV.z2 6 72,4,3,//minV.y2 4 74,6,5,//minV.x4 6 71,5,0,//maxV.y1 5 60,4,3,//maxV.z0、4、5};//对于单个渲染,此处将包含着色器代码glGenVertexArrays(1,& VAO);glGenBuffers(1,& VBO);glGenBuffers(1,& EBO);glBindVertexArray(VAO);//将数据加载到顶点缓冲区glBindBuffer(GL_ARRAY_BUFFER,VBO);//glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),& vertices [0],GL_STATIC_DRAW);glBufferData(GL_ARRAY_BUFFER,sizeof(顶点),顶点,GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);//glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),& indices [0],GL_STATIC_DRAW);glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(索引),索引,GL_STATIC_DRAW);////设置顶点属性指针////顶点位置glEnableVertexAttribArray(0);//glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(vec3),(void *)0);glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3 * sizeof(float),(void *)0);//glBindVertexArray(VAO);//设置矩阵的属性指针(4次vec4)glEnableVertexAttribArray(3);glVertexAttribPointer(3,4,GL_FLOAT,GL_FALSE,sizeof(glm :: mat4),(void *)0);glEnableVertexAttribArray(4);glVertexAttribPointer(4,4,GL_FLOAT,GL_FALSE,sizeof(glm :: mat4),(void *)(sizeof(glm :: vec4))));glEnableVertexAttribArray(5);glVertexAttribPointer(5,4,GL_FLOAT,GL_FALSE,sizeof(glm :: mat4),(void *)(sizeof(glm :: vec4)* 2)));;glEnableVertexAttribArray(6);glVertexAttribPointer(6,4,GL_FLOAT,GL_FALSE,sizeof(glm :: mat4),(void *)(sizeof(glm :: vec4)* 3)));glVertexAttribDivisor(3,1);glVertexAttribDivisor(4,1);glVertexAttribDivisor(5,1);glVertexAttribDivisor(6,1);glBindBuffer(GL_ARRAY_BUFFER,0);glBindVertexArray(0);} 

chunk.hpp

  #pragma一次#include< stdio.h>#include< iostream>#include< vector>#include< algorithm>#include"voxel.hpp"#define GLM_ENABLE_EXPERIMENTAL#include< glm/glm.hpp>#include< glm/gtc/matrix_transform.hpp>使用std :: vector;使用glm :: mat4;使用glm :: vec3;块{vec3 centerPoint;int voxelNum;int shaderProgram;未签名的int VBO,EBO,VAO;mat4 VP;上市:块(vec3中心,浮点半径,整数rinv);无效setVP(mat4 vp);void setVisible(bool v);无效draw();}; 

chunk.cpp

  #include"chunk.hpp"#include< iostream>#include< vector>#include< algorithm>#include< stdlib.h>#define GLM_ENABLE_EXPERIMENTAL#include< glm/glm.hpp>#include< glm/gtc/matrix_transform.hpp>使用std :: vector;使用glm :: mat4;使用glm :: vec3;Chunk :: Chunk(vec3 centerPoint,float半径,int rinv){vec3 endPoint(centerPoint.x-半径,centerPoint.y-半径,centerPoint.z-半径);浮点distVox = 2 *半径/rinv;voxelNum = pow(rinv,3);mat4 * modelMatrices =新的mat4 [voxelNum];srand(glfwGetTime());//初始化随机种子for(int z = 0; z< rinv; z ++){for(int y = 0; y< rinv; y ++){for(int x = 0; x< rinv; x ++){glm :: mat4模型= glm :: mat4(1.0f);模型=翻译(模型,vec3(endPoint.x +(x + 0.5)* distVox,endPoint.y +(y + 0.5)* distVox,endPoint.z +(z + 0.5)* distVox));模型=比例(模型,vec3(半径));int索引= x + y * rinv + z * pow(rinv,2);modelMatrices [index] =模型;}}}const char * vertexShaderSource ="#version 330 core \ n";在vec3 aPos中的布局(位置= 0); \ n"在mat4 aInstanceMatrix中的布局(位置= 3); \ n"统一的mat4 VP; \ n";"void main()\ n";"{\ n""gl_Position = VP * aInstanceMatrix * vec4(aPos,1.0); \ n;"} \ n \ 0&;const char * fragmentShaderSource ="#version 330 core \ n";"out vec4 FragColor; \ n";均匀的vec3颜色; \ n";"void main()\ n";"{\ n""FragColor = vec4(color,1.0f); \ n;"} \ n \ 0&;//顶点着色器int vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader,1,& vertexShaderSource,NULL);glCompileShader(vertexShader);//检查着色器编译错误成功字符infoLog [512];glGetShaderiv(vertexShader,GL_COMPILE_STATUS,& success);如果(!成功){glGetShaderInfoLog(vertexShader,512,NULL,infoLog);std :: cout<<"ERROR :: SHADER :: VERTEX :: COMPILATION_FAILED \ n"<<infoLog<<std :: endl;}//片段着色器intfragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader,1,& fragmentShaderSource,NULL);glCompileShader(fragmentShader);//检查着色器编译错误glGetShaderiv(fragmentShader,GL_COMPILE_STATUS,& success);如果(!成功){glGetShaderInfoLog(fragmentShader,512,NULL,infoLog);std :: cout<<"ERROR :: SHADER :: FRAGMENT :: COMPILATION_FAILED \ n"<<infoLog<<std :: endl;}//链接着色器shaderProgram = glCreateProgram();glAttachShader(shaderProgram,vertexShader);glAttachShader(shaderProgram,fragmentShader);glLinkProgram(shaderProgram);//检查链接错误glGetProgramiv(shaderProgram,GL_LINK_STATUS,& success);如果(!成功){glGetProgramInfoLog(shaderProgram,512,NULL,infoLog);std :: cout<<"ERROR :: SHADER :: PROGRAM :: LINKING_FAILED \ n"<<infoLog<<std :: endl;}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);glGenBuffers(1,& VBO);glBindBuffer(GL_ARRAY_BUFFER,VBO);glBufferData(GL_ARRAY_BUFFER,voxelNum * sizeof(mat4),& modelMatrices [0],GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER,0);glBindVertexArray(0);}无效Chunk :: setVP(mat4 vp){VP = vp;}无效Chunk :: draw(){glUseProgram(shaderProgram);glUniformMatrix4fv(glGetUniformLocation(shaderProgram,"VP"),1,GL_FALSE,& VP [0] [0]);体素eVox(vec3(0.0f),1.0f,true,false);glBindVertexArray(eVox.VAO);glDrawElementsInstanced(GL_TRIANGLES,36,GL_UNSIGNED_INT,0,voxelNum);glBindVertexArray(0);} 

main.cpp

  #include< iostream>使用命名空间std;#include"chunk.hpp"#include< GLFW/glfw3.h>#include< glm/glm.hpp>#include< glm/gtc/matrix_transform.hpp>使用名称空间glm;//全局变量GLFWwindow *窗口;const char * SCR_TITLE ="WORKINGPLANET";const int SCR_WIDTH = 500,SCR_HEIGHT = 500;浮点数x_rot = 0.0f;浮点y_rot = 0.0f;浮点y_rot_clamp = 89.999f;//计时浮点deltaTime = 0.0f;//当前帧和最后一帧之间的时间float lastFrame = 0.0f;void mouseCallback(GLFWwindow * window,int button,int action,int mods);vec3 X_AXIS = vec3(1.0f,0.0f,0.0f);vec3 Y_AXIS = vec3(0.0f,1.0f,0.0f);//主程序int main(){//构造函数代码if(!glfwInit()){cerr<<"错误!返回-1;}glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT,GL_TRUE);if(!(window = glfwCreateWindow(SCR_WIDTH,SCR_HEIGHT,SCR_TITLE,NULL,NULL))){cerr<<错误!GLFW窗口";glfwTerminate();返回-1;}glfwMakeContextCurrent(window);如果(!gladLoadGLLoader(((GLADloadproc)glfwGetProcAddress)){std :: cout<<无法初始化OpenGL上下文";<<std :: endl;返回-1;}大块(vec3(0.0f),0.5,2);mat4视图= mat4(1.0);vec3 cameraPos = glm :: vec3(0.0f,0.0f,4.0f);view = lookAt(cameraPos,vec3(0,0,0),vec3(0,1,0));//循环事件while(!glfwWindowShouldClose(window)){//每帧时间逻辑浮动currentFrame = glfwGetTime();deltaTime = currentFrame-lastFrame;lastFrame = currentFrame;glClearColor(1.0,1.0,1.0,1.0);glClear(GL_COLOR_BUFFER_BIT);//调整这些值以更改灵敏度float scale_x = 7.0f/SCR_WIDTH;float scale_y = 7.0f/SCR_HEIGHT;float rotSpeed = 350.0f;浮点数= scale_x * rotSpeed;如果(glfwGetKey(window,GLFW_KEY_W)== GLFW_PRESS){腐烂= scale_y *腐烂速度;如果(y_rot +腐烂> y_rot_clamp)rot = y_rot_clamp-y_rot;视图=旋转(视图,(浮点)弧度(旋转),X_AXIS);y_rot + =腐烂;}如果(glfwGetKey(window,GLFW_KEY_S)== GLFW_PRESS){腐烂= scale_y *腐烂速度;如果(y_rot-rot< -y_rot_clamp)腐烂= y_rot + y_rot_clamp;view = rotation(视图,(float)弧度(-rot),X_AXIS);y_rot-=腐烂;}如果(glfwGetKey(window,GLFW_KEY_A)== GLFW_PRESS){view = rotation(视图,(float)弧度(-rot),Y_AXIS);x_rot-=腐烂;}如果(glfwGetKey(window,GLFW_KEY_D)== GLFW_PRESS){view = rotation(视图,(float)弧度(rot),Y_AXIS);x_rot + =腐烂;}如果(glfwGetKey(window,GLFW_KEY_R)== GLFW_PRESS){view = lookAt(cameraPos,vec3(0,0,0),vec3(0,1,0));x_rot = 0.0f;y_rot = 0.0f;}mat4投影=透视图(弧度(45.0f),(浮动)SCR_WIDTH/(浮动)SCR_HEIGHT,0.1f,100.0f);//渲染chunk.setVP(projection * view);chunk.draw();glfwSwapBuffers(window);glfwPollEvents();}glfwTerminate();返回0;} 

我完全被困住了.添加更多体素不会改变实例化错误的外观.

有趣的是,在chunk.cpp中注释掉 glLinkProgram(shaderProgram); 会使此错误完全不同,该块显示为一个包含整个多维数据集的巨大体素.

解决方案

您的VBO设置没有任何意义.您可以在 Voxel :: generateElement()中将每个实例的转换矩阵设置为与几何使用相同的数据.

稍后,您将所有变换矩阵上载到单独的VBO中,但是属性指针仍指向几何VBO.您需要将实例化属性的属性设置移出 Voxel :: generateElement()并移入 Chunk :: Chunk()中,以便您可以告诉它使用该VBO作为模型矩阵的来源.

I'm trying to build a voxel engine, and to do this I have to create hundreds of thousands of voxels, and I was hoping I could use instanced rendering. However, the drawing is very unexpected. I'm primarily following the LearnOpenGL guide.

When rendering each voxel individually, the program works fine:

However, when using instanced rendering...

Another angle...

I'm trying to render the voxels in a big chunk, so this is what my code looks like:

voxel.hpp

#pragma once

#include <stdio.h>

#include <iostream>
#include <vector>

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

using std::vector;
using glm::mat4;
using glm::vec3;

class Voxel {
    float radius;
    bool visible;
    vec3 centerPoint;
public:
    unsigned int VBO, VAO, EBO;

    Voxel(vec3 center, float size, bool vis = false, bool single = false);
    void setMVP(mat4 mvp);
    void setVisible(bool v);
    void generateElement();
};

voxel.cpp

#include "voxel.hpp"

Voxel::Voxel(vec3 center, float size, bool vis, bool single) {
    visible = vis;
        
    centerPoint = center;
    radius = size;
    
    generateElement();
}

void Voxel::setVisible(bool v) {
    visible = v;
}

void Voxel::generateElement() {
    // this time we need all 8 vertices and a length 36 index array
    
    vec3 maxV(centerPoint.x + radius, centerPoint.y + radius, centerPoint.z + radius);
    vec3 minV(centerPoint.x - radius, centerPoint.y - radius, centerPoint.z - radius);
    
    float vertices[24] = {
        maxV.x, maxV.y, maxV.z,
        maxV.x, maxV.y, minV.z,
        maxV.x, minV.y, minV.z,
        maxV.x, minV.y, maxV.z,
        minV.x, minV.y, maxV.z,
        minV.x, maxV.y, maxV.z,
        minV.x, maxV.y, minV.z,
        minV.x, minV.y, minV.z,
    };
    
    unsigned int indices[36] = {
        0, 2, 1, // maxV.x
        0, 2, 3,

        2, 6, 1, // minV.z
        2, 6, 7,

        2, 4, 3, // minV.y
        2, 4, 7,

        4, 6, 5, // minV.x
        4, 6, 7,

        1, 5, 0, // maxV.y
        1, 5, 6,

        0, 4, 3, // maxV.z
        0, 4, 5,
    };
    
    // for individual rendering there would be shader code here
    
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    glBindVertexArray(VAO);
    // load data into vertex buffers
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
//    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
//    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), &indices[0], GL_STATIC_DRAW);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

//    // set the vertex attribute pointers
//    // vertex Positions
    glEnableVertexAttribArray(0);
//    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vec3), (void*)0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

//    glBindVertexArray(VAO);
    
    // set attribute pointers for matrix (4 times vec4)
    glEnableVertexAttribArray(3);
    glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)0);
    glEnableVertexAttribArray(4);
    glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(sizeof(glm::vec4)));
    glEnableVertexAttribArray(5);
    glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(sizeof(glm::vec4) * 2));
    glEnableVertexAttribArray(6);
    glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(sizeof(glm::vec4) * 3));

    glVertexAttribDivisor(3, 1);
    glVertexAttribDivisor(4, 1);
    glVertexAttribDivisor(5, 1);
    glVertexAttribDivisor(6, 1);

    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

chunk.hpp

#pragma once

#include <stdio.h>

#include <iostream>
#include <vector>

#include <algorithm>

#include "voxel.hpp"

#define GLM_ENABLE_EXPERIMENTAL
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

using std::vector;
using glm::mat4;
using glm::vec3;


class Chunk {
    vec3 centerPoint;
    int voxelNum;
    int shaderProgram;
    unsigned int VBO, EBO, VAO;
    mat4 VP;
public:
    Chunk(vec3 center, float radius, int rinv);
    void setVP(mat4 vp);
    void setVisible(bool v);
    void draw();
};

chunk.cpp

#include "chunk.hpp"

#include <iostream>
#include <vector>

#include <algorithm>

#include <stdlib.h>

#define GLM_ENABLE_EXPERIMENTAL
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
 
using std::vector;
using glm::mat4;
using glm::vec3;

Chunk::Chunk(vec3 centerPoint, float radius, int rinv) {
    vec3 endPoint(centerPoint.x - radius, centerPoint.y - radius, centerPoint.z - radius);
    
    float distVox = 2 * radius/rinv;
    
    voxelNum = pow(rinv, 3);
    
    mat4* modelMatrices = new mat4[voxelNum];
    srand(glfwGetTime()); // initialize random seed
    
    for (int z = 0; z < rinv; z++) {
        for (int y = 0; y < rinv; y++) {
            for (int x = 0; x < rinv; x++) {
                glm::mat4 model = glm::mat4(1.0f);
                
                model = translate(model, vec3(endPoint.x + (x + 0.5) * distVox, endPoint.y + (y + 0.5) * distVox, endPoint.z + (z + 0.5) * distVox));
                model = scale(model, vec3(radius));
                
                int index = x + y * rinv + z * pow(rinv, 2);
                modelMatrices[index] = model;
            }
        }
    }
    
    const char *vertexShaderSource = "#version 330 core\n"
        "layout (location = 0) in vec3 aPos;\n"
        "layout (location = 3) in mat4 aInstanceMatrix;\n"
        "uniform mat4 VP;\n"
        "void main()\n"
        "{\n"
        "    gl_Position = VP * aInstanceMatrix * vec4(aPos, 1.0);\n"
        "}\n\0";
    
    const char *fragmentShaderSource = "#version 330 core\n"
        "out vec4 FragColor;\n"
        "uniform vec3 color;\n"
        "void main()\n"
        "{\n"
        "   FragColor = vec4(color, 1.0f);\n"
        "}\n\0";

    // vertex shader
    int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    // check for shader compile errors
    int success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // fragment shader
    int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    // check for shader compile errors
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // link shaders
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    // check for linking errors
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, voxelNum * sizeof(mat4), &modelMatrices[0], GL_STATIC_DRAW);
    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

void Chunk::setVP(mat4 vp) {
    VP = vp;
}

void Chunk::draw() {
    glUseProgram(shaderProgram);
    glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "VP"), 1, GL_FALSE, &VP[0][0]);

    Voxel eVox(vec3(0.0f), 1.0f, true, false);

    glBindVertexArray(eVox.VAO);
    glDrawElementsInstanced(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0, voxelNum);
    glBindVertexArray(0);
}

main.cpp

#include <iostream>
using namespace std;

#include "chunk.hpp"

#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;

//Global Variables
GLFWwindow* window;
const char* SCR_TITLE = "WORKINGPLANET";
const int SCR_WIDTH = 500, SCR_HEIGHT = 500;

float x_rot = 0.0f;
float y_rot = 0.0f;

float y_rot_clamp = 89.999f;

// timing
float deltaTime = 0.0f; // time between current frame and last frame
float lastFrame = 0.0f;

void mouseCallback(GLFWwindow *window, int button, int action, int mods);

vec3 X_AXIS = vec3(1.0f, 0.0f, 0.0f);
vec3 Y_AXIS = vec3(0.0f, 1.0f, 0.0f);

//Main Program
int main()
{
    //Constructor Code
    if(!glfwInit())
    {
        cerr << "Error!!GLFW";
        return -1;
    }
    
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    
    if(!(window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, SCR_TITLE, NULL, NULL)))
    {
        cerr << "Error!!GLFW window";
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) {
        std::cout << "Failed to initialize OpenGL context" << std::endl;
        return -1;
    }
    
    Chunk chunk(vec3(0.0f), 0.5, 2);

    mat4 view = mat4(1.0);
    vec3 cameraPos = glm::vec3(0.0f, 0.0f, 4.0f);
    view = lookAt(cameraPos, vec3(0,0,0), vec3(0,1,0));
    //Loop Events
    while(!glfwWindowShouldClose(window))
    {
        // per-frame time logic
        float currentFrame = glfwGetTime();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;
        
        glClearColor(1.0, 1.0, 1.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);


        // Tweak these values to change the sensitivity
        float scale_x = 7.0f / SCR_WIDTH;
        float scale_y = 7.0f / SCR_HEIGHT;
        float rotSpeed = 350.0f;
        float rot = scale_x * rotSpeed;

        if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
            rot = scale_y * rotSpeed;
            if (y_rot + rot > y_rot_clamp)
                rot = y_rot_clamp - y_rot;

            view = rotate(view, (float)radians(rot), X_AXIS);
            y_rot += rot;
        } if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
            rot = scale_y * rotSpeed;
            if (y_rot - rot < -y_rot_clamp)
                rot = y_rot + y_rot_clamp;

            view = rotate(view, (float)radians(-rot), X_AXIS);
            y_rot -= rot;
        } if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
            view = rotate(view, (float)radians(-rot), Y_AXIS);
            x_rot -= rot;
        } if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
            view = rotate(view, (float)radians(rot), Y_AXIS);
            x_rot += rot;
        } if (glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS) {
            view = lookAt(cameraPos, vec3(0,0,0), vec3(0,1,0));
            x_rot = 0.0f;
            y_rot = 0.0f;
        }

        mat4 projection = perspective(radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);

        //Rendering
        chunk.setVP(projection * view);
        chunk.draw();
        
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;

}

I'm totally stuck. Adding more voxels doesn't change how the instanced bug looks.

Interestingly, commenting out the glLinkProgram(shaderProgram); in chunk.cpp makes this bug entirely different, with the chunk appearing as one huge voxel that emcompasses the entire cube.

解决方案

Your VBO setup doesn't make the slightest sense. You set up your per-instance transformation matrix to use the same data as your geometry in Voxel::generateElement().

You later upload all your transformation matrixes into a separate VBO, but the attribute pointers still point to the geometry VBO. YOu need to move the attribute setup for the instanced attribute out of Voxel::generateElement() and into Chunk::Chunk() so you can tell it to use that VBO as source for the model matrices.

这篇关于OpenGL实例化渲染绘制一个三角形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆