Question

I'm doing my first steps in OpenGl Shader base programming and computer graphics. I'm trying the following example, but when I try to compile the project I got the following error:

fragment shader failed to link. vertex shader failed to link. ERROR: Not all shaders has valid object code

i tried running the program in Visual Studio 2012 and 2010. glut library version is 3.7 and glew library version is 1.10.0. what is the problem?

.cpp Program

#include <stdio.h>
#include <stdlib.h>
#include <glew.h>
#include <glut.h>
#include <gl.h>


#pragma comment(lib,"glew32.lib")
#define NoP 50000

GLuint InitShader(char *, char *);
void mydisplay();


struct points
{   GLfloat x,y,z;
};
void init();
void Sierpinski(points Num[]);

int main(int argc, char** argv)
    {
    glutInit(&argc,  argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE|GLUT_DEPTH);
    glutInitWindowSize(600, 600);
    glutInitWindowPosition(0,0);
    glutCreateWindow("Sierpinski 3D");
    glewInit();
    init();
    glEnable(GL_DEPTH_TEST);
    glutDisplayFunc(mydisplay);
    glutMainLoop();
}

void init()
{
    points  Num[NoP];
    Sierpinski(Num);

    glClearColor(1.0f, 1.0f, 1.0f, 0.0f);//set the color for clearing the display
    glPointSize(2); // set the point size
    // Creating a program object containing shader files
    GLuint program;
    program = InitShader("vshader.glsl","fshader.glsl");
    glUseProgram(program);

    //Creating a buffer object containing Sirepinski verteces data
    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Num), Num, GL_STATIC_DRAW);

    //Make a conncetion between data in object buffer and "vPosition in vertex shader
    GLuint location = glGetAttribLocation(program, "vPosition");
    glEnableVertexAttribArray ( location );
    glVertexAttribPointer( location, 3, GL_FLOAT, GL_FALSE,0, 0);//BUFFER_OFFSET(0));
}
void mydisplay()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //the clear call will affect the color buffer
    glDrawArrays(GL_POINTS,0,NoP);//Rendering verteces data
    glFlush();  //Empty all commands buffer, causing all issued commands to be executed as quickly as they are accepted by the actual rendering engine
}

static char * ReadShaderSource(char * ShaderFile)
{
    FILE *fp;
    fp = fopen(ShaderFile,"rt");
    if (!fp) return NULL;
    long size=0;
    while (!feof(fp))
    {
      fgetc (fp);
      size++;
    }
    size--;//EOF should not be counted
    fseek(fp, 0, SEEK_SET);
    char * buf= new char[size + 1];
    fread(buf, 1, size,fp);
    buf[size]=0;// string is NULL terminated
    fclose(fp);
    return buf;
}
GLuint InitShader(char * vShaderFile, char * fShaderFile)
{ 
    char * svs, * sfs; 
    GLuint program, VertexShader, FragmentShader;
    program = glCreateProgram();
    VertexShader =  glCreateShader(GL_VERTEX_SHADER);
    svs=ReadShaderSource(vShaderFile);
    glShaderSource(VertexShader,1,(const GLchar **)&svs,NULL);
    glCompileShader(VertexShader);

    // reading GLSL compiler error messages for vertex shader
    GLint compiled;
    glGetShaderiv(VertexShader, GL_COMPILE_STATUS, &compiled);
    if(!compiled)
    {   printf("/n failed to compile");
        GLint logSize;
        glGetShaderiv(VertexShader, GL_INFO_LOG_LENGTH,&logSize);
        char * logMsg = new char[logSize];
        glGetShaderInfoLog(VertexShader, logSize, NULL, logMsg);
        printf("\n  %s",logMsg);
        delete [] logMsg;
        getchar();
        exit(EXIT_FAILURE);
    }

    FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    sfs = ReadShaderSource(fShaderFile);
    glShaderSource(FragmentShader, 1, (const GLchar **)&sfs, NULL);
    glCompileShader(FragmentShader);

    // reading GLSL compiler error messages for fragment shader
    glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &compiled);
    if(!compiled) 
    {   printf("\n failed to compile");
        GLint logSize2;
        glGetShaderiv(FragmentShader, GL_INFO_LOG_LENGTH,&logSize2);
        char * logMsg2 = new char[logSize2];
        glGetShaderInfoLog(FragmentShader, logSize2, NULL, logMsg2);
        printf("\n  %s",logMsg2);
        delete [] logMsg2;
        getchar();
        exit(EXIT_FAILURE);
    }
    glAttachShader(program,VertexShader);
    glAttachShader(program, FragmentShader);
    glLinkProgram(program);
    // reading GLSL linker error messages for program object
    GLint linked;
    glGetProgramiv(program, GL_LINK_STATUS, &linked);
    if(!linked)
    {   printf("/n failed to link");
        GLint logSize;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH,&logSize);
        char * logMsg = new char[logSize];
        glGetProgramInfoLog(program, logSize, NULL, logMsg);
        printf("\n  %s",logMsg);
        delete [] logMsg;
        getchar();
        exit(EXIT_FAILURE);
    }

    glUseProgram(program);
    return program;
}
void Sierpinski(points Num[])
{
    int j;
    points  Vertices[4]={{-1.0,-1.0, -1.0},{1.0,-1.0,-1.0},{0.0,1.0,-1.0},{0.0,0.0,1.0}};
    Num[0].x = 0;
    Num[0].y = 0;
    Num[0].z = 0;
    for(int i=1;i<NoP;i++)
    {
        j = rand()  % 4;
        Num[i].x = (Vertices[j].x + Num[i - 1].x)/2;
        Num[i].y = (Vertices[j].y + Num[i - 1].y)/2;
        Num[i].z = (Vertices[j].z + Num[i - 1].z)/2;
    }

}

