opengl VAO 中记录了哪些设置?

2lpgd968  于 2023-08-04  发布在  其他
关注(0)|答案(1)|浏览(113)

在下面的代码示例中,我设置了一个 VAO ,尝试在其中绑定顶点着色器的参数:第一个参数是顶点坐标,第二个参数是颜色,它是固定的,我尝试使用glVertexAttrib3f来设置。在设置 VAO 之后(设置由glBindVertexArray(0)结束),我再次调用glVertexAttrib3f,希望这不会影响我在VAO中设置的值。
代码编译为:

$ g++ vao.cc -lglfw -lGLEW -lGL

字符串
vao.cc的内容:

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include <iostream>

const unsigned int SCR_WIDTH = 600;
const unsigned int SCR_HEIGHT = 600;

GLuint compileShader (const char * VertexShaderCode, const char * FragmentShaderCode)
{
  int len;
  GLint res = GL_FALSE;
  GLuint VertexShaderID = glCreateShader (GL_VERTEX_SHADER);
  GLuint FragmentShaderID = glCreateShader (GL_FRAGMENT_SHADER);

  // Compile Vertex Shader
  glShaderSource (VertexShaderID, 1, &VertexShaderCode , NULL);
  glCompileShader (VertexShaderID);

  glGetShaderiv (VertexShaderID, GL_COMPILE_STATUS, &res);
  glGetShaderiv (VertexShaderID, GL_INFO_LOG_LENGTH, &len);
  if (len > 0)
    {
      char mess[len+1];
      glGetShaderInfoLog (VertexShaderID, len, NULL, &mess[0]);
      printf ("%s\n", mess);
    }

  // Compile Fragment Shader
  glShaderSource (FragmentShaderID, 1, &FragmentShaderCode , NULL);
  glCompileShader (FragmentShaderID);

  glGetShaderiv (FragmentShaderID, GL_COMPILE_STATUS, &res);
  glGetShaderiv (FragmentShaderID, GL_INFO_LOG_LENGTH, &len);
  if (len > 0)
    {
      char mess[len+1];
      glGetShaderInfoLog (FragmentShaderID, len, NULL, &mess[0]);
      printf ("%s\n", mess);
    }

  // Link the program
  GLuint ProgramID = glCreateProgram ();
  glAttachShader (ProgramID, VertexShaderID);
  glAttachShader (ProgramID, FragmentShaderID);
  glLinkProgram (ProgramID);
  
  // Check the program
  glGetProgramiv (ProgramID, GL_LINK_STATUS, &res);
  glGetProgramiv (ProgramID, GL_INFO_LOG_LENGTH, &len);
  if (len > 0)
    {
      char mess[len+1];
      glGetProgramInfoLog (ProgramID, len, NULL, &mess[0]);
      printf ("%s\n", mess);
    }
  
  
  glDetachShader (ProgramID, VertexShaderID);
  glDetachShader (ProgramID, FragmentShaderID);
  
  glDeleteShader (VertexShaderID);
  glDeleteShader (FragmentShaderID);
  
  return ProgramID;
}

int main ()
{
    glfwInit ();
    glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    GLFWwindow* window = glfwCreateWindow (SCR_WIDTH, SCR_HEIGHT, "", NULL, NULL);

    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate ();
        return -1;
    }
    glfwMakeContextCurrent (window);

    glewExperimental = true; 
    if (glewInit () != GLEW_OK)
      {
        fprintf (stderr, "Failed to initialize GLEW\n");
        glfwTerminate ();
        return -1;
      }

    glEnable (GL_DEPTH_TEST);

    GLuint shader = compileShader 
(R"CODE(
#version 460 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aCol;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

out vec3 col;

void main ()
{
  gl_Position = projection * view * model * vec4 (aPos, 1.0);
  col = aCol;
}
)CODE",
 R"CODE(
#version 460 core
out vec4 FragColor;

in vec3 col;

void main ()
{
    FragColor = vec4 (col, 1.0);
}
)CODE");

    glUseProgram (shader);

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

    unsigned int VBO, VAO;
    glGenVertexArrays (1, &VAO);
    glGenBuffers (1, &VBO);

    glBindVertexArray (VAO);

    glBindBuffer (GL_ARRAY_BUFFER, VBO);
    glBufferData (GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW);

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

    glDisableVertexAttribArray (1);
    glVertexAttrib3f (1, 0.0f, 1.0f, 0.0f);

    glBindVertexArray (0);

    glDisableVertexAttribArray (1);
    glVertexAttrib3f (1, 1.0f, 0.0f, 0.0f);

    while (! glfwWindowShouldClose (window))
    {
        if (glfwGetKey (window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose (window, true);

        glClearColor (0.1f, 0.1f, 0.1f, 1.0f);
        glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
        glUseProgram (shader);

        glm::mat4 projection = glm::perspective (glm::radians (20.0f), 1.0f / 1.0f, 0.1f, 100.0f);
        glm::mat4 view       = glm::lookAt (glm::vec3 (6.0f,0.0f,0.0f), glm::vec3 (0,0,0), glm::vec3 (0,0,1));
        glUniformMatrix4fv (glGetUniformLocation (shader, "projection"), 1, GL_FALSE, &projection[0][0]);
        glUniformMatrix4fv (glGetUniformLocation (shader, "view"), 1, GL_FALSE, &view[0][0]);

        glm::mat4 model = glm::mat4(1.0f);
        glUniformMatrix4fv (glGetUniformLocation (shader, "model"), 1, GL_FALSE, &model[0][0]);

        glBindVertexArray (VAO);

        glDrawArrays (GL_TRIANGLES, 0, 36);

        glfwSwapBuffers (window);
        glfwPollEvents ();
    }

    glDeleteVertexArrays (1, &VAO);
    glDeleteBuffers (1, &VBO);

    glfwTerminate ();
    return 0;
}


因此,我希望看到一个绿色方块,但我得到一个红色方块,这意味着我认为存储在 VAO 中的颜色值已被替换。
问题:

  • 是否预期由glVertexAttrib* 设置的值不存储在VAO中?
  • 更一般地,什么存储在VAO中,什么不存储在VAO中?
oxalkeyp

oxalkeyp1#

正如名称“Vertex Array Object”所示,VAO仅存储与vertex arrays 相关的值。指定属性数据的旧的非数组方式(您不应该使用)是全局状态,而不是VAO的一部分。

相关问题