2011-12-09 40 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的任何例子,這是很新的

編輯---這裏搜索是可行的解決方案----- -

// 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

也許我沒有關注,但爲什麼release()在map()之前? – Bart

+0

@VJovic - 爲什麼.MAP()總是返回NULL –

回答

3

您應該在映射之前綁定緩衝區!

documentation for QGLBuffer::map

假定創建()被調用該緩衝區和,它已被綁定到當前上下文

除了VJovic的意見,我認爲你缺少有關公益組織幾點:

像素的解壓縮緩衝不給你的指針圖形紋理。它是顯卡上分配的一塊獨立內存,您可以直接從CPU寫入該內存。

可以通過glTexSubImage2D(.....,0)調用將緩衝區複製到紋理中,紋理也被綁定,這是您不需要的。 (0是像素緩衝區的偏移量)。部分需要複製,因爲紋理的佈局與線性像素緩衝區不同。

請參閱this page,以便對PBO使用情況有一個很好的解釋(幾周前我用它來做異步紋理上傳)。

+0

明白了 - 只是glMapBufferARB()的一個包裝?所以數據直接寫入卡片,而不是紋理。但是從PBO到紋理的更新在GPU上如此之快?否則,我coudln't看到一個PBO –

+0

@MartinBeckett好點,是的。從PBO複製紋理比從CPU複製到紋理要快得多,但我不知道從CPU複製到PBO到紋理的整體速度是否比CPU->紋理快。但請記住,PBO的重點不僅在於可能的GPU存儲,還包括更新的異步性。在綁定PBO的情況下,glTexImage2D會立即返回,並且可以將數據從PBO複製到紋理,同時在CPU上執行其他操作。作爲一個完美的例子,看看Macke的流式紋理上傳鏈接。當然,它們也適用於渲染到VBO等等。 –

+0

@Christian,我目前使用紋理,並獲得卡的最大總線速度約50%。最終目標是寫入PBO,然後寫入CUDA以轉換爲紋理。不知道異步在這裏幫助我 - 系統總線將充滿數據上傳到GPU我無法做任何事情! –

0

create將返回false如果GL實現不支持的緩衝區,或者沒有當前QGLContext。

bind如果無法綁定,則返回false,通常是因爲此GL實現不支持type()。

你是不是檢查,如果這兩個函數傳遞。

+0

bind()的數量,並創建()返回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);