2013-08-19 23 views
2

我的一個非常奇怪的問題是我的簡單的OpenGL應用程序沒有在我的女朋友的機器上工作。起初,我想到了我的代碼存在的各種問題,但是我最終可以將其分解爲這種代碼不工作(不工作意味着:三角形繪製正確,但是黑色,即沒有正確的顏色):glVertexAttrib3f在一臺機器上的奇怪行爲

#include <stdio.h> 
#include <stdlib.h> 
#include <string> 

#define GLEW_STATIC 
#include <GL/glew.h> 
#include <GLFW/glfw3.h> 
#include <glm/glm.hpp> 
#include <glm/gtx/transform.hpp> 

#include "../common/shader.h" 


const GLfloat reticle_vertices[] = 
{ 
     -1.0f, -1.0f, 0.0f, 
     1.0f, -1.0f, 0.0f, 
     0.0f, 1.0f, 0.0f 
}; 


glm::mat4 MVP; 
glm::mat4 vp; 


const char *vertexSource = 
     "#version 150\n" 
     "layout(location = 0) in vec3 position;" 
     "layout(location = 1) in vec3 color;" 
     "out vec3 fragColor;" 
     "uniform mat4 MVP;" 
     "void main() {" 
     "gl_Position = MVP * vec4(position, 1.0);" 
     "fragColor = color;" 
     "}"; 

const char *fragmentSource = 
     "#version 150\n" 
     "in vec3 fragColor;" 
     "out vec4 outColor;" 
     "void main() {" 
     "outColor = vec4(fragColor, 1.0);" 
     "}"; 


// Key callback: exit on ESCAPE 
static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) 
{ 
     if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) 
       glfwSetWindowShouldClose(window, GL_TRUE); 
} 


// Initialize and return a window with GLFW 
GLFWwindow *initGLWindow(int width, int height, int samples, const char *title, GLFWkeyfun keycb) 
{ 
     if (!glfwInit()) 
     { 
       fprintf(stderr, "Failed to initialize GLFW\n"); 
       return NULL; 
     } 
     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 
     glfwWindowHint(GLFW_SAMPLES, samples); 
     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 

     GLFWwindow *w = glfwCreateWindow(width, height, title, NULL, NULL); 
     if (!w) 
     { 
       glfwTerminate(); 
       return NULL; 
     } 

     glfwMakeContextCurrent(w); 
     glfwSetKeyCallback(w, keycb); 

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

     return w; 
} 


int main() 
{ 
     // Initialize the OpenGL window 
     GLFWwindow *window = initGLWindow(1024, 768, 2, "Schnuff", key_callback); 

     // Load and use the shaders 
     GLuint programID = LoadShaders(vertexSource, fragmentSource); 
     glUseProgram(programID); 

     // Get the attribute locations 
     GLuint posAttrib = glGetAttribLocation(programID, "position"); 
     printf("posAttrib = %d\n", posAttrib); 
     GLuint colAttrib = glGetAttribLocation(programID, "color"); 
     printf("colAttrib = %d\n", colAttrib); 
     //GLint normAttrib = glGetAttribLocation(programID, "normal"); 
     //printf("normAttrib = %d\n", normAttrib); 
     GLuint mvpID = glGetUniformLocation(programID, "MVP"); 

     // Vertex array object 
     GLuint vao; 
     glGenVertexArrays(1, &vao); 
     glBindVertexArray(vao); 

     // Vertex buffer object 
     GLuint vbo; 
     glGenBuffers(1, &vbo); 
     glBindBuffer(GL_ARRAY_BUFFER, vbo); 
     glBufferData(GL_ARRAY_BUFFER, sizeof(reticle_vertices), reticle_vertices, GL_STATIC_DRAW); 

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

     // Hide the cursor 
     glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); 

     glEnable(GL_DEPTH_TEST); 
     glDepthFunc(GL_LESS); 
     glEnable(GL_CULL_FACE); 

     glClearColor(0.0f, 0.0f, 0.2f, 1.0f); 
     glm::mat4 m = glm::mat4(1.0f); 

     // Main loop 
     do 
     { 
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

       glUniformMatrix4fv(mvpID, 1, GL_FALSE, &m[0][0]); 
       glVertexAttrib3f(colAttrib, 1.0f, 0.0f, 0.0f); 
       glDrawArrays(GL_TRIANGLES, 0, 3); 

       glfwSwapBuffers(window); 
       glfwPollEvents(); 
     } 
     while (!glfwWindowShouldClose(window)); 

     glDeleteProgram(programID); 
     glfwDestroyWindow(window); 
     glfwTerminate(); 
     return 0; 
} 

至於我能弄清楚,只有是因爲以下的問題:她的機器,posAttrib = 1, colAttrib = 0上,而在我的是倒過來。我嘗試使用

layout(location = 0) in vec3 position; 
layout(location = 1) in vec3 color; 

然後它工作正常!雖然曾經我交換這些數字(我還沒有與其他的價值觀和#version 330 core\n進行測試,但她的筆記本電腦目前處於脫機狀態),它停止工作了......

我甚至發現下面沒有答案的問題here on SO,這似乎非常密切相關。

您有沒有人遇到類似的行爲,或知道如何解決整個情況,而無需使用layout(location = x)?因爲我認爲在一個更大的項目中,手工設置每個位置可能是乏味的或不需要的(如果我錯了,糾正我,這實際上是實現這個目標的首選方法!)。

還沒有測試:大於0或1,#version東西其他值,因爲我的機器上我甚至不能使用layout(location = x)沒有#version 330 core(這又是奇怪,因爲它顯然不她的機器上的東西這使其工作)。

我是OpenGL的新手,因此在這裏完全搞不懂! :-)

+0

爲什麼它downvoted什麼建議嗎?如果您留下提示,我可以嘗試改進我的帖子:/ – InvisiblePanda

+0

內嵌該代碼。糊狀蛋白有消失的習慣。 – genpfault

回答

2

看起來像我的AMD卡上的driver bug

使用VBO的顏色陣列的工作原理:

#include <vector> 
#include <iostream> 
#include <GL/glew.h> 
#include <GLFW/glfw3.h> 
#include <glm/glm.hpp> 
#include <glm/gtx/transform.hpp> 

// GLSL shader program loader 
struct Program 
{ 
    static GLuint Load(const char* vert, const char* geom, const char* frag) 
    { 
     GLuint prog = glCreateProgram(); 
     if(vert) AttachShader(prog, GL_VERTEX_SHADER, vert); 
     if(geom) AttachShader(prog, GL_GEOMETRY_SHADER, geom); 
     if(frag) AttachShader(prog, GL_FRAGMENT_SHADER, frag); 
     glLinkProgram(prog); 
     CheckStatus(prog); 
     return prog; 
    } 

private: 
    static void CheckStatus(GLuint obj) 
    { 
     GLint status = GL_FALSE, len = 10; 
     if(glIsShader(obj)) glGetShaderiv(obj, GL_COMPILE_STATUS, &status); 
     if(glIsProgram(obj)) glGetProgramiv(obj, GL_LINK_STATUS, &status); 
     if(status == GL_TRUE) return; 
     if(glIsShader(obj)) glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &len); 
     if(glIsProgram(obj)) glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &len); 
     std::vector<char> log(len, 'X'); 
     if(glIsShader(obj)) glGetShaderInfoLog(obj, len, NULL, &log[0]); 
     if(glIsProgram(obj)) glGetProgramInfoLog(obj, len, NULL, &log[0]); 
     std::cerr << &log[0] << std::endl; 
     exit(-1); 
    } 

    static void AttachShader(GLuint program, GLenum type, const char* src) 
    { 
     GLuint shader = glCreateShader(type); 
     glShaderSource(shader, 1, &src, NULL); 
     glCompileShader(shader); 
     CheckStatus(shader); 
     glAttachShader(program, shader); 
     glDeleteShader(shader); 
    } 
}; 
#define GLSL(version, shader) "#version " #version "\n" #shader 

const char* vert = GLSL 
    (
    150 core, 
    in vec3 position; 
    in vec3 color; 
    out vec3 fragColor; 
    uniform mat4 MVP; 
    void main() 
    { 
     fragColor = color; 
     gl_Position = MVP * vec4(position, 1.0); 
    } 
); 

const char* frag = GLSL 
    (
    150 core, 
    in vec3 fragColor; 
    out vec4 outColor; 
    void main() 
    { 
     outColor = vec4(1.0); 
    } 
); 


