2012-02-06 14 views
18

Leggendo le specifiche OpenGL, ho notato che si può includere più shader dello stesso tipo in un singolo programma (cioè più di un GL_VERTEX_SHADER allegato con glAttachShader). Specificamente in OpenGL 4.2, §2.11.3, Oggetti programma: "Più oggetti shader dello stesso tipo possono essere collegati a un singolo oggetto programma ...".Collegamento di più shader dello stesso tipo in un singolo programma OpenGL?

Qui potrebbero essere applicati i programmi di pipeline OpenGL e le subroutine, ma questo è stato definito prima di quelli esistenti (infatti torna alle specifiche 2.1, §2.15.2) quindi sto cercando un esempio pre-GL4 di questa idea. Quando ho fatto alcuni test semplici, ho scoperto che incluso più di uno void main() causato errori di collegamento. Qualcuno sa di un esempio didove viene utilizzato?

+0

Non sono sicuro che funzioni, ma suppongo che tu possa avere degli shader con funzioni comuni (ma nessuna funzione principale) in modo da poterli collegare al porgram e accedere a queste funzioni dallo shader principale. In questo modo hai solo bisogno di compilare quelle funzioni una sola volta. –

risposta

26

È possibile inserire funzioni comuni a Shader separata. Quindi compila solo una volta e collega in più programmi.

È simile al modo in cui si compila i file cpp una sola volta per ottenere una libreria statica o condivisa. Quindi colleghi questa libreria a più programmi eseguibili, risparmiando così tempo di compilazione.

Diciamo che avete complessa funzione di illuminazione:

vec3 ComputeLighting(vec3 position, vec3 eyeDir) 
{ 
    // ... 
    return vec3(...); 
} 

Poi per ciascuno di shader di cui si desidera utilizzare questa funzionalità fare questo:

vec3 ComputeLighting(vec3 position, vec3 eyeDir); 

void main() 
{ 
    vec3 light = ComputeLighting(arg1, arg2); 
    gl_FragColor = ...; 
} 

Poi si compila separatamente Shader comune e il vostro principale shader. Ma fai la compilation di shader comune solo una volta.

+0

Ovviamente, questo ha perfettamente senso. Grazie! –

7

ho scoperto che tra cui più di un void main() ha causato errori che collegano

Per ogni fase dello shader ci deve essere solo una funzione di entrata principale.

un esempio pratico in cui questo è usato (pre-GL4)?

È possibile dichiarare una funzione in una sorgente shader e non definirla, e al momento del collegamento è possibile fornire una definizione da un'altra sorgente di shader (molto simile al collegamento c/C++).

Esempio:

generate_txcoord.glsl:

#version 330 
precision highp float; 

const vec2 madd = vec2(0.5, 0.5); 

vec2 generate_txcoord(vec2 v) 
{ 
    return v * madd + madd; 
} 

vertex.glsl:

#version 330 
precision highp float; 

in vec2 vxpos; 

out vec2 out_txcoord; 

vec2 generate_txcoord(vec2 vxpos); // << declared, but not defined 

void main() 
{ 
    // generate 0..+1 domain txcoords and interpolate them 
    out_txcoord = generate_txcoord(vxpos); 

    // interpolate -1..+1 domain vxpos 
    gl_Position = vec4(vxpos, 0.0, 1.0); 
} 
Problemi correlati