OpenGL 不显示简单的三角形

OpenGL does not display simple triangle

我正在尝试使用 OpenGL 来构建一些渲染软件,我过去已经使用过 OpenGL,但我找不到我的代码中哪里出错了。所以我实施了:

这是我的网格 class 函数和构造函数初始化和显示 :

Mesh::Mesh(char* meshSource)
{

//Creation d'un triangle pour quelques debug...
struct Vertex v0;
struct Vertex v1;
struct Vertex v2;
//Position local
v0.coord = vec3(-1.0f,-1.0f,0.0f);
v1.coord = vec3(1.0f,-1.0f,0.0f);
v2.coord = vec3(0.0f,1.0f,0.0f);
//Coouleur des points
v0.color = vec3(1.0,0.0,0.0);
v1.color = vec3(0.0,1.0,0.0);
v2.color = vec3(0.0,0.0,1.0);
//normals des points
v0.normal = vec3(0.0,0.0,-1.0);
v1.normal = vec3(0.0,0.0,-1.0);
v2.normal = vec3(0.0,0.0,-1.0);

Vertices.push_back(v0);
Vertices.push_back(v1);
Vertices.push_back(v2);

//sert a la premiere initialisation...
_ready = false;

}


void Mesh::init(Shader *_shader)
{

  glGenVertexArrays(1,&_vao);
  glGenBuffers(1,&_vbo);
  checkGLError();
  //bind des caracteristiques du mesh...
  glBindVertexArray(_vao);
  glBindBuffer(GL_ARRAY_BUFFER,_vbo);
  checkGLError();
  //On donne nos données au VBO.
  glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * Vertices.size(), Vertices.data(), GL_STATIC_DRAW);
  checkGLError();

  int vertex_loc = _shader->getAttribLocation("V_position");
  std::cout << "vertex_loc = " << vertex_loc << std::endl;
  if(vertex_loc>=0)
  {
      glEnableVertexAttribArray(vertex_loc);
      glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
  }

  int color_loc = _shader->getAttribLocation("V_color");
  std::cout << "color_loc = " << color_loc << std::endl;
  if(color_loc>=0)
  {
      glEnableVertexAttribArray(color_loc);
      glVertexAttribPointer(color_loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)sizeof(vec3));
  }

  int normal_loc = _shader->getAttribLocation("V_normal");
  std::cout << "normal_loc = " << normal_loc << std::endl;
  if(normal_loc>=0)
  {
      glEnableVertexAttribArray(normal_loc);
      glVertexAttribPointer(normal_loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(2*sizeof(vec3)));
  }

  if(vertex_loc>=0)
      glDisableVertexAttribArray(vertex_loc);
  if(color_loc>=0)
      glDisableVertexAttribArray(color_loc);
  if(normal_loc>=0)
      glDisableVertexAttribArray(normal_loc);

      glBindVertexArray(0);

  this->_ready = true;

}


void Mesh::draw(Shader *_shader)
{

    if(!_ready)
    {
      init(_shader);
      std::cout << "Initialisation du mesh terminer" << std::endl;
    }

    glBindVertexArray(_vao);

    glDrawArrays(GL_TRIANGLE_STRIP, 0,3);

    glBindVertexArray(0);
}

这是我的查看器和我的渲染循环..:[=​​15=]

void S2Viewer::runLoop()
{


/* Loop until the user closes the window */
  glClearColor(1.0, 1.0, 1.0, 0.0);
  glEnable (GL_DEPTH_TEST);

    while (!glfwWindowShouldClose(_S2viewer))
    {
      Shaders[0]->use();
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      for (std::vector<Mesh*>::iterator mesh = Meshs.begin(); mesh < Meshs.end(); mesh++)
      {
          (*mesh)->draw(Shaders[0]);
      }
        glfwSwapBuffers(_S2viewer);
        glfwPollEvents();
        Shaders[0]->desactivate();
    }
    glfwTerminate();
}

和我的main.cpp

int main(int argc,char** argv)
{
  std::cout << "Hello fuck**g World" <<std::endl;
  S2Viewer viewer;
  viewer.init();
  //initialisation des shaders et des mesh...
  Mesh mesh = Mesh("mesh");
  Shader shader("/Users/benz/Documents/projPerso/Moteur_S2_Engine/data/shader/simple.vert","/Users/benz/Documents/projPerso/Moteur_S2_Engine/data/shader/simple.frag");

  viewer.addMesh(&mesh);
  viewer.addShader(&shader);

  viewer.runLoop();
}

这是我的顶点着色器:

#version 410 core


layout(location = 0) in vec3 V_position;
layout(location = 1) in vec3 V_color;
layout(location = 2) in vec3 V_normal;


void main()
{
    gl_Position = vec4(V_position, 1.);
}

这是我的片段着色器:

#version 410 core


out vec4 out_color;

void main(void) {

    out_color = vec4(1.0,0.0,0.0,1.0);
}

当我 运行 我的代码编译完美但什么都不显示.. 问题不是来自着色器,因为我过去在以前的软件中使用过我的 class 着色器。 另外 glGetError 没有显示任何错误,我不明白我的问题在哪里..

PS :我在 macOS

启用顶点属性时的状态存储在Vertex Array Object中。

在您的代码中,顶点属性被启用,但您之后又立即禁用了它们。最后存储在顶点数组对象状态向量中的顶点属性的状态为"disabled".

跳过顶点属性的禁用

glBindVertexArray(_vao);

....

if(vertex_loc>=0)
{
    glEnableVertexAttribArray(vertex_loc);
    glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
}

....


if(vertex_loc>=0)
    glDisableVertexAttribArray(vertex_loc); // <---- delete this
....

glBindVertexArray(0);

glBufferData 的第二个参数必须是以字节为单位的整个缓冲区的大小。
您的缓冲区有 Vertices.size() 个元素,每个元素的大小为 sizeof(Vertex),因此以字节为单位的缓冲区大小为 sizeof(Vertex) * Vertices.size()

glBufferData(GL_ARRAY_BUFFER, 
   sizeof(Vertex) * Vertices.size(), // <---- sizeof(Vertex) istead of sizeof(vec3)
   Vertices.data(), GL_STATIC_DRAW);