OpenGL不显示简单三角形

时间:2018-11-11 21:41:33

标签: c++ opengl cmake glsl glfw

我正在尝试使用OpenGL来构建一些渲染软件,我过去已经使用过OpenGL,但是我找不到我的代码错误的地方。所以我已经实现了:

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

$ python3
Python 3.6.6 (default, Sep 12 2018, 18:26:19) 
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3
>>> sqlite3.version
'2.6.0'
>>> sqlite3.sqlite_version
'3.22.0'

这是我的渲染循环查看器..:

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);
}

和我的main.cpp

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();
}

这里是我的顶点着色器:

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.);
}

当我运行我的代码时,它可以完美编译,但是什么也不显示。 问题并非来自着色器,因为我过去在以前的软件中使用过我的类着色器。 再加上glGetError不显示任何错误,我也不知道我的问题在哪里..

PS:我在macOS上

1 个答案:

答案 0 :(得分:1)

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

在您的代码中启用了顶点属性,但是您又一次禁用了它们。最后,存储在顶点数组对象状态向量中的顶点属性的状态为“禁用”。

跳过禁用顶点属性

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);