繁体   English   中英

OpenGL 使用索引批量渲染 [重复]

[英]OpenGL Batch Rendering with indices [duplicate]

我正在尝试使用批处理渲染系统一次渲染多个纹理。 但是我遇到了索引问题。 我在 Windows 上使用 OpenGL 4.6。 我创建了一个较小的程序来复制我的原始程序而不添加纹理,以查看四边形是否可以正确渲染。 使用下面的代码,我得到了这个(只有两个四边形渲染):

但是当我将第三个四边形的索引从“2.0f”更改为“1.0f”时,如下所示:

864.0f, 392.0f, 0.0f, 1.0f, 1.0f,
928.0f, 392.0f, 1.0f, 1.0f, 1.0f,
864.0f, 458.0f, 0.0f, 0.0f, 1.0f,
928.0f, 458.0f, 1.0f, 0.0f, 1.0f

我能够渲染所有三个四边形: 在此处输入图像描述

我对这一切还是陌生的,所以我很感激任何建议/帮助。

主.cpp:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "Shader.h"

#include <iostream>

using namespace std;

int main() {
    // Initialise GLFW
    if (!glfwInit()) {
        cerr << "Failed to initialize GLFW" << endl;
        return 0;
    }

    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow *window {glfwCreateWindow(1280, 720, "2D GAME", NULL, NULL)};
    if (window == NULL) {
        cerr << "Failed to open GLFW window." << endl;
        glfwTerminate();
        return 0;
    }
    glfwMakeContextCurrent(window);

    glewExperimental = true;
    if (glewInit() != GLEW_OK) { // Initialize Glew
        cerr << "Failed to initialize GLEW" << endl;
        glfwTerminate();
        return 0;
    }
    // Settings
    cout << "OpenGL Version: " << glGetString(GL_VERSION) << endl;
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    //Vertex Array
    GLuint VAO;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
    // Vertex Buffers
    GLuint VBOs[2];
    glGenBuffers(2, VBOs);

    GLfloat vbData[60] {
    //    X        Y     U     V    Index
        512.0f, 392.0f, 0.0f, 1.0f, 0.0f,
        576.0f, 392.0f, 1.0f, 1.0f, 0.0f,
        512.0f, 458.0f, 0.0f, 0.0f, 0.0f,
        576.0f, 458.0f, 1.0f, 0.0f, 0.0f,

        736.0f, 392.0f, 0.0f, 1.0f, 1.0f,
        800.0f, 392.0f, 1.0f, 1.0f, 1.0f,
        736.0f, 458.0f, 0.0f, 0.0f, 1.0f,
        800.0f, 458.0f, 1.0f, 0.0f, 1.0f,

        864.0f, 392.0f, 0.0f, 1.0f, 1.0f,
        928.0f, 392.0f, 1.0f, 1.0f, 1.0f,
        864.0f, 458.0f, 0.0f, 0.0f, 1.0f,
        928.0f, 458.0f, 1.0f, 0.0f, 1.0f
    };
    glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
    glBufferData(GL_ARRAY_BUFFER, 60 * sizeof(GLfloat), vbData, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0); // Position
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), nullptr);
    glEnableVertexAttribArray(1); // Texture Coords
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *) (2 * sizeof(GLfloat)));
    glEnableVertexAttribArray(2); // Texture Index
    glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *) (4 * sizeof(GLfloat)));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBOs[1]);
    GLuint ibData[18] {
        0, 1, 2, 1, 2, 3,
        4, 5, 6, 5, 6, 7,
        8, 9, 10, 9, 10, 11
    };
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 18 * sizeof(GLuint), ibData, GL_STATIC_DRAW);
    // MVP
    glm::mat4 Projection {glm::ortho(0.0f, 1280.0f, 0.0f, 720.0f, 0.0f, 1.0f)};
    glm::mat4 View {glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 0))};

    glm::vec3 translationA {glm::vec3(0, 0, 0)};
    glm::mat4 Model = glm::translate(glm::mat4(1.0f), translationA); // Model Matrix (Using Identity Matrix - Origin)
    glm::mat4 mvp = Projection * View * Model; // ModelViewProjection Matrix (MVP) *Matrix multiplication is the other way around*
    // Shader
    Shader shader {"shader/vertex.vert", "shader/fragment.frag"};
    shader.bind();
    shader.setUniformMat4f("MVP", mvp);
    int sampler[] {0, 1, 2};
    shader.setUniform1iv("v_Textures", sampler, 3);
    // MAIN LOOP //
    while (glfwWindowShouldClose(window) == 0) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glDrawElements(GL_TRIANGLES, 18, GL_UNSIGNED_INT, nullptr);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwTerminate();
}

