2017-05-14 102 views
0

我想這是相同類型的第100個問題。我正在使用OpenGL 3.3核心配置文件與C++並嘗試渲染一個三角形。C++/OpenGL 3.3+:沒有頂點被渲染

我已閱讀以下兩頁,其中包括鍵入並複製正在討論的代碼。下面我發佈了重要的比特。我已經有了一個三角形被渲染,但顯然我改變了一些小的細節,並搞砸了。 GLFW和GLEW正在初始化,使用glClearColor清理工作很好。

使用中的框架:用於開窗,GLEW和GLM的GLFW。

問題:什麼是我的代碼錯誤,爲什麼沒有被呈現?

期望值:白色的三角形應該是可見的。

結果:什麼都沒有呈現。窗口充滿glClearColor

Game.cpp

const float vertex_data[9] = { 
    -1.0f, -1.0f, 0.0f, 
    1.0f, -1.0f, 0.0f, 
    0.0f, 1.0f, 0.0f, 
}; 

void Game::init() 
{ 
    shader = ShaderProgram(); 
    shader.attachShader(readTextFromFile("data/shaders/main.vs"), GL_VERTEX_SHADER); 
    shader.attachShader(readTextFromFile("data/shaders/main.fs"), GL_FRAGMENT_SHADER); 
    shader.linkProgram(); 

    mesh = Mesh(vertex_data); 
} 

void Game::render() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    shader.bind(); 
    { 
     mesh.render(); 
    } 
    shader.unbind(); 
} 

Mesh.cpp

uint32_t vao; 
uint32_t vertex_buffer; 

Mesh::Mesh(const float vertex_data[]) 
{ 
    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao); 

    glGenBuffers(1, &vertex_buffer); 
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0); 
} 

void Mesh::render() 
{ 
    glBindVertexArray(vao); 
    glEnableVertexAttribArray(0); 
    { 
     // Is this actually necessary for every draw-call? 
     glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); 
     glDrawArrays(GL_TRIANGLES, 0, 3); 
    } 
    glDisableVertexAttribArray(0); 
} 

ShaderProgram.cpp

uint32 id = 0; 
bool linked = false; 

uint32 vertex_shader = 0; 
uint32 fragment_shader = 0; 

ShaderProgram::~ShaderProgram() 
{ 
    unbind(); 

    if (vertex_shader > 0) 
    { 
     glDetachShader(id, vertex_shader); 
     glDeleteShader(vertex_shader); 
    } 

    if (fragment_shader > 0) 
    { 
     glDetachShader(id, fragment_shader); 
     glDeleteShader(fragment_shader); 
    } 

    if (id > 0 && linked) 
    { 
     glDeleteProgram(id); 
    } 
} 

void ShaderProgram::attachShader(std::string source, int32 type) 
{ 
    assert(type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER); 
    assert(id == 0); 

    const char* code = source.c_str(); 

    switch (type) 
    { 
     case GL_VERTEX_SHADER: 
      assert(vertex_shader == 0); 

      vertex_shader = glCreateShader(GL_VERTEX_SHADER); 
      glShaderSource(vertex_shader, 1, &code, NULL); 
      glCompileShader(vertex_shader); 

      int32 vresult; 
      glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &vresult); 

      if (vresult != GL_TRUE) 
      { 
       int32 infolength; 
       glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &infolength); 

       GLchar* infolog = new GLchar[infolength + 1]; 
       glGetShaderInfoLog(vertex_shader, infolength + 1, NULL, infolog); 

       std::stringstream ss; 
       ss << "Shader compilation failed for Vertex Shader: " << infolog << std::endl; 

       std::cout << ss.str() << std::endl; 

       throw std::runtime_error(ss.str()); 
      } 
      break; 
     case GL_FRAGMENT_SHADER: 
      assert(fragment_shader == 0); 

      fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); 
      glShaderSource(fragment_shader, 1, &code, NULL); 
      glCompileShader(fragment_shader); 

      int32 fresult; 
      glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &fresult); 

      if (fresult != GL_TRUE) 
      { 
       int32 infolength; 
       glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &infolength); 

       int32 infosize = infolength + 1; 
       GLchar* infolog = new GLchar[infosize]; 
       glGetShaderInfoLog(fragment_shader, infosize, NULL, infolog); 

       std::stringstream ss; 
       ss << "Shader compilation failed for Fragment Shader: " << infolog << std::endl; 

       std::cout << ss.str() << std::endl; 

       throw std::runtime_error(ss.str()); 
      } 
      break; 
     default: 
      throw std::invalid_argument("Unknown Shader-Type specified"); 
    } 
} 

void ShaderProgram::linkProgram() 
{ 
    assert(id == 0); 
    assert(vertex_shader > 0); 
    assert(fragment_shader > 0); 

    id = glCreateProgram(); 

    glAttachShader(id, vertex_shader); 
    glAttachShader(id, fragment_shader); 

    glLinkProgram(id); 

    int32 result; 
    glGetProgramiv(id, GL_LINK_STATUS, &result); 

    if (result != GL_TRUE) 
    { 
     int32 infolength; 
     glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infolength); 

     int32 infosize = infolength + 1; 
     GLchar* infolog = new GLchar[infosize]; 
     glGetProgramInfoLog(id, infosize, NULL, infolog); 

     std::stringstream ss; 
     ss << "Shader Program Linking failed: " << infolog << std::endl; 

     throw std::runtime_error(ss.str()); 
    } 

    linked = true; 
} 

void ShaderProgram::bind() 
{ 
    assert(id > 0); 
    assert(linked); 

    glUseProgram(id); 
} 

void ShaderProgram::unbind() 
{ 
    int32 current; 
    glGetIntegerv(GL_CURRENT_PROGRAM, &current); 

    if (current == id) 
    { 
     glUseProgram(0); 
    } 
} 

bool ShaderProgram::isLinked() 
{ 
    return linked; 
} 

頂點着色器: 「main.vs」

#version 330 

layout(location = 0) in vec3 VertexPosition; 

void main() 
{ 
    gl_Position = vec4(VertexPosition.xyz, 1.0); 
} 

片段着色器「main.fs」:

#version 330 

out vec4 FinalColor; 

void main() 
{ 
    FinalColor = vec4(1.0, 1.0, 1.0, 1.0); 
} 
+0

您使用的窗口框架(例如'glfw')? –

+0

@BenSteffan添加到主要帖子。 GLFW用於開窗,GLEW和GLM。 – j8a2b0e7

回答

1

此線有一個錯誤:

glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); 

第二參數期望陣列的大小,但要傳遞的大小指針。修復它使用類似於vertex count * sizeof(float)

+0

很快!這是正確的答案。解決這個問題會使三角形出現。我會盡快接受你的回答。有關如何自動檢索正確大小而不是手動輸入sizeof(float)*(vertexcount * 3)的建議? – j8a2b0e7

+0

@ j8a2b0e7您可以將頂點存儲到'std :: vector'中以獲取數組大小而不是使用C樣式數組,但是您仍然必須乘以sizeof(float) – SurvivalMachine