shader glsl compilation problème lors de l'exécution
Je suis en train de travailler sur un projet qui utilise OpenGL 4.0 shaders.
J'ai pour l'alimentation de l'appel à glShaderSource() avec un tableau de tableaux de char, qui représente la source de l'ombrage.
Le shader de la compilation échoue avec l'erreur suivante:
(0) : error C0206: invalid token "<null atom>" in version line
(0) : error C0000: syntax error, unexpected $end at token "<EOF>"
Voici mon (hello world) shader - directement à partir de OpenGL 4.0 shading language livre de cuisine
#version 400
in vec3 VertexPosition;
in vec3 VertexColor;
out vec3 Color;
void main()
{
Color = VertexColor;
gl_Position = vec4( VertexColor, 1.0 );
}
Et voici mon code pour lire le fichier shader dans mon code C++, et de compiler le shader à l'exécution:
const int nMaxLineSize = 1024;
char sLineBuffer[nMaxLineSize];
ifstream stream;
vector<string> vsLines;
GLchar** ppSrc;
GLint* pnSrcLineLen;
int nNumLines;
stream.open( m_sShaderFile.c_str(), std::ios::in );
while( (stream.good()) && (stream.getline(sLineBuffer, nMaxLineSize)) )
{
if( strlen(sLineBuffer) > 0 )
vsLines.push_back( string(sLineBuffer) );
}
stream.close();
nNumLines = vsLines.size();
pnSrcLineLen = new GLint[nNumLines];
ppSrc = new GLchar*[nNumLines];
for( int n = 0; n < nNumLines; n ++ )
{
string & sLine = vsLines.at(n);
int nLineLen = sLine.length();
char * pNext = new char[nLineLen+1];
memcpy( (void*)pNext, sLine.c_str(), nLineLen );
pNext[nLineLen] = 'const int nMaxLineSize = 1024;
char sLineBuffer[nMaxLineSize];
ifstream stream;
vector<string> vsLines;
GLchar** ppSrc;
GLint* pnSrcLineLen;
int nNumLines;
stream.open( m_sShaderFile.c_str(), std::ios::in );
while( (stream.good()) && (stream.getline(sLineBuffer, nMaxLineSize)) )
{
if( strlen(sLineBuffer) > 0 )
vsLines.push_back( string(sLineBuffer) );
}
stream.close();
nNumLines = vsLines.size();
pnSrcLineLen = new GLint[nNumLines];
ppSrc = new GLchar*[nNumLines];
for( int n = 0; n < nNumLines; n ++ )
{
string & sLine = vsLines.at(n);
int nLineLen = sLine.length();
char * pNext = new char[nLineLen+1];
memcpy( (void*)pNext, sLine.c_str(), nLineLen );
pNext[nLineLen] = '\0';
ppSrc[n] = pNext;
pnSrcLineLen[n] = nLineLen+1;
}
vsLines.clear();
//just for debugging purposes (lines print out just fine..)
for( int n = 0; n < nNumLines; n ++ )
ATLTRACE( "line %d: %s\r\n", n, ppSrc[n] );
//Create the shader
m_nShaderId = glCreateShader( m_nShaderType );
//Compile the shader
glShaderSource( m_nShaderId, nNumLines, (const GLchar**)ppSrc, (GLint*) pnSrcLineLen );
glCompileShader( m_nShaderId );
//Determine compile status
GLint nResult = GL_FALSE;
glGetShaderiv( m_nShaderId, GL_COMPILE_STATUS, &nResult );
';
ppSrc[n] = pNext;
pnSrcLineLen[n] = nLineLen+1;
}
vsLines.clear();
//just for debugging purposes (lines print out just fine..)
for( int n = 0; n < nNumLines; n ++ )
ATLTRACE( "line %d: %s\r\n", n, ppSrc[n] );
//Create the shader
m_nShaderId = glCreateShader( m_nShaderType );
//Compile the shader
glShaderSource( m_nShaderId, nNumLines, (const GLchar**)ppSrc, (GLint*) pnSrcLineLen );
glCompileShader( m_nShaderId );
//Determine compile status
GLint nResult = GL_FALSE;
glGetShaderiv( m_nShaderId, GL_COMPILE_STATUS, &nResult );
Le code C++ s'exécute comme prévu, mais le shader de la compilation échoue. Quelqu'un peut-il repérer ce que je fais de mal?
J'ai le sentiment que cela peut être à faire avec les caractères de fin de ligne en quelque sorte, mais comme c'est ma première tentative à l'shader compilation, je suis coincé!
J'ai lu d'autres AFIN de réponses sur le shader de la compilation, mais ils semblent spécifiques à Java /d'autres langues, pas du C++. Si cela peut aider, je suis sur la plate-forme win32.
Je ne suis pas sûr de suivre. Le fichier shader doit être compilé en glsl lors de l'exécution de mon programme. Mais je ne pense pas que le shader est en faute. Le shader est un simple bonjour tout le monde, prises à partir d'un livre. Je pense que le problème est peut-être à voir avec les caractères de saut de ligne.
Pas que ce soit une erreur, mais pourquoi est-vertexcolor utilisé dans la position?
C'est juste un exemple tiré d'un livre. Le code du shader n'est pas la question ici, je pense que le problème peut être à voir avec la façon dont il est fourni à la glShaderSource (), ou une ligne d'analyse de problème.
OriginalL'auteur | 2011-11-06
Vous devez vous connecter pour publier un commentaire.
Juste un petit pressentiment:
Avez-vous essayé d'appeler glShaderSource avec NULL comme paramètre de durée? Dans ce cas, OpenGL va assumer votre code doit être null.
(Édité à cause de la stupidité)
+1 pour me pointer dans la bonne direction 😉
Ah, oui, bon, désolé pour ça... gosh, c'est gênant, mais c'est dans le milieu de la nuit ici 😀
S'il vous plaît ne pas utiliser un code de chargement de chaque ligne en
glShaderSource
comme une chaîne distincte. Il suffit de ne pas le faire.Il semble que vous simplement accepté la mauvaise réponse. Et non, ce n'est pas subjective dicision (et ne devrait pas être un hasard).
OriginalL'auteur Shelling
Vous avez fait une erreur que d'autres ont fait. C'est la définition de
glShaderSource
:La
string
est un tableau de chaînes de caractères. Il est pas destiné à être un tableau de lignes dans votre shader. La manière dont le compilateur va interpréter ce tableau de chaînes est par la concaténation de l'ensemble, l'un après l'autre. Sans retours à la ligne.Depuis
stream.getline
sera pas mettre le\n
caractère de la chaîne, chaque shader chaînes de vous générer n'aura pas de saut de ligne à la fin. Par conséquent, lorsqueglShaderSource
va à la compilation, votre shader ressemblera à ceci:Ce n'est pas légal GLSL.
La bonne façon de le faire est de charger le fichier en tant que chaîne de caractères.
Alors vous pouvez simplement passer le long de
glShaderSource
assez facilement:Si vous avez copié ce code de chargement de quelque part, alors je vous suggère fortement de trouver un autre endroit pour apprendre OpenGL. Parce que c'est terrible de codage.
OriginalL'auteur Nicol Bolas
Je sais que la signature de glShaderSource semble tentant d'envoyer chaque ligne du shader séparément. Mais c'est maintenant ce que cela signifiait. Au point d'être en mesure d'envoyer de multiples tableaux est ainsi que l'on peut mélanger plusieurs primitives shader sources en un seul shader, un genre de fichiers à inclure. La compréhension de ce, fait qu'il est beaucoup plus simple à lire dans un fichier shader – et évite de ces vilaines bestioles.
À l'aide de C++, vous pouvez faire beaucoup plus agréable et plus propre. J'ai déjà écrit le follwing dans Obtenir des ordures caractères lors de la lecture de fichiers GLSL
Vous êtes à l'aide de C++, donc je vous suggère d'en tirer parti. Au lieu de lire dans une auto alloué char tableau, je vous suggère de lire dans un std::string:
Qui prend automatiquement soin de l'allocation de la mémoire et de la bonne délimitation -- le mot-clé est RAII: l'Allocation des Ressources Est l'Initialisation. Plus tard, vous pouvez télécharger le code source avec quelque chose comme
Vous pouvez utiliser ces deux fonctions comme ceci:
OriginalL'auteur datenwolf