着色器.cpp:

#include <GL/glew.h>
#include "Shader.h"

#include <fstream>
#include <sstream>
#include <iostream>

using namespace std;

Shader::Shader(const std::string &vertFilePath, const std::string &fragFilePath) 
    : vertFilePath{vertFilePath}, fragFilePath{fragFilePath}, ID{0} {
        ID = LoadShaders(vertFilePath, fragFilePath); // Create & Compile program from shaders
}

Shader::~Shader() {
    glDeleteProgram(ID);
}

unsigned int Shader::compileShader(const unsigned int type, const string &filePath) {
    unsigned int shaderID {glCreateShader(type)};
    std::string shaderCode;
    std::ifstream shaderStream(filePath);
    // Check if file is valid
    if (shaderStream.is_open()) {
        std::stringstream sstr;
        sstr << shaderStream.rdbuf();
        shaderCode = sstr.str();
        shaderStream.close();
    } else {
        cout << "Failed to open shader file: " << filePath << endl;
        glDeleteShader(shaderID);
        return 0;
    }
    const char *src = shaderCode.c_str();
    // Compile Shader
    cout << "Compiling shader: " << filePath << endl;
    glShaderSource(shaderID, 1, &src, nullptr);
    glCompileShader(shaderID);
    // Check Shader
    int result;
    glGetShaderiv(shaderID, GL_COMPILE_STATUS, &result);

    if (result == GL_FALSE) {
        int infoLogLength;
        glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
        char *shaderErrorMessage {(char *) alloca(infoLogLength * sizeof(char))};
        glGetShaderInfoLog(shaderID, infoLogLength, &infoLogLength, shaderErrorMessage);
        cout << "Failed to compile shader: " << filePath << '\n' << shaderErrorMessage << endl;
        glDeleteShader(shaderID);
        return 0;
    }
    return shaderID;
}

unsigned int Shader::LoadShaders(const string &vertexFilePath, const string &fragmentFilePath) {
    // Create the shaders
    unsigned int vertexShader {compileShader(GL_VERTEX_SHADER, vertexFilePath)};
    unsigned int fragmentShader {compileShader(GL_FRAGMENT_SHADER, fragmentFilePath)};
    // Link the program
    unsigned int programID = glCreateProgram();
    glAttachShader(programID, vertexShader);
    glAttachShader(programID, fragmentShader);
    glLinkProgram(programID);
    glValidateProgram(programID);
    cout << "Program Linked!" << endl;
    // Detach and Delete Shaders
    glDetachShader(programID, vertexShader);
    glDetachShader(programID, fragmentShader);
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    // Check program
    int result;
    glGetProgramiv(programID, GL_LINK_STATUS, &result);

    if (result == GL_FALSE) {
        int infoLogLength;
        glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength);
        char *programErrorMessage {(char *) alloca(infoLogLength * sizeof(char))};
        glGetProgramInfoLog(programID, infoLogLength, &infoLogLength, programErrorMessage);
        cout << "Failed to compile program\n" << programErrorMessage << endl;
        glDeleteProgram(programID);
        return 0;
    }
    return programID;
}

void Shader::bind() const {
    glUseProgram(ID);
}

void Shader::unbind() const {
    glUseProgram(0);
}

void Shader::setUniform1iv(const std::string &name, const int *array, int size) const {
    glUniform1iv(getUniformLocation(name), size, array);
}

void Shader::setUniformMat4f(const std::string &name, const glm::mat4 &matrix) const {
    glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, &matrix[0][0]);
}

unsigned int Shader::getUniformLocation(const std::string &name) const {
    if (uniformLocationCache.find(name) != uniformLocationCache.end())
        return uniformLocationCache[name];

    int location {glGetUniformLocation(ID, name.c_str())};
    if (location == -1)
        std::cout << "Warning: uniform " << name << " doesn't exist!" << std::endl;

    uniformLocationCache[name] = location;
    return location;
}

顶点着色器:

#version 460 core

layout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoord;
layout(location = 2) in float texIndex;

out vec2 v_TexCoord;
out float v_TexIndex;

uniform mat4 MVP;

void main() {
    gl_Position = MVP * vec4(position, 1.0);
    v_TexCoord = texCoord;
    v_TexIndex = texIndex;
}

片段着色器:

#version 460 core

in vec2 v_TexCoord;
in float v_TexIndex;

uniform sampler2D v_Textures[2];