vshader.glsl

#version 130
in vec4 vPosition;
out vec4 color;
void main()
{  

    gl_Position = vPosition;
    color = vPosition;
}

fshader.glsl

#version 130
in vec4 color;
void main()
{
    gl_FragColor = vec4((1.0 + color.xyz)/2.0,1.0);
}
Was it helpful?

Solution

Seems to work fine:

triangle

#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>

void CheckStatus( GLuint obj )
{
    GLint status = GL_FALSE;
    if( glIsShader(obj) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
    if( glIsProgram(obj) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
    if( status == GL_TRUE ) return;
    GLchar log[ 1 << 17 ] = { 0 };
    if( glIsShader(obj) ) glGetShaderInfoLog( obj, sizeof(log), NULL, log );
    if( glIsProgram(obj) ) glGetProgramInfoLog( obj, sizeof(log), NULL, log );
    std::cerr << log << std::endl;
    exit( -1 );
}

void AttachShader( GLuint program, GLenum type, const char* src )
{
    GLuint shader = glCreateShader( type );
    glShaderSource( shader, 1, &src, NULL );
    glCompileShader( shader );
    CheckStatus( shader );
    glAttachShader( program, shader );
    glDeleteShader( shader );
}

GLuint LoadProgram( const char* vert, const char* geom, const char* frag )
{
    GLuint prog = glCreateProgram();
    if( vert ) AttachShader( prog, GL_VERTEX_SHADER, vert );
    if( geom ) AttachShader( prog, GL_GEOMETRY_SHADER, geom );
    if( frag ) AttachShader( prog, GL_FRAGMENT_SHADER, frag );
    glLinkProgram( prog );
    CheckStatus( prog );
    return prog;
}

#define GLSL(version, shader) "#version " #version "\n" #shader

const char* vert = GLSL
(
    130,
    in vec4 vPosition;
    out vec4 color;
    void main()
    {  
        gl_Position = vPosition;
        color = vPosition;
    }
);

const char* frag = GLSL
(
    130,
    precision mediump float;
    in vec4 color;
    void main()
    {
        gl_FragColor = vec4((1.0 + color.xyz)/2.0,1.0);
    }
);


#define NoP 50000

struct points
{   
    GLfloat x,y,z;
};

void Sierpinski(points Num[])
{
    int j;
    points  Vertices[4]={{-1.0,-1.0, -1.0},{1.0,-1.0,-1.0},{0.0,1.0,-1.0},{0.0,0.0,1.0}};
    Num[0].x = 0;
    Num[0].y = 0;
    Num[0].z = 0;
    for(int i=1;i<NoP;i++)
    {
        j = rand()  % 4;
        Num[i].x = (Vertices[j].x + Num[i - 1].x)/2;
        Num[i].y = (Vertices[j].y + Num[i - 1].y)/2;
        Num[i].z = (Vertices[j].z + Num[i - 1].z)/2;
    }
}

void init()
{
    points  Num[NoP];
    Sierpinski(Num);

    GLuint program = LoadProgram( vert, NULL, frag );
    glUseProgram(program);

    //Creating a buffer object containing Sirepinski verteces data
    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Num), Num, GL_STATIC_DRAW);

    //Make a conncetion between data in object buffer and "vPosition in vertex shader
    GLuint location = glGetAttribLocation(program, "vPosition");
    glEnableVertexAttribArray ( location );
    glVertexAttribPointer( location, 3, GL_FLOAT, GL_FALSE,0, 0);//BUFFER_OFFSET(0));
}

void mydisplay()
{
    glClearColor(1.0f, 1.0f, 1.0f, 0.0f);//set the color for clearing the display
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //the clear call will affect the color buffer

    glPointSize(2); // set the point size
    glDrawArrays(GL_POINTS,0,NoP);//Rendering verteces data

    glutSwapBuffers();
}

int main(int argc, char** argv)
{
    glutInit(&argc,  argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE|GLUT_DEPTH);
    glutInitWindowSize(600, 600);
    glutInitWindowPosition(0,0);
    glutCreateWindow("Sierpinski 3D");
    glewInit();
    init();
    glEnable(GL_DEPTH_TEST);
    glutDisplayFunc(mydisplay);
    glutMainLoop();
}

Make sure you use FreeGLUT, Nate's GLUT is way, way old.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top