2014-08-29 78 views
0

所以我在OpenGL中編寫了一個模型加載器,它事實上加載了模型,但由於某種原因,我無法看到屏幕。看看自己:我無法讓我的OpenGL程序渲染一個三角形

#define GLEW_STATIC 

#include <GL\glew.h> // Graphics Libraries 
#include <GLFW\glfw3.h> 

#include <iostream> 
#include <fstream> 
#include <vector> 
#include <string> 

int main() 
{ 
    std::cout << "Please enter the name of the mesh file: "; 
    std::string FileName; 
    std::cin >> FileName; 

    std::cout << "You entered: " << FileName << std::endl; 

    if (!glfwInit()) 
    { 
     std::cout << "Failed to initialize GLFW" << std::endl; 
     system("Pause"); 
     return EXIT_FAILURE; 
    } 

    std::cout << "GLFW 3.0.4 Initialized" << std::endl; 

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 

    GLFWwindow* Window = glfwCreateWindow(800, 600, "Window", NULL, NULL); 
    glfwMakeContextCurrent(Window); 

    if (Window == NULL) 
    { 
     std::cout << "Failed to create an OpenGL 3.3 context" << std::endl; 
     system("Pause"); 
     return EXIT_FAILURE; 
    } 

    std::cout << "Created an OpenGL 3.3 context" << std::endl; 

    glewExperimental = GL_TRUE; 

    if (glewInit() != GLEW_OK) 
    { 
     std::cout << "Failed to initialize GLEW 1.11.0" << std::endl; 
     system("Pause"); 
     return EXIT_FAILURE; 
    } 

    std::ifstream FileStream(FileName); 
    std::vector <float> Vertices; 

    if (!FileStream) 
    { 
     std::cout << "An error was encountered while opening "<< FileName << std::endl; 
     system("Pause"); 
     return EXIT_FAILURE; 
    } 

    float coordinateX, coordinateY, coordinateZ; 
    std::string Character; 

    while (!FileStream.eof()) 
    { 
     FileStream >> Character; 

     if (Character == "v") 
     { 
      FileStream >> coordinateX >> coordinateY >> coordinateZ; 
      std::cout << "Loading in " << coordinateX << " " << coordinateY << " " << coordinateZ << std::endl; 
      Vertices.push_back(coordinateX); 
      Vertices.push_back(coordinateY); 
      Vertices.push_back(coordinateZ); 
     } 

     else 
     { 
      std::cout << "Skipping " << Character << std::endl; 
      continue; 
     } 
    } 

    std::cout << "Loaded " << FileName << std::endl; 

    glEnable(GL_DEPTH_TEST); 
    glDepthFunc(GL_LESS); 

    unsigned int VBO; 
    glGenBuffers(1, &VBO); 
    glBindBuffer(GL_ARRAY_BUFFER, VBO); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * Vertices.size(), &Vertices.front(), GL_STATIC_DRAW); 

    unsigned int VAO; 
    glGenVertexArrays(1, &VAO); 
    glBindVertexArray(VAO); 
    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 

    const char* Vertex_Shader = 
     "#version 330\n" 
     "in vec3 vp;" 
     "void main() {" 
     " gl_Position = vec4 (vp, 1.0);" 
     "}"; 

    const char* Fragment_Shader = 
     "#version 330\n" 
     "out vec4 frag_colour;" 
     "void main() {" 
     " frag_colour = vec4 (0.5, 0.0, 0.5, 1.0);" 
     "}"; 

    unsigned int VertexShader = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(VertexShader, 1, &Vertex_Shader, NULL); 
    glCompileShader(VertexShader); 

    unsigned int FragmentShader = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(FragmentShader, 1, &Fragment_Shader, NULL); 
    glCompileShader(FragmentShader); 

    unsigned int Shader_Program = glCreateProgram(); 
    glAttachShader(Shader_Program, FragmentShader); 
    glAttachShader(Shader_Program, VertexShader); 
    glLinkProgram(Shader_Program); 

    while (!glfwWindowShouldClose(Window)) 
    { 

     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     glUseProgram(Shader_Program); 
     glBindVertexArray(VAO); 
     glDrawArrays(GL_TRIANGLES, 0, Vertices.size()); 

     glfwPollEvents(); 
     glfwSwapBuffers(Window); 
    } 

    return EXIT_SUCCESS; 
} 

而加載的文件如下:

v 0.0 0.5 0.0 
v 0.5 -0.5 0.0 
v -0.5 -0.5 0.0 
+0

不相關:在檢查「Window」是否爲null之後,您應該可能調用'glfwMakeContextCurrent'。 – 2014-08-29 18:56:34

+0

你必須在你的頂點數組之後綁定你的'GL_ARRAY_BUFFER' **,這可能是你的問題(除了沒有創建片段着色器)。 – CoffeeandCode 2014-08-30 02:47:32

回答

0
glEnableVertexAttribArray(0); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 

const char* Vertex_Shader = 
    "#version 330\n" 
    "in vec3 vp;" 
    "void main() {" 
    " gl_Position = vec4 (vp, 1.0);" 
    "}"; 

有沒有那個屬性將按照聲明的順序進行分配屬性插槽的保證。

您需要告訴OpenGL(通過a location qualifierglBindAttribLocation() pre-link)在哪裏放置或詢問(glGetAttribLocation() post-link)放置在哪裏。

0

有在該代碼中的至少3個問題:

  1. 它創建兩個頂點着色器對象,並且沒有片段着色器對象。替換:

    unsigned int FragmentShader = glCreateShader(GL_VERTEX_SHADER); 
    

    由:

    unsigned int FragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 
    
  2. 的第三個參數glDrawArrays()必須是頂點的數量,而這個代碼在通過座標的總數量。由於每個頂點的3個座標用在這裏,呼叫更改爲:

    glDrawArrays(GL_TRIANGLES, 0, Vertices.size()/3); 
    
  3. 沒有指定頂點屬性的位置。這可能通過「意外」起作用,特別是只有一個屬性。但指定位置更安全。要做到這一點,最簡單的方法是將位置添加到的vp聲明的頂點着色器:

    "layout(location = 0) in vec3 vp;" 
    
0
  1. 您結合您的GL_ARRAY_BUFFER錯誤
  2. 您的着色器創建
  3. 錯誤
  4. 您的着色器錯誤

1)只需綁定(並創建)您的GL_ARRAY_BUFFER您的glBindVertexArray致電。

2)由於已經在另一個答案說,你的片段着色器創作是錯誤的,應該改爲:unsigned int FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

3)你是理所當然,你會得到正確的屬性在你的着色器,這是不好的做法。你應該是明確的,有一個佈局與此類似:layout(location = X) in vec3 myVec;


的一些技巧:

沒有必要在循環中的VAO重新綁定,只需將它綁定之前while(!glfwWindowShouldClose(Window))。你的着色器程序也一樣。

您應該檢查着色器編譯是否正確,並且程序鏈接正確!分別查看glGetShaderiv,glGetProgramivGL_COMPILE_STATUSGL_LINK_STATUS;和glGetShaderInfoLogglGetProgramInfoLog如果您沒有獲得任何狀態的GL_TRUE

這會給你一個消息,告訴你編譯/鏈接時你得到的確切問題,所以你可以輕鬆地調試你的着色器代碼,而無需猜測。

+0

在glBindVertexArray()之前或之後綁定'GL_ARRAY_BUFFER'並不重要。此綁定不是VAO狀態的一部分。 – 2014-08-30 03:26:04

+0

你是對的,而且我一直認爲這是! – CoffeeandCode 2014-08-30 03:31:45