void main() {
    gl_FragColor = texture2D(v_Textures[int(v_TexIndex)], v_TexCoord);
}

我正在尝试使用批处理渲染系统一次渲染多个纹理。 但是我遇到了索引问题。 我在 Windows 上使用 OpenGL 4.6。 我创建了一个较小的程序来复制我的原始程序而不添加纹理,以查看四边形是否可以正确渲染。 使用下面的代码,我得到了这个(只有两个四边形渲染):

但是当我将第三个四边形的索引从“2.0f”更改为“1.0f”时,如下所示:

864.0f, 392.0f, 0.0f, 1.0f, 1.0f,
928.0f, 392.0f, 1.0f, 1.0f, 1.0f,
864.0f, 458.0f, 0.0f, 0.0f, 1.0f,
928.0f, 458.0f, 1.0f, 0.0f, 1.0f

我能够渲染所有三个四边形: 在此处输入图像描述

我对这一切还是陌生的,所以我很感激任何建议/帮助。

主.cpp:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "Shader.h"

#include <iostream>

using namespace std;

int main() {
    // Initialise GLFW
    if (!glfwInit()) {
        cerr << "Failed to initialize GLFW" << endl;
        return 0;
    }

    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow *window {glfwCreateWindow(1280, 720, "2D GAME", NULL, NULL)};
    if (window == NULL) {
        cerr << "Failed to open GLFW window." << endl;
        glfwTerminate();
        return 0;
    }
    glfwMakeContextCurrent(window);

    glewExperimental = true;
    if (glewInit() != GLEW_OK) { // Initialize Glew
        cerr << "Failed to initialize GLEW" << endl;
        glfwTerminate();
        return 0;
    }
    // Settings
    cout << "OpenGL Version: " << glGetString(GL_VERSION) << endl;
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    //Vertex Array
    GLuint VAO;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
    // Vertex Buffers
    GLuint VBOs[2];
    glGenBuffers(2, VBOs);

    GLfloat vbData[60] {
    //    X        Y     U     V    Index
        512.0f, 392.0f, 0.0f, 1.0f, 0.0f,
        576.0f, 392.0f, 1.0f, 1.0f, 0.0f,
        512.0f, 458.0f, 0.0f, 0.0f, 0.0f,
        576.0f, 458.0f, 1.0f, 0.0f, 0.0f,

        736.0f, 392.0f, 0.0f, 1.0f, 1.0f,
        800.0f, 392.0f, 1.0f, 1.0f, 1.0f,
        736.0f, 458.0f, 0.0f, 0.0f, 1.0f,
        800.0f, 458.0f, 1.0f, 0.0f, 1.0f,

        864.0f, 392.0f, 0.0f, 1.0f, 1.0f,
        928.0f, 392.0f, 1.0f, 1.0f, 1.0f,
        864.0f, 458.0f, 0.0f, 0.0f, 1.0f,
        928.0f, 458.0f, 1.0f, 0.0f, 1.0f
    };
    glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
    glBufferData(GL_ARRAY_BUFFER, 60 * sizeof(GLfloat), vbData, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0); // Position
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), nullptr);
    glEnableVertexAttribArray(1); // Texture Coords
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *) (2 * sizeof(GLfloat)));
    glEnableVertexAttribArray(2); // Texture Index
    glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *) (4 * sizeof(GLfloat)));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBOs[1]);
    GLuint ibData[18] {
        0, 1, 2, 1, 2, 3,
        4, 5, 6, 5, 6, 7,
        8, 9, 10, 9, 10, 11
    };
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 18 * sizeof(GLuint), ibData, GL_STATIC_DRAW);
    // MVP
    glm::mat4 Projection {glm::ortho(0.0f, 1280.0f, 0.0f, 720.0f, 0.0f, 1.0f)};
    glm::mat4 View {glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 0))};

    glm::vec3 translationA {glm::vec3(0, 0, 0)};
    glm::mat4 Model = glm::translate(glm::mat4(1.0f), translationA); // Model Matrix (Using Identity Matrix - Origin)
    glm::mat4 mvp = Projection * View * Model; // ModelViewProjection Matrix (MVP) *Matrix multiplication is the other way around*
    // Shader
    Shader shader {"shader/vertex.vert", "shader/fragment.frag"};
    shader.bind();
    shader.setUniformMat4f("MVP", mvp);
    int sampler[] {0, 1, 2};
    shader.setUniform1iv("v_Textures", sampler, 3);
    // MAIN LOOP //
    while (glfwWindowShouldClose(window) == 0) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glDrawElements(GL_TRIANGLES, 18, GL_UNSIGNED_INT, nullptr);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwTerminate();
}

