2011-07-22 14 views
5

Piszę własny moduł cieniujący z OpenGL, a ja jestem zakłopotany, dlaczego ten moduł cieniujący się nie skompiluje. Czy ktoś mógłby na to spojrzeć?Dlaczego ten GLSL Vertex Shader nie zostanie skompilowany?

Co mam przekazując jako wierzchołka wynosi 2 pływaki (oddzielone jako bajty) w następującym formacie:

Float 1: 

Byte 1: Position X 
Byte 2: Position Y 
Byte 3: Position Z 
Byte 4: Texture Coordinate X 


Float 2: 

Byte 1: Color R 
Byte 2: Color G 
Byte 3: Color B 
Byte 4: Texture Coordinate Y 

A to moja shader:

in vec2 Data; 
varying vec3 Color; 
varying vec2 TextureCoords; 

uniform mat4 projection_mat; 
uniform mat4 view_mat; 
uniform mat4 world_mat; 

void main() 
{ 
    vec4 dataPosition = UnpackValues(Data.x); 
    vec4 dataColor = UnpackValues(Data.y); 

    vec4 position = dataPosition * vec4(1.0, 1.0, 1.0, 0.0); 
    Color = dataColor.xyz; 

    TextureCoords = vec2(dataPosition.w, dataColor.w) 

    gl_Position = projection_mat * view_mat * world_mat * position; 
} 

vec4 UnpackValues(float value) 
{ 
    return vec4(value % 255, (value >> 8) % 255, (value >> 16) % 255, value >> 24); 
} 

Jeśli potrzebujesz więcej informacje, z przyjemnością się do tego zastosuję.

+0

Skopiuj komunikat o błędzie. – tibur

+0

Jak mogę otrzymać komunikat o błędzie? Dostaję jeden, gdy wywołuję glGetProgramInfoLog, ale to tylko "Vertex Shader (s) nie zostały pomyślnie skompilowane przed wywołaniem funkcji glLinkProgram(). Link nie powiodło się." – Azzi777

+3

@ Azzi777: Istnieje parametr glGetShaderInfoLog, który działa, gdy narzędzie glCompileShader ulegnie awarii. Powinieneś sprawdzić status kompilacji obiektów modułu cieniującego i obiektów programu. –

Odpowiedz

10

Musisz zadeklarować UnpackValuesprzed numerem, którą nazywasz. GLSL jest podobny do C i C++; nazwy muszą mieć deklarację, zanim będą mogły zostać użyte.


BTW: Co ty próbujesz zrobić nie zadziała. Pływaki są pływakami; chyba że pracujesz z GLSL 4.00 (a ponieważ nadal używasz starych pojęć takich jak "zmienny", nie zgaduję), nie możesz wyodrębnić bitów z float. W rzeczywistości operator prawostronny jest zdefiniowany tylko dla liczb całkowitych; próba użycia go na floats zakończy się niepowodzeniem z błędem kompilatora.

GLSL to nie C ani C++ (ironicznie).

Jeśli chcesz spakować swoje dane, skorzystaj z OpenGL, aby je spakować. Wyślij dwa atrybuty vec4 zawierających znormalizowane niepodpisane bajtów:

glVertexAttribPointer(X, 4, GL_UNSIGNED_BYTE, GL_TRUE, 8, *); 
glVertexAttribPointer(Y, 4, GL_UNSIGNED_BYTE, GL_TRUE, 8, * + 4); 

Twój vertex shader zajęłoby dwa vec4 wartości, jak wejść. Ponieważ nie używasz glVertexAttrib I Pointer, OpenGL wie, że przekazujesz wartości, które mają być interpretowane jako zmienne.

+0

Dziękuję za pomoc, moduł cieniujący kompiluje się teraz. Mam jednak problemy z glGetVertexAttribute. Czy możesz wyjaśnić, w jakiej kolejności powinienem zadzwonić, glGenBuffer, glBindBuffer (czy powinienem zadzwonić do glSetData?) I co jeszcze muszę wywołać, aby faktycznie przenieść dane vertex do modułu cieniującego? Z góry dziękuję – Azzi777

+0

@ Azzi777: Wiele z wymienionych przez ciebie funkcji ('glGetVertexAttribute',' glSetData') nie istnieje. Wygląda na to, że odpowiedź na twoje pierwotne pytanie. Jeśli masz pytanie dotyczące wysyłania danych vertex, powinieneś zadać to jako nowe pytanie. –

Powiązane problemy