2012-05-11 3 views
1

J'ai un problème où mon code 130 glsl ne fonctionnera pas correctement sur mon matériel un peu moderne (ATI 5850) tandis que le code identique fonctionne parfaitement bien sur un ordinateur portable plus ancien avec une carte NVIDIA que j'ai .. Ceci est le cas no mater quel contexte opengl j'utilise. Ce qui se passe, ce sont les vecteurs: in_position, in_colour et in_normal ne se lient pas correctement sur le nouveau matériel. Il semble que je suis obligé d'utiliser une version plus récente de glsl (330) sur un nouveau matériel.opengl 3.3+ non compatible avec le code glsl 130?

Voici le code glsl pour le vertex shader. C'est assez simple et basique.

#version 130 

uniform mat4 projectionMatrix; 
uniform mat4 viewMatrix; 
uniform mat4 modelMatrix; 
uniform mat4 normalMatrix; 

in vec4 in_position; 
in vec4 in_colour; 
in vec3 in_normal; 

out vec4 pass_colour; 

smooth out vec3 vNormal; 

void main() 
{ 
    gl_Position = projectionMatrix * viewMatrix * modelMatrix * in_position; 
    vec4 vRes = normalMatrix*vec4(in_normal, 0.0); 
    vNormal = vRes.xyz; 
    pass_colour = in_colour; 
} 

Qu'advient est données pour:

in vec4 in_position; 
in vec4 in_colour; 
in vec3 in_normal; 

ne se lie pas ou pas complètement. Les valeurs sont étrangement déformées. De mes tests tout fonctionne correctement. La modification de la version à 330 et l'utilisation du mot clé location corrige le problème, mais cela rend également le code non compatible avec les anciennes versions d'opengl ...

Voici un exemple du code que j'utilise pour spécifier ces emplacements.

pour le programme:

glBindAttribLocation(LD_standard_program, 0, "in_position"); 
glBindAttribLocation(LD_standard_program, 1, "in_colour"); 
glBindAttribLocation(LD_standard_program, 2, "in_normal"); 

et plus tard pour les données lui-même:

--- code to buffer vertex data 
glEnableVertexAttribArray(0); 
glVertexAttribPointer((GLuint) 0, 4, GL_FLOAT, GL_FALSE, 0, 0); 
--- code to buffer colour data 
glEnableVertexAttribArray(1); 
glVertexAttribPointer((GLuint) 1, 4, GL_FLOAT, GL_FALSE, 0, 0); 
--- code to buffer normal data 
glEnableVertexAttribArray(2); 
glVertexAttribPointer((GLuint) 2, 3, GL_FLOAT, GL_FALSE, 0, 0); 

Ma question est: est-ce pas opengl censé être rétrocompatible ?? Je commence à avoir peur que je doive écrire des shaders séparés pour une seule version d'opengl pour faire fonctionner mon programme sur un matériel différent ... Depuis que ces attributs sont liés à une fonctionnalité très basique, je doute que ce soit un bug dans l'implémentation ATI ...

+0

Il est plus probable que votre code ait rencontré un bogue NVIDIA qui a permis à votre code non conforme de fonctionner ou un bogue ATI qui a provoqué l'échec du code conforme. Ou les deux. De toute façon, où avez-vous mis le code pour lier vos attributs de vertex? –

+0

Pouvez-vous élaborer sur «ne pas lier ou pas complètement»? Qu'est-ce que ça veut dire? Des erreurs glGetErrors ou des liens de shader? – Tim

Répondre

1

Appellez-vous glBindAttribLocation avant glLinkProgram? L'appel après ne donnera aucun effet, car les attributs de vertex ne sont assignés que pendant glLinkProgram.

En GLSL 3.30+ il y a une meilleure façon d'indices specifiying d'attributs directement dans le code GLSL:

layout(location=0) in vec4 in_position; 
layout(location=1) in vec4 in_colour; 
layout(location=2) in vec3 in_normal; 

Edit: oh, je sauté la partie que vous avez essayé mot-clé de mise en page déjà.

+0

Non J'appelle glLinkProgram en premier lorsque je crée le programme. Je sais à propos de la disposition (emplacement = 0) etc ... J'ai glsl 330 code écrit qui fonctionne très bien. Dans ce cas, je présente le code que j'ai écrit pour rendre mon application compatible avec le matériel plus ancien qui ne peut pas exécuter de nouvelles versions de glsl. Ce code fonctionne bien pour les anciennes versions, mais pas les plus récentes. Je suis confus car j'étais sous l'impression que l'opengl était rétrocompatible. Cependant je trouve dans mon cas que le code de glsl 130 fonctionne bien sur le matériel plus ancien mais pas plus nouveau ... – kkuryllo

+0

Eh bien c'est le problème - vous appelez glLinkProgram avant glBindAttribLocation. L'index d'attribut Vertex est assigné dans l'appel glLinkProgram. Si vous n'avez pas appelé glBindAttribLocation à ce point, alors l'attribut sera assigné quel que soit l'index est libre - dans n'importe quel ordre combo pilote/gpu préfère. –

+0

Merci beaucoup. Cela corrige tout mon code juste en déplaçant cette ligne :) Je suivais un tutoriel en ligne qui l'a fait comme ça. Je viens de réaliser que mes données normales et vertex étaient échangées.C'est logique puisque je voyais tous mes polygones se fondre dans un sphère au centre. c'est-à-dire exactement 1 rayon d'unité éloigné de zéro. – kkuryllo

Questions connexes