2011-12-09 3 views
0

QGLbuffer을 사용하여 이미지를 표시하려고합니다.
순서 뭔가 같다 :QGLBuffer :: map은 NULL을 반환합니까?

initializeGL() { 
    glbuffer= QGLBuffer(QGLBuffer::PixelUnpackBuffer);   
    glbuffer.create(); 
    glbuffer.bind(); 
    glbuffer.allocate(image_width*image_height*4); // RGBA 
    glbuffer.release(); 
} 

// Attempting to write an image directly the graphics memory. 
// map() should map the texture into the address space and give me an address in the 
// to write directly to but always returns NULL 
unsigned char* dest = glbuffer.map(QGLBuffer::WriteOnly); FAILS 
MyGetImageFunction(dest);   
glbuffer.unmap(); 

paint() { 
    glbuffer.bind(); 
    glBegin(GL_QUADS); 
    glTexCoord2i(0,0); glVertex2i(0,height()); 
    glTexCoord2i(0,1); glVertex2i(0,0); 
    glTexCoord2i(1,1); glVertex2i(width(),0); 
    glTexCoord2i(1,0); glVertex2i(width(),height()); 
    glEnd();    
    glbuffer.release(); 
} 

이 방법으로 GLBuffer를 사용하는 모든 예제가 아닌, 꽤 새로운

편집 --- 여기 검색을위한 작업 솔루션입니다 ----- - GL의 구현은 버퍼를 지원하지 않는 경우

// Where glbuffer is defined as 
glbuffer= QGLBuffer(QGLBuffer::PixelUnpackBuffer); 

// sequence to get a pointer into a PBO, write data to it and copy it to a texture 
glbuffer.bind(); // bind before doing anything 
unsigned char *dest = (unsigned char*)glbuffer.map(QGLBuffer::WriteOnly); 
MyGetImageFunction(dest);       
glbuffer.unmap(); // need to unbind before the rest of openGL can access the PBO 

glBindTexture(GL_TEXTURE_2D,texture);      
// Note 'NULL' because memory is now onboard the card                     
glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, image_width, image_height, glFormatExt, glType, NULL); 
glbuffer.release(); // but don't release until finished the copy 


// PaintGL function 
glBindTexture(GL_TEXTURE_2D,textures); 
glBegin(GL_QUADS); 
    glTexCoord2i(0,0); glVertex2i(0,height()); 
    glTexCoord2i(0,1); glVertex2i(0,0); 
    glTexCoord2i(1,1); glVertex2i(width(),0); 
    glTexCoord2i(1,0); glVertex2i(width(),height()); 
glEnd();    
+2

질문은 무엇입니까? –

+0

아마 내가 따르지는 않지만 map() 이전에 release()를 사용하는 이유는 무엇입니까? – Bart

+0

@VJovic - .map()이 항상 NULL을 반환하는 이유 –

답변

3

매핑하기 전에 버퍼를 바인딩해야합니다! documentation for QGLBuffer::map에서

:

는 것으로 가정 생성()가 현재 컨텍스트에 결합 된 버퍼 및 불려왔다. VJovic의 의견뿐만 아니라

, 난 당신이 PBOs에 대해 몇 가지 사항을 누락 생각 :

픽셀의 포장을 풀고 버퍼가 당신에게 그래픽 텍스처에 대한 포인터를 제공하지 않습니다. 그래픽 카드에 할당 된 별도의 메모리 조각으로 CPU에서 직접 쓸 수 있습니다.

glTexSubImage2D (....., 0) 호출로 텍스처에 버퍼를 복사 할 수 있습니다. 텍스처는 바운드되고 바인딩되지 않습니다. (0은 픽셀 버퍼에 대한 오프셋 임). 텍스처는 선형 픽셀 버퍼와 다른 레이아웃을 가지기 때문에 부분적으로 복사가 필요합니다.

PBO 사용법에 대한 자세한 설명은 this page을 참조하십시오 (비동기 텍스처 업로드를 수행하기 위해 몇 주 전에 사용했습니다).

+0

알았어 - 단순히 glMapBufferARB() 주위의 래퍼입니까? 따라서 데이터는 카드에 직접 기록되지만 텍스처에는 기록되지 않습니다. 그러나 PBO에서 텍스쳐로의 업데이트는 GPU에서 매우 빠릅니다. 그렇지 않으면 PBO의 요점을 볼 수 없습니다. –

+0

@MartinBeckett 그렇습니다.아마도 PBO에서 CPU로 텍스처를 복사하는 것보다 훨씬 빠릅니다. 그러나 CPU에서 PBO로 텍스처를 복사하는 것이 CPU- 텍스처보다 훨씬 빠릅니다. 그러나 PBO의 요점은 가능한 GPU 저장소 일뿐만 아니라 업데이트의 비동기이기도합니다. PBO 바운드를 사용하면 glTexImage2D가 즉시 반환되고 CPU에서 다른 일을하는 동안 PBO에서 텍스처로 데이터를 복사 할 수 있습니다. 스트리밍 텍스처 업로드를위한 Macke 링크를 완벽한 예제로 살펴보십시오. 물론 VBO와 같은 것들에 대해서도 유용합니다. –

+0

@Christian, 저는 현재 질감을 사용하고 카드에 최대 50 %의 버스 속도를 얻습니다. 궁극적 인 목적은 PBO에 쓰고 CUDA를 텍스처로 변환하는 것입니다. 비동기가 여기에 도움이되는지 확신하지 못한다. 시스템 버스는 GPU로 데이터를 업로드하기에 충분할 것이다. 어쨌든 나는 아무것도 할 수 없다. –

0

create는 false를 반환합니다, 또는 전류 QGLContext가 없습니다.

bind은 바인딩이 불가능한 경우 false를 반환합니다. 일반적으로이 GL 구현에서는 type()이 지원되지 않기 때문입니다.

이 두 함수가 전달되었는지 확인하지 않습니다.

+0

bind() 및 create()가 true를 반환하므로 여기 코드를 단순화하고 싶습니다. allocate는 반환 값을 가지지 않지만 size()는 올바른 크기를 반환합니다. –

0

같은 것을 얻었습니다.지도는 NULL을 반환합니다. 다음 명령을 사용하면 해결됩니다.

bool success = mPixelBuffer->create(); 
mPixelBuffer->setUsagePattern(QGLBuffer::DynamicDraw); 
success = mPixelBuffer->bind(); 
mPixelBuffer->allocate(sizeof(imageData)); 
void* ptr =mPixelBuffer->map(QGLBuffer::ReadOnly); 
관련 문제