2012-04-21 178 views
0

我想在我的程序中創建自己的頂點和片段着色器(這基本上是一個顯示VBO三角形的非常簡單的程序)。但是,當我嘗試運行它時,我總是得到一個沒有任何顯示的黑屏。我檢查了編譯日誌,並返回了沒有錯誤。我還沒有用自己的自定義着色器運行一個程序,這讓我想知道在這裏做錯了什麼。我跑我的代碼上的OpenGL 3.2和GLSL 1.5讓GLSL 1.5在Mac OS X上工作

下面是我試圖運行目前


GLuint vbo; 

GLfloat data[] = {0.0, 0.0, -5.0, 
        1.0, 0.0, -5.0, 
        1.0, 1.0, -5.0 
}; 

const char *vertexShader = "\n\ 
#version 150\n\ 
\n\ 
layout (location=0) in vec4 position;\n\ 
void main()\n\ 
{\n\ 
gl_Position = position;\n\ 
}\n\ 
"; 

const char *fragmentShader = "\n\ 
#version 150\n\ 
\n\ 
out vec4 outColor;\n\ 
\n\ 
void main()\n\ 
{\n\ 
    outColor = vec4(1.0, 0.0, 0.0, 1.0);\n\ 
}"; 


- (void)drawRect:(NSRect)dirtyRect 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 

    glMatrixMode(GL_MODELVIEW); 

    glLoadIdentity(); 

    glUseProgram(programId); 

    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 

    glEnableClientState(GL_VERTEX_ARRAY); 

    glVertexPointer(3, GL_FLOAT, 0, 0); 

    glDrawArrays(GL_TRIANGLES, 0, sizeof(data)); 

    glFlush(); 


    glDisableClientState(GL_VERTEX_ARRAY); 

} 

-(void)reshape 
{ 
    glViewport(0, 0, w, h); 
    gluPerspective(45.0,     //The camera angle 
        (double)w/(double)h, //The width-to-height ratio 
        1.0,     //The near z clipping coordinate 
        200.0); 
} 

-(void)prepareOpenGL 
{ 
    glEnable(GL_DEPTH_TEST); 

    glGenBuffersARB(1, &vbo); 
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo); 
    glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(data), data, GL_STATIC_DRAW); 

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


    vertexShaderId = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(vertexShaderId, 1, &vertexShader, NULL); 

    glCompileShader(vertexShaderId); 

    GLint completed; 
    glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &completed); 

    if (!completed) 
    { 
     GLint length; 
     GLchar *log; 
     glGetShaderiv(vertexShaderId, GL_INFO_LOG_LENGTH, &length); 

     log = (GLchar *)malloc(length); 
     glGetShaderInfoLog(vertexShaderId, length, &length, log); 
     fprintf(stderr, "Vertex compile log = '%s'\n", log); 
    } 



    fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER); 
    glShaderSource(fragmentShaderId, 1, &fragmentShader, NULL); 
    glCompileShader(fragmentShaderId); 

    GLint complete; 

    glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &complete); 

    if (!complete) 
    { 
     GLint length; 
     GLchar *log; 
     glGetShaderiv(fragmentShaderId, GL_INFO_LOG_LENGTH, &length); 

     log = (GLchar *)malloc(length); 
     glGetShaderInfoLog(fragmentShaderId, length, &length, log); 
     fprintf(stderr, "fragment compile log = '%s'\n", log); 
    } 

    programId = glCreateProgram(); 

    glAttachShader(programId, vertexShaderId); 
    glAttachShader(programId, fragmentShaderId); 

    glLinkProgram(programId); 

    glUseProgram(programId); 
} 

回答

9

這裏有幾個問題的代碼。從上到下:


GLfloat data[] = {0.0, 0.0, -5.0, 
        1.0, 0.0, -5.0, 
        1.0, 1.0, -5.0 
}; 

該數據是不可見的,因爲該Z值是觀察體積之外[-1,1]。嘗試使用0.0代替。


#version 150\n\ 
\n\ 
layout (location=0) in vec4 position; 

layout(location=0)僅用於頂點着色器輸入合法的在兩種情況下:

  1. 您使用GLSL 3.30版或更高版本。你的着色器說#version 150
  2. 您正在使用ARB_explicit_attrib_location擴展名。在這種情況下,您需要使用#extension聲明在着色器中激活它。另外,我知道一個事實,即OSX的GL 3.2支持而不是提供此擴展。

所以你需要做到這一點老式的方式:與glBindAttribLocationUse this function before you link your program


glEnableClientState(GL_VERTEX_ARRAY); 
glVertexPointer(3, GL_FLOAT, 0, 0); 

這不僅是不必要的,當你試圖渲染它的積極破壞性你想實現什麼,因爲類似的原因一個OpenGL錯誤的產生。

如果您使用的是通用屬性,則不需要需要的舊式屬性。


glDrawArrays(GL_TRIANGLES, 0, sizeof(data)); 

sizeof(data)字節data陣列的大小。在大多數機器上,這將是36.你是而不是呈現36個頂點;你正在渲染三個。所以這應該是:

glDrawArrays(GL_TRIANGLES, 0, 3); 

gluPerspective(45.0,     //The camera angle 
       (double)w/(double)h, //The width-to-height ratio 
       1.0,     //The near z clipping coordinate 
       200.0); 

這不是一個問題,這麼多完全沒有意義的。你使用着色器進行渲染,而你沒有使用內置的矩陣。這沒有沒有


glGenBuffersARB(1, &vbo); 
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo); 
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(data), data, GL_STATIC_DRAW); 

這也很可能不是一個 「問題」,但它可能是。以「ARB」結尾的函數和枚舉器代表OpenGL擴展。所以你正在使用ARB_vertex_buffer_object擴展所公開的函數。

自GL 1.4以來,此擴展已成爲核心。事實上,你甚至不使用擴展一致(這可能會出現問題)。您正在使用ARB擴展名設置緩衝區的數據,但在渲染時使用核心功能。

只是溝通ARB擴展的東西,並使用核心功能。


log = (GLchar *)malloc(length); 
    glGetShaderInfoLog(vertexShaderId, length, &length, log); 
    fprintf(stderr, "Vertex compile log = '%s'\n", log); 

這不會導致錯誤,但......哪裏是你要free電話嗎?


glLinkProgram(programId); 
glUseProgram(programId); 

你應該總是check for errors編譯着色器鏈接程序後。


你的代碼似乎是從各種來源複製粘貼到一起形成某種弗蘭肯斯坦的程序。你的大部分問題都源於不同的代碼,它們的行爲方式與你計劃如何使用它們不同。你真的應該調查這些東西是如何工作的;這樣,你就不會遇到這些問題。

+0

似乎沒有問題。我仍然得到一個黑屏。 – TheAmateurProgrammer 2012-04-22 01:21:26

+2

@theAmateurProgrammer:不,這是問題;它只是不是*唯一*一個。看我的編輯。 – 2012-04-22 01:51:36

+0

「另外,我知道OSX的GL 3.2支持不提供這種擴展。」實際上,它確實(正如蘋果公司的網站和openGL擴展查看器所指出的那樣,並且還使用glGet()來查詢擴展......唯一的怪癖是你必須將它定義爲:「#extension GL_ARB_explicit_attrib_location:enable」它使用glsl好多了! – 2014-06-02 21:33:00