着色器.cpp:

#include <GL/glew.h>
#include "Shader.h"

#include <fstream>
#include <sstream>
#include <iostream>

using namespace std;

Shader::Shader(const std::string &vertFilePath, const std::string &fragFilePath) 
    : vertFilePath{vertFilePath}, fragFilePath{fragFilePath}, ID{0} {
        ID = LoadShaders(vertFilePath, fragFilePath); // Create & Compile program from shaders
}

Shader::~Shader() {
    glDeleteProgram(ID);
}

unsigned int Shader::compileShader(const unsigned int type, const string &filePath) {
    unsigned int shaderID {glCreateShader(type)};
    std::string shaderCode;
    std::ifstream shaderStream(filePath);
    // Check if file is valid
    if (shaderStream.is_open()) {
        std::stringstream sstr;
        sstr << shaderStream.rdbuf();
        shaderCode = sstr.str();
        shaderStream.close();
    } else {
        cout << "Failed to open shader file: " << filePath << endl;
        glDeleteShader(shaderID);
        return 0;
    }
    const char *src = shaderCode.c_str();
    // Compile Shader
    cout << "Compiling shader: " << filePath << endl;
    glShaderSource(shaderID, 1, &src, nullptr);
    glCompileShader(shaderID);
    // Check Shader
    int result;
    glGetShaderiv(shaderID, GL_COMPILE_STATUS, &result);

    if (result == GL_FALSE) {
        int infoLogLength;
        glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
        char *shaderErrorMessage {(char *) alloca(infoLogLength * sizeof(char))};
        glGetShaderInfoLog(shaderID, infoLogLength, &infoLogLength, shaderErrorMessage);
        cout << "Failed to compile shader: " << filePath << '\n' << shaderErrorMessage << endl;
        glDeleteShader(shaderID);
        return 0;
    }
    return shaderID;
}

unsigned int Shader::LoadShaders(const string &vertexFilePath, const string &fragmentFilePath) {
    // Create the shaders
    unsigned int vertexShader {compileShader(GL_VERTEX_SHADER, vertexFilePath)};
    unsigned int fragmentShader {compileShader(GL_FRAGMENT_SHADER, fragmentFilePath)};
    // Link the program
    unsigned int programID = glCreateProgram();
    glAttachShader(programID, vertexShader);
    glAttachShader(programID, fragmentShader);
    glLinkProgram(programID);
    glValidateProgram(programID);
    cout << "Program Linked!" << endl;
    // Detach and Delete Shaders
    glDetachShader(programID, vertexShader);
    glDetachShader(programID, fragmentShader);
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    // Check program
    int result;
    glGetProgramiv(programID, GL_LINK_STATUS, &result);

    if (result == GL_FALSE) {
        int infoLogLength;
        glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength);
        char *programErrorMessage {(char *) alloca(infoLogLength * sizeof(char))};
        glGetProgramInfoLog(programID, infoLogLength, &infoLogLength, programErrorMessage);
        cout << "Failed to compile program\n" << programErrorMessage << endl;
        glDeleteProgram(programID);
        return 0;
    }
    return programID;
}

void Shader::bind() const {
    glUseProgram(ID);
}

void Shader::unbind() const {
    glUseProgram(0);
}

void Shader::setUniform1iv(const std::string &name, const int *array, int size) const {
    glUniform1iv(getUniformLocation(name), size, array);
}

void Shader::setUniformMat4f(const std::string &name, const glm::mat4 &matrix) const {
    glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, &matrix[0][0]);
}

unsigned int Shader::getUniformLocation(const std::string &name) const {
    if (uniformLocationCache.find(name) != uniformLocationCache.end())
        return uniformLocationCache[name];

    int location {glGetUniformLocation(ID, name.c_str())};
    if (location == -1)
        std::cout << "Warning: uniform " << name << " doesn't exist!" << std::endl;

    uniformLocationCache[name] = location;
    return location;
}

顶点着色器:

#version 460 core

layout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoord;
layout(location = 2) in float texIndex;

out vec2 v_TexCoord;
out float v_TexIndex;

uniform mat4 MVP;

void main() {
    gl_Position = MVP * vec4(position, 1.0);
    v_TexCoord = texCoord;
    v_TexIndex = texIndex;
}

片段着色器:

#version 460 core

in vec2 v_TexCoord;
in float v_TexIndex;

uniform sampler2D v_Textures[2];

void main() {
    gl_FragColor = texture2D(v_Textures[int(v_TexIndex)], v_TexCoord);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM