2011-09-11 9 views
5

Ho ottenuto un segfault quando ho provato a caricare un'immagine 771x768.glTexImage2D Segfault correlato alla larghezza/altezza

Provato con un'immagine 24x24 e 768x768 e hanno funzionato, nessun problema.

È previsto? Perché non dovrebbe fallire con grazia con un errore GL?

L'errore di segmentazione si verifica nella chiamata glTexImage2D. Sto caricando un file binario PPM in modo che sia pieno di 24 bit per pixel. Questo numero dispari combinato con una dimensione dispari produce probabilmente una struttura allineata non a 4 byte (o anche a 2 byte) (e il riferimento al di fuori del mio buffer assegnato esattamente può essere la causa dell'errore ma gdb non mi mostra una memoria indirizzo (che potrei usare per scoprire se questo è ciò che lo causa)).

glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, dataptr); 
// in this specific case of failure, width = 771, height = 768, 
// dataptr contains 1776384 bytes of binary RGB image data (771*768*3 = 1776384) 
+2

Dove si verifica il segfault? Com'è il tuo codice? – Goz

+0

domanda aggiornata con alcuni dettagli. Penso di avere un'idea di cosa è andato storto. Hai bisogno di testare di più. –

+0

Ancora nessun codice però. – Goz

risposta

14

Questo numero dispari combinato con una dimensione dispari probabilmente produce un non-4-byte (o anche 2 byte) allineato struttura (e riferimento fuori della mia buffer allocato esattamente sufficiente può essere la causa dell'errore

Questa è probabilmente la causa. Fortunatamente puoi impostare l'allineamento che OpenGL utilizza per leggere i dati dei pixel. Subito prima di chiamare glTexImage…(…) do

glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 
+0

Questo ha fatto il trucco. –

+0

C'è un collegamento dove potrei leggere di più sulla struttura allineata a 4/2 byte? –

+1

@BenediktBock: Non c'è molto da fare. n-alignment significa semplicemente che l'inizio di un particolare set di dati (una riga di pixel, un pixel stesso) accade così inizia da un indirizzo di memoria che è un multiplo intero di n. La maggior parte delle architetture della CPU ha determinate restrizioni di allineamento da seguire; per esempio ARM a 32 bit vuole che tutto sia allineato a 16 bit = 2 byte o 32 bit = 4 byte (a seconda della versione dell'architettura ARM). Le CPU Intel possono eseguire operazioni atomiche solo a 4 byte di allineamento. Quindi troverai formati di struttura che allineano i dati ad alcuni n = 2, 4 o 8 per semplificare le cose. – datenwolf

1

ho letto questo nel forum di OpenGL:

width must be 2^m + 2(border) for some integer m. 
height must be 2^n + 2(border) for some integer n. 

(source)

ho trovato questo che credo chiarisce ciò che sta accadendo:

1. What should this extension be called? 

    STATUS: RESOLVED 

    RESOLUTION: ARB_texture_non_power_of_two. Conventional OpenGL 
    textures are restricted to size dimensions that are powers of two. 

da GL_ARB_texture_non_power_of_two

+0

Questo è rilevante solo per OpenGL-1.x. Poiché le dimensioni di trama arbitrarie di OpenGL-2.x sono consentite. – datenwolf

+0

Da quando ho risolto il problema del crash ho scritto un piccolo test che itera su tutte le permutazioni di coppie di numeri interi da 64 a 1024, caricando una texture con quelle dimensioni. (ad esempio 64x64, 64x65 ... 64x1024, 65x64, ...), Finora è quasi a metà delle 921.600 risoluzioni possibili in questo set. Nessun arresto anomalo e nessun segoult ancora. Quindi, sì, l'implementazione di OpenGL che sto eseguendo sembra soddisfare dimensioni di texture arbitrarie, e posso garantire per questo perché ho caricato oltre 500 mila diversi. –