简体   繁体   中英

ERROR: 0:2: 'attribute' : cannot initialize this type of qualifier (whatever GLSL version used from 1.1 till 1.5)

I followed the developpez tuto about GLSL, http://alexandre-laurent.developpez.com/tutoriels/OpenGL/OpenGL-GLSL ; I downloaded the final project proposed by the author, everything work fine except this line of code:

ERROR: 0:2: 'attribute' :  cannot initialize this type of qualifier

Here is the vert file contents:

#version 120
attribute vec3 couleur = vec3(0.0,1.0,0.0);

void main (void)
{
    gl_Position = ftransform(); 
    gl_FrontColor = vec4(couleur,1.0);
}

And the frag file

#version 120
void main(void)
{
    gl_FragColor = gl_Color;
}

Even when I change the version to 140, 150, 110, i keep getting this error code, thought the spashscreen showed by the author show all working;

I'm on Intel(R) HD graphics 775Mb if it helps

Here is my main.cpp file (I changed nothing in it, it uses freeglut as renderer):

#include <GL/glew.h>

#include <GL/freeglut.h>
/*
#include <GL/gl.h>
#include <GL/glu.h>
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// Déclaration des points de notre cube
GLfloat cubeVertices[] =
{
    // Face de devant
    1,1,1,
    -1,1,1,
    -1,-1,1,
    1,-1,1,

    1, 1, -1,
    -1, 1, -1,

    -1, -1, -1,
    1, -1, -1,
};

GLfloat cubeColours[] =
{
    1, 0, 0,
    0, 1, 0,
    0, 1, 0,
    1, 0, 0,

    0, 0, 1,
    1, 1, 0,

    1, 1, 0,
    0, 0, 1,
};

GLubyte cubeIndices[] =
{
    0, 1, 2, 3,
    0, 4, 7, 3,
    4, 5, 6, 7,
    1, 2, 6, 5,
    2, 3, 7, 6,
    0, 1, 5, 4
};

GLuint vertexID = 0;
GLuint fragmentID = 0;
GLuint programID = 0;

GLint attributeId = 0;

unsigned int getFileSize(FILE* const pFile)
{
    long length = 0;

    fseek(pFile,0,SEEK_END);

    length = ftell(pFile);

    // Ne pas oublier de mettre le fichier à son début, sinon on ne peut pas le lire
    fseek(pFile,0,SEEK_SET);

    return length;
}

/**
    Le fonction retourne un pointeur, qui a été alloué dans la fonction même.
    ! Ceci est extrèmement dangereux car cela peut entrainer des fuites de mémoire
    du à l'oubli de libéré le pointeur.
*/
char* readFile(const char* fileName)
{
    FILE* pFile = NULL;
    char* fileContent = NULL;
    unsigned int fileSize = 0;

    pFile = fopen(fileName,"r");
    if ( pFile == NULL )
    {
        fprintf(stderr,"Erreur d'ouverture du fichier: '%s'\n",fileName);
        return NULL;
    }

    fileSize = getFileSize(pFile);

    fileContent = (char*)malloc(fileSize+1);
    if ( fileContent == NULL )
    {
        fprintf(stderr,"Erreur d'allocation de la mémoire pour y placer le contenu du fichier\n");
        return NULL;
    }

    fread(fileContent,fileSize,1,pFile);
    // Termine le tableau qui contient le shader
    fileContent[fileSize] = '\0';

    fclose(pFile);

    return fileContent;
}

void deleteShader()
{
    // On arrête d'utiliser le programme shader
    glUseProgram(0);

    // Deliage des shaders au programme
    glDetachShader(programID, fragmentID);
    glDetachShader(programID, vertexID);

    // Destruction du programme
    glDeleteProgram(programID);

    // Destruction des IDs des shaders
    glDeleteShader(fragmentID);
    glDeleteShader(vertexID);
}

