2010-05-27 6 views
1

J'ai un peu de problème avec mon code pour compiler les shaders, à savoir qu'ils s'annulent tous deux en tant que compilations échouées et qu'aucun journal n'est reçu.Erreur OpenGL Shader Compile

Ce code est la compilation de shaders:

/* Make the shader */ 

Uint size; 
GLchar* file; 

loadFileRaw(filePath, file, &size); 

const char * pFile = file; 
const GLint pSize = size; 


newCashe.shader = glCreateShader(shaderType); 
glShaderSource(newCashe.shader, 1, &pFile, &pSize); 
glCompileShader(newCashe.shader); 

GLint shaderCompiled; 

glGetShaderiv(newCashe.shader, GL_COMPILE_STATUS, &shaderCompiled); 

if(shaderCompiled == GL_FALSE) 
{ 
    ReportFiler->makeReport("ShaderCasher.cpp", "loadShader()", "Shader did not compile", "The shader " + filePath + " failed to compile, reporting the error - " + OpenGLServices::getShaderLog(newCashe.shader)); 

} 

Et ce sont les fonctions support:

bool loadFileRaw(string fileName, char* data, Uint* size) 
{  
    if (fileName != "") 
    { 
     FILE *file = fopen(fileName.c_str(), "rt"); 

     if (file != NULL) 
     { 
      fseek(file, 0, SEEK_END); 
      *size = ftell(file); 
      rewind(file); 

      if (*size > 0) 
      { 
       data = (char*)malloc(sizeof(char) * (*size + 1)); 
       *size = fread(data, sizeof(char), *size, file); 
       data[*size] = '\0'; 
      } 

      fclose(file); 
     } 
    } 

    return data; 
} 

string OpenGLServices::getShaderLog(GLuint obj) 
{ 
    int infologLength = 0; 

    int charsWritten = 0; 
    char *infoLog; 

    glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infologLength); 

    if (infologLength > 0) 
    { 
     infoLog = (char *)malloc(infologLength); 
     glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog); 

     string log = infoLog; 

     free(infoLog); 

     return log; 
    } 

    return "<Blank Log>"; 
} 

et les shaders que je suis chargement:

void main(void) 
{ 
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); 
} 

void main(void) 
{ 
    gl_Position = ftransform(); 
} 

En bref, je obtenir

From: ShaderCasher.cpp, In: loadShader(), Subject: Shader did not compile 
Message: The shader Data/Shaders/Standard/standard.vs failed to compile, reporting the error - <Blank Log> 

pour chaque shader que je compile.

J'ai essayé de remplacer la lecture du fichier avec juste une chaîne codée en dur, mais j'ai la même erreur, donc il doit y avoir quelque chose de mal dans la façon dont je les compile. J'ai couru et compilé des exemples de programmes avec des shaders, donc je doute que mes drivers soient en cause, mais en tout cas je suis sur une Nvidia 8600m GT.

Quelqu'un peut-il aider?

+0

Ce n'est pas un doublon exact, mais vous pourriez trouver cette réponse utile: http: // stackoverflow.com/questions/2795044/facile-cadre-pour-opengl-shaders-in-c-c/2796153 # 2796153 –

+0

êtes-vous 'free()' -donnez votre 'data' n'importe où après loadFileRaw()'? À moins de manquer quelque chose, je vois une fuite de mémoire. –

+0

Je prévoyais de mettre en cache ou d'afficher le code source du shader quelque part si la compilation échouait, mais je n'ai pas actuellement un enregistreur suffisamment sophistiqué pour le faire dans un format facile à lire. Je savais que j'avais besoin de libérer les données, mais une fois que la compilation de test échoue, vous jetez tous les autres éléments de côté pour trouver le problème. – Tomas

Répondre

4

Dans loadFileRaw, vous transmettez char *data par valeur. Ensuite, vous lui assignez:

data = (char*)malloc(sizeof(char) * (*size + 1)); 

si votre appel

loadFileRaw(filePath, file, &size); 

ne pas changer la valeur de file! Pour changer file, passer dans par pointeur:

loadFileRaw(filePath, &file, &size); 

puis changer votre fonction

bool loadFileRaw(string fileName, char** data, Uint* size) { ... } 

et en elle,

*data = (char*)malloc(sizeof(char) * (*size + 1)); 

etc. (pour les autres références à data). Cela dit, puisque vous utilisez C++, utilisez std::vector<char> ou std::string pour la gestion de la mémoire. Pour vous aider à démarrer,

{ 
    std::vector<char> data; 
    data.resize(100); // now it has 100 entries, initialized to zero 
    silly_C_function_that_takes_a_char_pointer_and_a_size(&data[0], 100); // OK 
} // presto, memory freed 

Vous pouvez également regarder dans std::ifstream pour la lecture de fichiers, au lieu d'utiliser FILE *.

+0

Ma fonction d'origine a utilisé std :: ifstream, mais j'ai copié celui affiché sur Internet une fois que j'ai eu ce problème. Urgh, maintenant je reçois un mauvais accès sur glShaderSource – Tomas

+0

Si je fais la fonction read utiliser std :: string, n'aura-t-il pas besoin d'utiliser des caractères pour les fonctions ifstream de toute façon? – Tomas

+0

@Tomas, je ne suis pas votre deuxième question, mais il semble que vous ayez des problèmes avec les pointeurs, alors pourquoi ne pas mettre les shaders en attente pendant un moment et travailler avec précaution des exemples plus simples avec des pointeurs (y compris, mais pas seulement, les cordes de style C) jusqu'à ce que vous vous sentiez plus à l'aise. –

1

Essayez avec:

glShaderSource (newCashe.shader, 1, & pfile, NULL);

Quel est l'appel le plus couramment utilisé pour charger des sources de shader.

Questions connexes