glDrawElements 什么都不做。 Opengl

问题描述 投票:0回答:0

有这个简单的代码:

#include <iostream>
#include <memory>

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>

#include <test/main/shader.hpp>

class Foo {
public:
    void OnAttach() {
        glfwInit();
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        window_ = glfwCreateWindow(960, 540, "test", nullptr, nullptr);
        if (window_ == nullptr) {
            std::cerr << "failed to create GLFW window\n";
        }
        glfwMakeContextCurrent(window_);
        glfwSetFramebufferSizeCallback(window_, [](GLFWwindow *_, int width, int height) {
            glViewport(0, 0, width, height);
        });
        if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) {
            std::cerr << "failed to initialize GLAD\n";
        }
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        shader_ = std::make_shared<Shader>("assets/GLSL/test.glsl");

        glGenVertexArrays(1, &quad_va_);
        glBindVertexArray(quad_va_);

        float vertices[] = {
                -0.5f, -0.5f, 0.0f,
                0.5f, -0.5f, 0.0f,
                0.5f, 0.5f, 0.0f,
                -0.5f, 0.5f, 0.0f
        };

        glGenBuffers(1, &quad_vb_);
        glBindBuffer(GL_ARRAY_BUFFER, quad_vb_);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, nullptr);
        glEnableVertexAttribArray(0);

        uint32_t indices[] = {0, 1, 2, 2, 3, 0};
        glGenBuffers(1, &quad_ib_);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_ib_);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    }

    void OnUpdate() {
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        shader_->Bind();
        shader_->SetVec3("u_color", square_color_);

        glBindVertexArray(quad_va_);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
    }

    GLFWwindow *GetWindow() const {
        return window_;
    }

private:
    GLFWwindow *window_;
    std::shared_ptr<Shader> shader_;
    uint32_t quad_va_, quad_vb_, quad_ib_;
    glm::vec4 square_color_ = {0.8f, 0.2f, 0.3f, 1.0f};
};

void Run(Foo *foo) {
    foo->OnAttach();

    while (!glfwWindowShouldClose(foo->GetWindow())) {
        foo->OnUpdate();
        glfwSwapBuffers(foo->GetWindow());
        glfwPollEvents();
    }
}

int main() {
    Run(new Foo);
}

和着色器:

#type vertex
#version 330 core

layout(location = 0) in vec3 a_pos;

uniform mat4 u_view_projection;

void main()
{
        gl_Position = vec4(a_pos, 1.0);
}

#type fragment
#version 330 core

out vec4 color;

uniform vec4 u_color;

void main()
{
        color = u_color;
}

未显示的 Shader 类简单地解析包含顶点和片段部分的着色器文件。并在帧循环中简单地设置制服。我只看到空窗口,没有正方形。但一切似乎都已注定。出了什么问题?

PS:为了完整起见,这里是着色器类:

标题

#ifndef TEST_SHADER_HPP
#define TEST_SHADER_HPP

#include <string>

#include <glm/glm.hpp>

class Shader {
public:
    explicit Shader(const std::string& filepath);

    void Bind() const;

    void SetInt(const std::string& name, int value) const;

    void SetFloat(const std::string& name, float value) const;

    void SetVec3(const std::string& name, const glm::vec3& vec) const;

    void SetVec4(const std::string& name, const glm::vec4& vec) const;

    void SetMat4(const std::string& name, const glm::mat4& mat) const;

private:
    static void CheckCompileErrors(uint32_t shader_id, const std::string& type, const std::string& filepath);

    uint32_t id_;
};

#endif //TEST_SHADER_HP

来源

#include <test/main/shader.hpp>

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

#include <glad/glad.h>

void Shader::CheckCompileErrors(uint32_t shader_id, const std::string& type, const std::string& filepath) {
    int success;
    char infoLog[1024];
    if (type != "PROGRAM") {
        glGetShaderiv(shader_id, GL_COMPILE_STATUS, &success);
        if (!success) {
            glGetShaderInfoLog(shader_id, 1024, nullptr, infoLog);
            std::cout << "ERROR::SHADER::COMPILATION_ERROR of type: " << type << "\n" << infoLog << "filepath: "
                      << filepath;
        }
    } else {
        glGetProgramiv(shader_id, GL_LINK_STATUS, &success);
        if (!success) {
            glGetProgramInfoLog(shader_id, 1024, nullptr, infoLog);
            std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "filepath: "
                      << filepath;
        }
    }
}

Shader::Shader(const std::string& filepath) {
    // 1. divide vertex and fragment part
    enum class ShaderType {
        NONE = -1, VERTEX = 0, FRAGMENT = 1
    };
    std::ifstream stream(filepath);
    std::string line;
    std::stringstream ss[2];
    ShaderType type = ShaderType::NONE;
    while (getline(stream, line)) {
        if (line.find("#type") != std::string::npos) {
            if (line.find("vertex") != std::string::npos) {
                type = ShaderType::VERTEX;
            } else if (line.find("fragment") != std::string::npos) {
                type = ShaderType::FRAGMENT;
            } else {
                std::cout << "Unknown shader: " << line << '\n';
            }
        } else {
            if (type == ShaderType::NONE) {
                std::cout << "No shader defined" << '\n';
            } else {
                ss[(int) type] << line << '\n';
            }
        }
    }
    std::string vertex_code = ss[(int) ShaderType::VERTEX].str();
    std::string fragment_code = ss[(int) ShaderType::FRAGMENT].str();

    // 2. convert, compile and link sources to shader program
    // 2.1 convert string to c str
    const char *vertex_str = vertex_code.c_str();
    const char *fragment_str = fragment_code.c_str();
    // 2.2.1 vertex shader
    uint32_t vertex_id = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_id, 1, &vertex_str, nullptr);
    glCompileShader(vertex_id);
    CheckCompileErrors(vertex_id, "VERTEX", filepath);
    // 2.2.2 fragment shader
    uint32_t fragment_id = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment_id, 1, &fragment_str, nullptr);
    glCompileShader(fragment_id);
    CheckCompileErrors(fragment_id, "FRAGMENT", filepath);
    // 2.3 shader program
    id_ = glCreateProgram();
    glAttachShader(id_, vertex_id);
    glAttachShader(id_, fragment_id);
    glLinkProgram(id_);
    CheckCompileErrors(id_, "PROGRAM", filepath);
    // 2.4 delete the shaders as they're linked into program and no longer necessary
    glDeleteShader(vertex_id);
    glDeleteShader(fragment_id);
}

void Shader::Bind() const {
    glUseProgram(id_);
}

void Shader::SetInt(const std::string& name, int value) const {
    glUniform1i(glGetUniformLocation(id_, name.c_str()), value);
}

void Shader::SetFloat(const std::string& name, float value) const {
    glUniform1f(glGetUniformLocation(id_, name.c_str()), value);
}

void Shader::SetVec4(const std::string& name, const glm::vec4& vec) const {
    glUniform4f(glGetUniformLocation(id_, name.c_str()), vec.x, vec.y, vec.z, vec.w);
}

void Shader::SetVec3(const std::string& name, const glm::vec3& vec) const {
    glUniform3f(glGetUniformLocation(id_, name.c_str()), vec.x, vec.y, vec.z);
}

void Shader::SetMat4(const std::string& name, const glm::mat4& mat) const {
    glUniformMatrix4fv(glGetUniformLocation(id_, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
c++ opengl glfw
© www.soinside.com 2019 - 2024. All rights reserved.