// Pour plus de simplicité, j'ajoute une fonction qui vérifie la compilation des shaders
char checkShaderCompilation(GLuint shaderID)
{
    GLint compilationStatus = 0;

    // Verification de la compialtion pour le vertex shader
    glGetShaderiv(vertexID, GL_COMPILE_STATUS, &compilationStatus);
    if ( compilationStatus != GL_TRUE )
    {
        // Nous savons que la compilation a échoué, donc nous devons savoir pourquoi
        // Nous devons récupéré la taille du log
        GLint logLength = 0;
        GLchar* log = NULL;

        glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLength);

        // Maintenant que nous avons la taille, nous pouvons alloué la mémoire suffisante pour ce log
        log = (GLchar*)malloc(logLength);
        if ( log == NULL )
        {
            fprintf(stderr,"Erreur d'allocation de mémoire pour le log de la compilation du shader\n");
            return 0;
        }

        glGetShaderInfoLog(shaderID, logLength, &logLength, log);

        // On peut afficher le message
        fprintf(stderr,"Erreur de compilation:\n%s",log);

        // Et on n'oublie pas de libéré la mémoire
        free(log);

        return 0;
    }

    return 1; // Pas d'erreur
}

void loadShader()
{
    GLchar* vertexSource = NULL;
    GLchar* fragmentSource = NULL;
    GLint programState = 0;
    GLint vertexSize = 0;
    GLint fragmentSize = 0;
    GLenum errorState = GL_NO_ERROR;

    // Création des IDs
    vertexID = glCreateShader(GL_VERTEX_SHADER);
    fragmentID = glCreateShader(GL_FRAGMENT_SHADER);

    // Lecture des fichiers
    // Certaines personnes aiment avoir le fichier du vertex shader avec l'extion .vert
    // et le fichier du fragement shader avec l'extension .frag
    vertexSource = (GLchar*)readFile("data/simple.vert");
    fragmentSource = (GLchar*)readFile("data/simple.frag");

    if ( !vertexSource || !fragmentSource )
    {
        // Ici, il faudrait faire en sorte que le programme s'arrête
        deleteShader();    // Nettoyage
        return;
    }

    // Chargement des sources dans OpenGL
    vertexSize = strlen(vertexSource);
    fragmentSize = strlen(fragmentSource);
    glShaderSource(vertexID, 1, (const GLchar**)(&vertexSource), &vertexSize);
    glShaderSource(fragmentID, 1, (const GLchar**)(&fragmentSource), &fragmentSize);

    // Compilation du vertex shader
    glCompileShader(vertexID);
    glCompileShader(fragmentID);

    // Vérification des erreurs
    if ( !checkShaderCompilation(vertexID) || !checkShaderCompilation(fragmentID))
    {
        deleteShader();
        return;
    }


    // Creation de l'ID pour le programme
    programID = glCreateProgram();

    // On attache les shader ensemble
    glAttachShader(programID, vertexID);
    glAttachShader(programID, fragmentID);

    // On peut enfin passer aux liage.
    glLinkProgram(programID);

    // Et encore une fois on vérifie si tout se passe bien
    glGetProgramiv(programID , GL_LINK_STATUS  , &programState);
    if ( programState != GL_TRUE)
    {
        // On récupère la taille du log
        GLint logSize = 0;
        GLchar* log = NULL;

        glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &logSize);

        // On peut allouer la mémoire, une fois que l'on a la taille du log
        log = (GLchar*)malloc(logSize);
        if ( log == NULL )
        {
            fprintf(stderr,"Erreur d'allocation de mémoire pour le log de la compilation du programme\n");
            deleteShader();
            return;
        }

        // Et on récupère le log
        glGetProgramInfoLog(programID, logSize, &logSize, log);

        // On affiche
        fprintf(stderr,"Erreur lors du liage du shader:\n%s",log);

        free(log);
        deleteShader();
        return;
    }

    attributeId = glGetAttribLocation(programID, "couleur");
    errorState = glGetError();
    if ( attributeId == -1 || errorState != GL_NO_ERROR )
    {
        fprintf(stderr,"Erreur (%d) lors de la récupération de l'id de la variable attribute 'couleur'\n",errorState);
    }

    // Voilà, nous sommes prêt
    glUseProgram(programID);

    glEnableVertexAttribArray(attributeId);
    errorState = glGetError();

    glVertexAttribPointer(attributeId,
                          3,
                          GL_FLOAT,
                          GL_TRUE,
                          0,
                          cubeColours);

    if ( errorState != GL_NO_ERROR )
    {
        fprintf(stderr,"Erreur (%d) lors du passage du tableau de valeur à la variable attribute 'couleur'\n",errorState);
    }
}

