2013-12-21 130 views
0

我遵循第8版,下面是我從書中修改的代碼。它不會給我我想要的,而是一個空白的窗口。我想知道我在修改過程中犯了什麼錯誤?OpenGL編程指南第一個示例

下面是我修改的代碼,希望有人能指出這個錯誤。

#include <iostream> 
#include <OpenGL/glu.h> 
#include <OpenGL/gl3.h> 
#include <GLUT/GLUT.h> 

GLuint vaoNames[1]; 
GLuint bufferNames[1]; 
int vPosition = 0; 

GLuint createProgram(); 
GLuint createShader(GLenum type, const char* src); 
GLuint program; 

void init() 
{ 
    glGenVertexArrays(1, vaoNames); 
    glBindVertexArray(vaoNames[0]); 

    GLfloat vertices[6][2] = { 
     { -0.90, -0.90 }, // Triangle 1 
     { 0.85, -0.90 }, 
     { -0.90, 0.85 }, 
     { 0.90, -0.85 }, // Triangle 2 
     { 0.90, 0.90 }, 
     { -0.85, 0.90 } 
    }; 

    glGenBuffers(1, bufferNames); 
    glBindBuffer(GL_ARRAY_BUFFER, bufferNames[0]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 

    glUseProgram(createProgram()); 
    glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); 
    glEnableVertexAttribArray(vPosition); 
} 

void render() 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 
    glBindVertexArray(vaoNames[0]); 
    glDrawArrays(GL_TRIANGLES, 0, 6); 
    glFlush(); 
} 

GLuint createProgram() 
{ 
    GLuint program = glCreateProgram(); 

    const char* vertexShaderSrc = 
    "#version 400 core        \n" 
    "layout(location = 0) in vec4 vPosition;  \n" 
    "void main()         \n" 
    "{            \n" 
     "gl_Position = vPosition;     \n" 
    "}"; 
    GLuint vertexShader = createShader(GL_VERTEX_SHADER, vertexShaderSrc); 

    const char* fragmentShaderSrc = 
    "#version 400 core        \n" 
    "out vec4 fColor;        \n" 
    "void main()         \n" 
    "{            \n" 
    "fColor = vec4(0.0, 0.0, 1.0, 1.0);   \n" 
    "}"; 
    GLuint fragmentShader = createShader(GL_FRAGMENT_SHADER, fragmentShaderSrc); 

    glAttachShader(program, vertexShader); 
    glAttachShader(program, fragmentShader); 

    glLinkProgram(program); 
    return program; 
} 

GLuint createShader(GLenum type, const char* src){ 
    GLuint shaderID = glCreateShader(type); 
    glShaderSource(shaderID, 1, &src, 0); 
    glCompileShader(shaderID); 
    return shaderID; 
} 

int main(int argc, char ** argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGBA); 
    glutInitWindowSize(512, 512); 
    glutCreateWindow("8877"); 

    init(); 
    glutDisplayFunc(render); 
    glutMainLoop(); 
} 
+0

你是否試圖做一些愚蠢的事情在OSX上使用它? – genpfault

+0

除了空白屏幕之外,您是否還有其他錯誤?你能發佈一個你得到的和你期望的(如果你可以的話)的屏幕截圖嗎? – rhughes

+0

爲什麼不檢查着色器編譯和鏈接日誌? – genpfault

回答

3

當你說「有着色器編譯和鏈接程序過程中沒有錯誤」,你的意思是,該程序不會停止,或者你的意思,你居然跑不同的程序和檢查結果glGetError()在各個點上,還是取得編譯或連接日誌?你的程序並沒有實際的錯誤檢查,OpenGL也不會引發異常或產生錯誤輸出。你必須要求這些東西。

只是因爲glCompileShader()不會產生錯誤並不意味着您的着色器實際編譯。你需要檢查與此類似着色器編譯狀態和程序與代碼的鏈接狀態:

GLint compiled; 
    glGetShaderiv(newShader, GL_COMPILE_STATUS, &compiled); 
    if (!compiled) { 
     std::string log = getLog(newShader); 
     SAY(log.c_str()); 
     throw std::runtime_error("Failed to compile shader " + log); 
    } 

其中getLog

static std::string getLog(GLuint shader) { 
    std::string log; 
    GLint infoLen = 0; 
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 

    if (infoLen > 1) { 
     char* infoLog = new char[infoLen]; 
     glGetShaderInfoLog(shader, infoLen, NULL, infoLog); 
     log = std::string(infoLog); 
     delete[] infoLog; 
    } 
    return log; 
} 

這對於檢查着色器,並有相當的功能用於檢查結果並獲取程序鏈接的日誌。除非你打電話給他們,否則你不能保證着色器正在編譯。假設你沒有在着色器語法中犯過一些簡單的錯誤,那麼你面臨的最可能的問題是缺乏對OpenGL 4.x的支持,這會導致着色器立即失敗。

+0

謝謝@Jherico,看來問題是Mac os x支持較低版本的Opengl導致着色器無法編譯。 – Korben

+0

我應該猜到了。語句#include 是Mac OS的獨特之處,我一直在爲自己的OSX缺乏4.x支持而苦苦掙扎。 – Jherico

+0

我也是,根據這個鏈接https://developer.apple.com/graphicsimaging/opengl/capabilities/index.html,我的代碼應該支持GLSL 4.1。不知何故,它似​​乎不是。我仍在爲此努力 – Korben