2011-01-06 6 views
6

편집 : rotoglup 내 코드에서 문제를 발견했습니다. 제거한 셰이더를 추가하면 솔루션이 완료됩니다. 올바른 코드 (쉐이더 포함)는 아래의 내 대답을 참조하십시오.기본 openGL, 정점 버퍼 및 pyglet

안녕하세요!

나는 현대 OpenGL의 기초를 배우려고 노력하고있다. this tutorial.

나는 python/pyglet 대신 C++로하고 싶다. 나는 pyglet이 저수준 OpenGL을 많이 추상화 할 수 있다는 것을 알고 있습니다. 나는 추상의 레이어 뒤에 그들을 숨기기로 이동하기 전에 몇 가지 기본 사항을 이해하고 싶습니다.

내 문제는 매우 간단합니다. 아래 코드는 예상 한 3 점 대신에 단일 점만 그립니다. 내 코드는 자습서의 C++과 동일하지만 파이썬에서 gletools을 통해 수행 된 정점 및 조각 쉐이더 제거를 제외하고는 내 문제와 아무런 차이가없는 것으로 보입니다.

단일 지점으로 단순화하는 것은 내가 이해하지 못하는 행동을 보여 주며 (첫 번째 좌표 만이 영향을 미치는 유일한 것으로 보임) 일반적으로 pyglet, OpenGL을, 또는 3D : 1 3,

import pyglet 
from pyglet.gl import * 

window = pyglet.window.Window() 

positionBufferObject = GLuint() 
vao = GLuint() 

vertexPositions = [0.0, 0.0, 0.0, 
        0.25, 0.0, 0.0, 
        1.75, 1.75, 0.0] 

vertexPositionsGl = (GLfloat * len(vertexPositions))(*vertexPositions) 

@window.event 
def on_draw(): 
    glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject) 
    glEnableVertexAttribArray(0) 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0) 
    glDrawArrays(GL_POINTS, 0, 3) 
    glDisableVertexAttribArray(0) 

glGenBuffers(1, positionBufferObject) 
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject) 
glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW) 
glBindBuffer(GL_ARRAY_BUFFER, 0) 

glClearColor(0.0, 0.0, 0.0, 0.0) 
pyglet.app.run() 
+0

수정 된 코드를 사용하더라도 여전히 단일 점이 그려져 있습니까? 이 지점이 화면 중간에 그려져 있습니까? 첫 번째 좌표를 변경하면 점이 이동합니까? – rotoglup

+0

수정 된 코드를 통해 얻을 수있는 최상의 점은 w 좌표가 1로 이동하지 않고 바이트 단위로 크기를 전달하는 단일 점입니다. 내가 w 좌표를 제거하고 이에 따라 glVertexAttribPointer를 변경하면 아무 것도 얻지 못합니다. 나는 완전히 혼란스러워! –

+0

수정 : w가 표시되기 위해 0으로 설정되어야합니다. 그러면 나를 더 혼란스럽게 만듭니다. –

답변

5
glDrawArrays(GL_POINTS, 0, 1) 

이 튜토리얼에서, 1 점을 끌기 위해 지시 : P

는 여기에 관련 코드의

,
glDrawArrays(GL_POINTS, 0, 3) 

공지 사항 또한 정점의 4 (w) 구성 요소는 1이 아닌 0이 될 것을 : 당신은 w 구성 요소를 제거 할 수 있습니다,

vertexPositions = [0.0, 0.0, 0.0, 
        0.25, 0.0, 0.0, 
        1.75, 1.75, 0.0] 

을 대안으로

vertexPositions = [0.0, 0.0, 0.0, 1.0, 
        0.25, 0.0, 0.0, 1.0, 
        1.75, 1.75, 0.0, 1.0] 

및 변경 다음 전화로 문의하십시오 :

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

또 다른 문제는 pyglet의 전문가가 아닙니다. glBufferData는 C와 마찬가지로, 요소가 아니라 바이트 단위의 크기를 취합니다. 각 플로트는 4 바이트이므로 다음과 같이 시도해 볼 수 있습니다.

glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW) 
+0

답변 주셔서 감사합니다! 귀하의 제안에 내 질문을 편집했습니다 (실제로 drawArray 호출의 올바른 버전을 시도했지만 코드를 복사하기 전에 복원하지 않았습니다). 문제는 여전히 존재하지만 ... pylet의 제 버전에 문제가 있는지 궁금해지기 시작했습니다. gletools를 사용하기 위해서는 개발 버전을 설치해야했습니다. –

+0

다른 가능한 수정을 추가하기 위해 답을 편집했습니다. – rotoglup

+0

(추가 답변)에 감사드립니다. 아직도 불행히도 기쁨이 없습니다 ... OpenGL 문제가 아닌 pyglet에만 해당되는지 궁금해지기 시작했습니다. 나는 pyglet 메일 링리스트를보고 다시보고 할 것이다! –

4

마침내이 권리가 있습니다.

사실 정점, glDrawArrays 및 glVertexAttribPointer를 사용하면 때때로 하나의 점이 표시되는 경우가 많습니다. 이것은 사고로 보입니다. rotoglup의 답변에 의해 제공된 수정 사항과 함께 전혀 아무 것도 그려지지 않습니다. 이것은 원래 질문의 코드에 대한 "올바른"동작입니다.

이 사람하는 데 도움이 경우 내 실수의 재고 :

  • 승을 설정 완전히 튜토리얼 클립 공간 변환에 대한 설명을 누락 한 대신, 0 좌표입니다.

  • glBufferData는 바이트를 예상 할 때 정점의 버퍼 크기를 제공합니다.

  • (위의 두 가지 문제를 찾는 동안 코드를 단순화하기 위해) 꼭지점 및 조각 쉐이더를 제거하십시오. 이렇게하면 아무 것도 렌더링되지 않을 것입니다. 가끔씩 나는 (버기?) 단일 점을 제외하고.

아래의 코드는 패스 스루 쉐이더가있는 단일 삼각형과 최신 OpenJGL이 올바른 것입니다. 요구 사항은 pyglet 및 gletools입니다.

import pyglet 
from pyglet.gl import * 
from gletools import ShaderProgram, FragmentShader, VertexShader 

window = pyglet.window.Window() 

positionBufferObject = GLuint() 

vertexPositions = [0.75, 0.75, 0.0, 1.0, 
        0.75, -0.75, 0.0, 1.0, 
        -0.75, -0.75, 0.0, 1.0] 
vertexPositionsGl = (GLfloat * len(vertexPositions))(*vertexPositions) 

program = ShaderProgram(
    FragmentShader(''' 
    #version 330 
    out vec4 outputColor; 
    void main() 
    { 
     outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f); 
    }'''), 
    VertexShader(''' 
    #version 330 
    layout(location = 0) in vec4 position; 
    void main() 
    { 
     gl_Position = position; 
    }''') 
) 

@window.event 
def on_draw(): 
    with program: 
     glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject) 
     glEnableVertexAttribArray(0) 
     glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0) 
     glDrawArrays(GL_TRIANGLES, 0, 3) 
     glDisableVertexAttribArray(0) 

glGenBuffers(1, positionBufferObject) 
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject) 
glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW) 
glBindBuffer(GL_ARRAY_BUFFER, 0) 

pyglet.app.run()