2009-05-19 11 views
3

Je cherche un moyen d'accéder aux états OpenGL à partir d'un shader. Le GLSL Quick Reference Guide, une ressource impressionnante, ne pouvait pas vraiment m'aider sur celui-ci.GLSL: activer/désactiver texturing + shaders

Dans l'exemple, je travaille sur deux j'ai les shaders suivants:

Vertex:

void main() 
{ 
    gl_FrontColor = gl_Color; 
    gl_TexCoord[0] = gl_MultiTexCoord0; 
    gl_Position = ftransform(); 
} 

Fragment:

uniform sampler2D tex; 
uniform float flattening; 

void main(void) 
{ 
    vec4 texel; 
    texel = texture2D(tex, gl_TexCoord[0].st); 
    texel.r *= gl_Color.r; 
    texel.g *= gl_Color.g; 
    texel.b *= gl_Color.b; 
    texel.a *= gl_Color.a; 
    gl_FragColor = texel; 
} 

Quand je suis rendu des polygones qui ne sont pas texturé, leurs valeurs alpha sont correctes, mais ils sont assignés à la couleur noire.

1, Quelle vérification conditionnelle puis-je configurer de sorte que la variable 'texel' soit définie comme vec4(1.0, 1.0, 1.0, 1.0) plutôt que d'échantillonner à partir d'une texture lorsque GL_TEXTURE_2D est désactivé?

2, Le traitement serait-il plus rapide si j'écrivais différents shaders pour différents modes de texturation et passais entre eux où j'utiliserais glEnable/glDisable (GL_TEXTURE_2D)?

+0

Remarque: vous pouvez écrire texel * = gl_Color; comme un vecteur op au lieu de 4 opérations scalaires. – Macke

+0

merci, est-ce matériel accéléré? ne serait-ce pas un appel de fonction et 4 opérations scalaires vs 4 opérations scalaires? – zyndor

+1

Il est accéléré (si vous n'exécutez pas tous les shaders dans le logiciel, auquel cas vous êtes dans un espace de secondes par trame), mais il n'y a pas d'appel de fonction supplémentaire. Il est vrai que ce sera toujours 4 opérations scalaires (sur les GPU modernes), je pense juste comme une opération vectorielle, mais il est aussi beaucoup plus facile de suivre et de déboguer le code de cette façon. (Les compilateurs GLSL alignent très fortement les choses pour éviter les surcharges d'appel de fonction.) – Macke

Répondre

8

Désolé, mais vous ne pouvez pas accéder à ce type d'état à partir de GLSL, point.

En fait, dans le futur GLSL, vous devez envoyer vous-même tous les unforms/attributs, c'est-à-dire pas de glagelmagix, de gl_lightPosition, de gl_Normal ou autres. Seuls les éléments de base comme gl_Position et gl_FragColor seront disponibles. Cela annule votre deuxième question, mais vous pouvez toujours utiliser # ifdef pour activer/désactiver des parties de votre shader si cela vous semble plus pratique que d'écrire des shaders séparés pour différents modes de texture. Relié, notez que la ramification est généralement plutôt lente, donc si vous avez besoin de vitesse, évitez-la autant que possible. (Cela concerne en particulier les branchements dynamiques irréguliers, car les fragments sont traités dans des blocs SIMD et tous les fragments d'un bloc doivent calculer les mêmes instructions, même s'ils ne s'appliquent qu'à un ou plusieurs fragments.)

+0

merci pour la réponse en profondeur. Je viens de me rendre compte (à part que j'ai couru dans le mur de l'esprit) que je pouvais simplement déclarer un bool pour les activés/désactivés et acheminer les appels liés à cela. – zyndor

+0

C'est faisable, mais ne sera pas rapide. – Macke

3

Une méthode que j'ai vue est de lier une texture 1x1 avec un seul texel de (1.0, 1.0, 1.0, 1.0) lors du rendu de polygones non texturés. Un commutateur de texture devrait être moins cher qu'un commutateur de shader et une texture 1x1 s'adaptera entièrement à l'intérieur du cache de texture.

Questions connexes