void initScene()
{
    glClearColor(0.0,0.5,0.0,1.0);

    // Depth
    glClearDepth(1.0);
    glDepthFunc(GL_LESS);
    glEnable(GL_DEPTH_TEST);

    // Perspective mode
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluPerspective(45.0f,(GLfloat)640/(GLfloat)480,0.1f,100.0f);

    glMatrixMode(GL_MODELVIEW);

    loadShader();

    // Init the cube
        // Tell to OpenGL that we are using :
        //  - Vertices
        //  - Colours
    glEnableClientState(GL_VERTEX_ARRAY);
    //glEnableClientState(GL_COLOR_ARRAY);

    // Assign our data to OpenGL
    glVertexPointer(3, GL_FLOAT, 0, cubeVertices);
    //glColorPointer(3, GL_FLOAT, 0, cubeColours);
}

void renderScene()
{
    // Rotation stuff
    static unsigned int rotationAngle;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    gluLookAt(-2,5,-4,
              0,0,0,
              0,1,0);

    glRotated(rotationAngle, 1, 1, 0);

    // draw the cube
    glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, cubeIndices);

    if ( glGetError() != GL_NO_ERROR )
    {
        fprintf(stderr,"Error occur during drawing");
        return;
    }

    glutSwapBuffers();

    rotationAngle++;
}

void quitScene()
{
    glDisableVertexAttribArray(attributeId);
    //glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);

    deleteShader();
}

void keyboardFeedback(unsigned char key, int x, int y)
{
    if ( key == 27 ) // Escape
    {
        quitScene();
        glutLeaveMainLoop();
    }
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);

    glutInitWindowPosition(-1, -1);
    glutInitWindowSize(640,480);

    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE |GLUT_DEPTH);

    glutCreateWindow("OpenGL Shaders");

    // Demarrage de GLEW
    if ( glewInit() != GLEW_OK )
    {
        fprintf(stderr,"Echec du demarrage de GLEW\n");
        return -1;
    }

    // On vérifie que l'on peut géré les shaders
    // Check if the machine is capable of rendering our scene
    if ( !glewIsSupported("GL_ARB_shading_language_100") )
    {
        fprintf(stderr,"GL_ARB_shading_language_100 introuvables\n");
        return -2;
    }
    if ( !glewIsSupported("GL_ARB_shader_objects") )
    {
        fprintf(stderr,"GL_ARB_shader_objects introuvables\n");
        return -3;
    }
    if ( !glewIsSupported("GL_ARB_vertex_shader") )
    {
        fprintf(stderr,"GL_ARB_vertex_shader introuvables\n");
        return -4;
    }
    if ( !glewIsSupported("GL_ARB_fragment_shader") )
    {
        fprintf(stderr,"GL_ARB_fragment_shader introuvables\n");
        return -5;
    }

    initScene();
    // glutDisplayFunc(renderScene);
    glutKeyboardFunc(keyboardFeedback);
    glutIdleFunc(renderScene);

    glutMainLoop();

    quitScene();

    return 0;
}

Please help:p

The problem lies in this line:

attribute vec3 couleur = vec3(0.0,1.0,0.0);

As the message states, it is not allowed in GLSL to initialize attributes. They have to be filled from outside the program. Change the line to

attribute vec3 couleur;

then the shader will compile. But you will still have to attach some data to the attribute.

do this:

    if(solidColor) {gl.vertexAttrib4f(program.colorVertLocation, red, green, blue, alpha);}
    if(!solidColor) {gl.enableVertexAttribArray(program.colorVertLocation);}

if sometimes want one color for all vertices, you can set the default attribute value with "vertexAttrib4f", then any time you dont enable the the vertex attribute array, it will use that default value instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM