2013-02-19 22 views
9

Sto provando a implementare uno schema di attraversamento di otto utilizzando OpenGL e GLSL e vorrei mantenere i dati in trame. Mentre c'è una grande selezione di formati da usare per i dati di texture (float e interi di dimensioni diverse) ho qualche problema nel capire se c'è un modo per avere un controllo più preciso sui bit e ottenere così una maggiore efficienza e storage compatto. Questo potrebbe essere un problema generale, non solo applicando a OpenGL e GLSL.Controllo preciso sui bit di trama in GLSL

Come un semplice esempio di giocattolo, diciamo che ho un texel contenente un intero a 16 bit. Voglio codificare due booleans di 1 bit ciascuno, un valore intero a 10 bit e quindi un valore intero a 4 bit in questo texel. Esiste una tecnica per codificarlo quando si crea la trama e quindi decodificare questi componenti quando si campiona la trama utilizzando uno shader GLSL?

Modifica: Sembra che in effetti sto cercando tecniche di manipolazione dei bit. Dal momento che sembrano essere supportati, dovrei stare bene dopo qualche ricerca in più.

+0

Stai chiedendo come si fa la manipolazione del bit? –

+0

La manipolazione dei bit è possibile in GLSL 1.3 (OpenGL 3.0), non so come sia possibile leggere il raw int dalla texture in GLSL comunque ... Texture2D restituisce float vec4 –

+0

@NicolBolas: dopo qualche altra ricerca, sembra che Sono. Non l'ho fatto molto, quindi non ero sicuro. Se GLSL lo supporta, dovrei essere in grado di capire da dove iniziare a conoscerlo! –

risposta

3

Le manipolazioni di interi e di bit all'interno degli shader GLSL sono supportate da OpenGL 3 (quindi presenti sull'hardware di classe DX10, se questo ti dice di più). Quindi puoi semplicemente fare questo po 'di condizionamento da solo all'interno dello shader.

Ma lavorare con gli interi è una cosa, farli uscire dalla trama è un altro. I formati di texture OpenGL standard (a cui potresti essere abituato) sono sia i float direttamente (come GL_R16F) che i valori normalizzati a virgola fissa (come GL_R16, interi effettivi per chi non lo sapesse;)), ma leggendo da essi (usando texture, texelFetch o qualunque cosa) vi metterà in rete i valori fluttuanti nello shader, da cui non è possibile dedurre facilmente o in modo affidabile il modello di bit originale del numero intero memorizzato internamente.

Quindi ciò che è veramente necessario utilizzare è una trama intera, che richiede anche OpenGL 3 (o forse l'estensione GL_EXT_texture_integer, ma l'hardware che supporta avrà comunque GL3). Quindi per la tua texture devi usare un vero formato interno intero, come per es. GL_R16UI (per un intero senza segno a 16 bit a 1 componente) in contrasto nei soliti formati a virgola fissa (come ad esempio GL_R16 per un colore normalizzato [0,1] con precisione a 16 bit).

E quindi nello shader è necessario utilizzare un tipo di campionatore intero, come ad es. usampler2D per una texture 2D intero senza segno (e allo stesso modo isampler... per le varianti firmati) per ottenere in realtà un numero intero senza segno dal tuo texture o texelFetch chiamate:

CPU:

glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, ..., GL_R, GL_UNSIGNED_SHORT, data); 

GPU:

uniform usampler2D tex; 

... 
uint value = texture(tex, ...).r; 
bool b1 = (value&0x8000) == 0x8000, 
    b2 = (value&0x4000) == 0x4000; 
uint i1 = (value>>4) & 0x3FF, 
    i2 = value & 0xF; 
+0

Ciao, che glTexImage2D sta restituendo un errore per me, potresti dare un'occhiata? http://stackoverflow.com/questions/21625709/jogl-creating-only-red-channel-u16-but-getting-texture-type-and-format-combina – elect