2013-02-19 14 views
9

Próbuję zaimplementować schemat przechodzenia oktree za pomocą OpenGL i GLSL i chciałbym zachować dane w teksturach. Chociaż istnieje duży wybór formatów danych tekstur (zmiennoprzecinkowych i liczb całkowitych o różnych rozmiarach), mam pewne problemy z ustaleniem, czy istnieje sposób na bardziej precyzyjną kontrolę nad bitami, a tym samym na osiągnięcie większej wydajności i kompaktowego przechowywania. Może to być ogólny problem, nie tylko w przypadku OpenGL i GLSL.Precyzyjna kontrola bitów tekstur w GLSL

Jako prosty przykład zabawki, załóżmy, że mam texel zawierający 16-bitową liczbę całkowitą. Chcę zakodować dwa bajty 1-bitowe, jedną 10-bitową liczbę całkowitą, a następnie 4-bitową wartość całkowitą w tym texelu. Czy istnieje technika do kodowania tego podczas tworzenia tekstury, a następnie dekodowania tych komponentów podczas próbkowania tekstury przy użyciu modułu cieniującego GLSL?

Edytuj: Wygląda na to, że w rzeczywistości szukam technik manipulacji bitem. Ponieważ wydają się być wspierani, powinienem czuć się dobrze po dalszych badaniach.

+0

Pytasz, jak manipulować bitem? –

+0

Manipulacja bitami jest możliwa w GLSL 1.3 (OpenGL 3.0), nie wiem jak odczytać surowe int z tekstury w GLSL jednak ... Texture2D zwraca float vec4 –

+0

@NicolBolas: Po dalszych poszukiwaniach wygląda to tak Jestem. Nie zrobiłem tego zbyt często, więc nie byłem pewien. Jeśli GLSL go wesprze, powinienem być w stanie dowiedzieć się, gdzie zacząć się uczyć! –

Odpowiedz

3

Integer i bit-manipulacje wewnątrz shaderów GLSL są obsługiwane od OpenGL 3 (co jest obecne na sprzęcie klasy DX10, jeśli to ci mówi więcej). Tak więc możesz po prostu zrobić to samo w programie cieniującym.

Ale praca z liczbami całkowitymi to jedno, a wydobycie ich z faktury to coś innego. Standardowe formaty tekstur OpenGL (do których można się przyzwyczaić) są albo zapisujące pływaki bezpośrednio (jak GL_R16F) albo znormalizowane stałe wartości punktowe (jak GL_R16, skutecznie liczby całkowite dla niewtajemniczonych;)), ale odczyt z nich (przy użyciu texture, texelFetch lub cokolwiek) połączy cię wartościami pływającymi w module cieniującym, z których nie możesz tak łatwo lub niezawodnie wywnioskować pierwotnego wzorca bitowego wewnętrznej liczby całkowitej.

Tak więc, czego naprawdę potrzebujesz, to tekst w postaci liczb całkowitych, który również wymaga OpenGL 3 (lub może rozszerzenie GL_EXT_texture_integer, ale obsługa sprzętu, które i tak prawdopodobnie będzie miało GL3). Więc dla twojej tekstury musisz użyć rzeczywistego wewnętrznego formatu liczb całkowitych, np. GL_R16UI (dla 1-komponentowej 16-bitowej liczby całkowitej bez znaku) w przeciwieństwie do zwykłych formatów punktów stałych (np. GL_R16 dla znormalizowanego [0,1] -koloru z precyzją 16 bitów).

A następnie w module cieniującym należy użyć typu próbnika całkowitoliczbowego, np. usampler2D na liczbę całkowitą bez znaku 2D tekstury (podobnie isampler... dla podpisanych wariantów) rzeczywiście dostać liczbę całkowitą bez znaku od texture lub texelFetch połączeń:

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

Witam, że glTexImage2D zwraca mi błąd, czy mógłbyś rzucić okiem? http://stackoverflow.com/questions/21625709/jogl-creating-only-red-channel-u16-but-getting-texture-type-and-format-combina – elect