0

我已经编写了一个非常基本的测试设置来使用 glfw/glad 渲染一个四边形。

我会用它在窗口中间绘制一个黑色四边形。

#include <iostream>

#include <array>
#include <cinttypes>

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

using uint32 = std::uint32_t;
using gl_shader_id = GLuint;

gl_shader_id get_shader() {
  constexpr auto vertex_shader_source = R"(
    #version 460 core

    layout (location = 0) in vec3 position;

    void main() {
      gl_Position = vec4(position.x, position.y, position.z, 1.0);
    }
  )";

  constexpr auto fragment_shader_source = R"(
    #version 460 core

    out vec4 color;

    void main() {
      color = vec4(0.0, 0.0, 0.0, 1.0f);
    }
  )";

  const auto vertex_shader = glCreateShader(GL_VERTEX_SHADER);
  const auto fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);

  auto success = 0;

  glShaderSource(vertex_shader, 1, &vertex_shader_source, nullptr);
  glCompileShader(vertex_shader);

  glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);

  if (!success) {
    auto info_log = std::string{};
    info_log.reserve(512);

    glGetShaderInfoLog(vertex_shader, 512, nullptr, info_log.data());

    std::cout << info_log << '\n';

    assert(false); // Vertex shader compilation failed 
  }

  glShaderSource(fragment_shader, 1, &fragment_shader_source, nullptr);
  glCompileShader(fragment_shader);

  if (!success) {
    auto info_log = std::string{};
    info_log.reserve(512);

    glGetShaderInfoLog(fragment_shader, 512, nullptr, info_log.data());

    std::cout << info_log << '\n';

    assert(false); // Vertex shader compilation failed 
  }

  const auto shader_program = glCreateProgram();

  glAttachShader(shader_program, vertex_shader);
  glAttachShader(shader_program, fragment_shader);

  glLinkProgram(shader_program);

  glDetachShader(shader_program, vertex_shader);
  glDetachShader(shader_program, fragment_shader);

  glDeleteShader(vertex_shader);
  glDeleteShader(fragment_shader);

  return shader_program;
}

int main() {

  glfwInit();

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

  auto handle = glfwCreateWindow(800, 600, "Hello World", nullptr, nullptr);

  glfwMakeContextCurrent(handle);

  gladLoadGLLoader(reinterpret_cast<GLADloadproc>(glfwGetProcAddress));

  const auto shader_id = get_shader();

  const auto vertices = std::array<glm::vec3, 4>{
    glm::vec3{ -0.5f, -0.5f, 0.0f },
    glm::vec3{ -0.5f,  0.5f, 0.0f },
    glm::vec3{  0.5f, -0.5f, 0.0f },
    glm::vec3{  0.5f,  0.5f, 0.0f }
  };

  const auto indices = std::array<uint32, 6>{
    0, 1, 2,
    1, 3, 2
  };

  auto vertex_array = 0u;
  auto vertex_buffer = 0u;
  auto index_buffer = 0u;

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

  glGenBuffers(1, &vertex_buffer);
  glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
  glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);

  glEnableVertexArrayAttrib(vertex_array, 0);
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), nullptr);

  glGenBuffers(1, &index_buffer);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint32), indices.data(), GL_STATIC_DRAW);

  glBindBuffer(GL_ARRAY_BUFFER, 0);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

  glBindVertexArray(0);

  while (!glfwWindowShouldClose(handle)) {
    glfwPollEvents();

    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glBindVertexArray(vertex_array);
    glUseProgram(shader_id);

    glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, nullptr);

    glUseProgram(0);
    glBindVertexArray(0);

    glfwSwapBuffers(handle);
  }

  glfwDestroyWindow(handle);
  glfwTerminate();

  return 0;
}

程序和着色器代码编译时没有错误/警告。

当我执行程序时,我得到了以正确颜色清除的窗口。

但是我用顶点和索引指定的四边形没有显示出来。

4

1 回答 1

0

经过一番折腾,我想通了。

对于任何遇到这个问题的人。

在取消绑定顶点缓冲区和索引缓冲区之前,您必须取消绑定顶点数组。

否则,存储在顶点数组中的绑定将被设置为 0,并且无法绘制任何内容

于 2021-11-18T10:07:02.947 回答