2012-04-21 4 views
0

내 프로그램에서 내 자신의 정점 및 조각 쉐이더를 만들려고합니다. (기본적으로 VBO로 삼각형을 표시하는 아주 간단한 프로그램입니다). 그러나, 그것을 실행할 때, 나는 항상 아무 것도 나타나지 않는 검은 색 화면을 얻습니다. 컴파일 로그를 확인한 결과 오류없이 반환됩니다. 나는 내 자신의 커스텀 쉐이더로 프로그램을 실행해야만하는데, 여기서 나는 틀린 일을하는지 궁금하게 생각한다. 내가 OpenGL을 3.2 GLSL 1.5GLSL 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을 사용해보십시오.

  1. 사용하는 GLSL 버전 3.30 이상 :
    #version 150\n\ 
    \n\ 
    layout (location=0) in vec4 position; 
    

    layout(location=0)


    두 가지 상황에서 버텍스 쉐이더 입력에 대해서만 유효합니다. 귀하의 쉐이더는 #version 150라고 말합니다.
  2. ARB_explicit_attrib_location 확장을 사용하고 있습니다. 이 경우 셰이더에서 활성화하려면 #extension 선언이 필요합니다. 또한 OSX의 GL 3.2 지원이 이 아니고이 확장 기능을 제공한다는 사실을 알고 있습니다.

이렇게하려면 구식 방식으로해야합니다 (glBindAttribLocation). Use 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

+2

@theAmateurProgrammer : 아니요, 문제입니다. 그것은 단지 * 유일한 * 하나가 아닙니다. 내 편집을 참조하십시오. –

+0

"게다가, OSX의 GL 3.2 지원이이 확장 기능을 제공하지 않는다는 사실을 알고 있습니다." 사실, 사과 웹 사이트와 OpenGL 확장 뷰어에서 언급했듯이 확장 기능을 쿼리하기 위해 glGet()을 사용합니다 .... 유일한 단점은 "#extension GL_ARB_explicit_attrib_location : enable"을 사용하면 다음과 같이 정의해야한다는 것입니다. 너무 많이 좋네요! –