const GLfloat reticle_vertices[] = 
{ 
    -1.0f, -1.0f, 0.0f, 
    1.0f, -1.0f, 0.0f, 
    0.0f, 1.0f, 0.0f 
}; 

const GLfloat colors[] = 
{ 
    1.0f, 0.0f, 0.0f, 
    1.0f, 0.0f, 0.0f, 
    1.0f, 0.0f, 0.0f 
}; 


// Key callback: exit on ESCAPE 
static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) 
{ 
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) 
     glfwSetWindowShouldClose(window, GL_TRUE); 
} 


// Initialize and return a window with GLFW 
GLFWwindow *initGLWindow(int width, int height, int samples, const char *title, GLFWkeyfun keycb) 
{ 
    if (!glfwInit()) 
    { 
     fprintf(stderr, "Failed to initialize GLFW\n"); 
     return NULL; 
    } 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); 
    glfwWindowHint(GLFW_SAMPLES, samples); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 

    GLFWwindow *w = glfwCreateWindow(width, height, title, NULL, NULL); 
    if (!w) 
    { 
     glfwTerminate(); 
     return NULL; 
    } 

    glfwMakeContextCurrent(w); 

    glfwSetKeyCallback(w, keycb); 

    glewExperimental = true; 
    if (glewInit() != GLEW_OK) 
    { 
     fprintf(stderr, "Failed to initialize GLEW\n"); 
     return NULL; 
    } 
    while(glGetError() != GL_NO_ERROR) {} 

    return w; 
} 


int main() 
{ 
    // Initialize the OpenGL window 
    GLFWwindow *window = initGLWindow(1024, 768, 2, "Schnuff", key_callback); 

    // Hide the cursor 
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); 

    // Load and use the shaders 
    GLuint programID = Program::Load(vert, NULL, frag); 
    glUseProgram(programID); 

    // Vertex array object 
    GLuint vao; 
    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao); 

    // Vertex buffer object 
    GLuint posVbo; 
    glGenBuffers(1, &posVbo); 
    glBindBuffer(GL_ARRAY_BUFFER, posVbo); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(reticle_vertices), reticle_vertices, GL_STATIC_DRAW); 

    GLuint colorVbo; 
    glGenBuffers(1, &colorVbo); 
    glBindBuffer(GL_ARRAY_BUFFER, colorVbo); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); 

    glEnable(GL_DEPTH_TEST); 
    glDepthFunc(GL_LESS); 
    glEnable(GL_CULL_FACE); 

    // Main loop 
    while(!glfwWindowShouldClose(window)) 
    { 
     glClearColor(0.0f, 0.0f, 0.2f, 1.0f); 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

     glm::mat4 m = glm::mat4(1.0f); 
     GLuint mvpID = glGetUniformLocation(programID, "MVP"); 
     glUniformMatrix4fv(mvpID, 1, GL_FALSE, &m[0][0]); 

     GLuint posPos = glGetAttribLocation(programID, "position"); 
     glEnableVertexAttribArray(posPos); 
     glBindBuffer(GL_ARRAY_BUFFER, posVbo); 
     glVertexAttribPointer(posPos, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); 

     GLuint colorPos = glGetAttribLocation(programID, "color"); 
     // broken 
     //glDisableVertexAttribArray(colorPos); 
     //glVertexAttrib3f(colorPos, 1.0f, 0.0f, 0.0f); 
     // works 
     glEnableVertexAttribArray(colorPos); 
     glBindBuffer(GL_ARRAY_BUFFER, colorVbo); 
     glVertexAttribPointer(colorPos, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); 

     glDrawArrays(GL_TRIANGLES, 0, 3); 

     glfwSwapBuffers(window); 
     glfwPollEvents(); 
    } 

    glDeleteProgram(programID); 
    glfwDestroyWindow(window); 
    glfwTerminate(); 
    return 0; 
} 
+0

哇,謝謝驅動程序錯誤鏈接!我不會發現:)關於在緩衝區對象中使用顏色的事情是:我有更多的對象,如體素,它們都是均勻顏色的,並且可以共享相同的常量頂點數組。這就是爲什麼我不想將顏色放入數組中,因爲它正在從一個對象變爲另一個對象。但我認爲我只是要將位置的位置固定爲0.此外,我將嘗試使用統一而不是'in vec3 color;',因爲每次繪製調用的顏色都是不變的。 – InvisiblePanda