Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: OpenGL 3.1 glLinkProgram not working properly

  1. #1
    Intern Contributor
    Join Date
    Jun 2012
    Posts
    52

    OpenGL 3.1 glLinkProgram not working properly

    Following this tutorial, and making small adjustments for compatibility with OpenGL 3.1, I've managed to set up a window with freeGLUT and initialize GLEW, but I cannot draw any shapes. For some reason glUseProgram always returns GL_INVALID_OPERATION, which according to this tutorial means the program is not linked correctly. My source code is almost exactly that which works in the first tutorial, though:
    Code :
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <gl\glew.h>
    #include <GL\freeglut.h>
    #define WINDOW_TITLE_PREFIX "OpenGL Context"
     
    int numberInput;
    int CurrentWidth = 800,
    	CurrentHeight = 600,
    	WindowHandle = 0;
    unsigned FrameCount = 0;
    GLuint
    	VertexShaderId,
    	FragmentShaderId,
    	ProgramId,
    	VaoId,
    	VboId,
    	ColorBufferId;
    const GLchar* VertexShader =
    {
    	"#version 130\n"\
     
    	"layout(location=0) in vec4 in_Position;\n"\
    	"layout(location=1) in vec4 in_Color;\n"\
    	"out vec4 ex_Color;\n"\
     
    	"void main(void)\n"\
    	"{\n"\
    	"	gl_Position = in_Position;\n"\
    	"	ex_Color = in_Color;\n"\
    	"}\n"
    };
    const GLchar* FragmentShader =
    {
    	"#version 130\n"\
     
    	"in vec4 ex_Color;\n"\
    	"out vec4 out_Color;\n"\
     
    	"void main(void)\n"\
    	"{\n"\
    	"	out_Color = ex_Color;\n"\
    	"}\n"
    };
     
     
    void Initialize(int, char*[]);
    void InitWindow(int, char*[]);
    void ResizeFunction(int, int);
    void RenderFunction(void);
    void TimerFunction(int);
    void IdleFunction(void);
    void Cleanup(void);
    void CreateVBO(void);
    void DestroyVBO(void);
    void CreateShaders(void);
    void DestroyShaders(void);
     
     
    int main(int argc, char* argv[])
    {
    	Initialize(argc, argv);
     
    	glutMainLoop();
     
    	//numberInput = getchar();
     
    	exit(EXIT_SUCCESS);
    }
     
    void Initialize(int argc, char* argv[])
    {
    	GLenum GlewInitResult;
     
    	InitWindow(argc, argv);
     
    	glewExperimental = GL_TRUE;
    	GlewInitResult = glewInit();
     
    	if (GLEW_OK != GlewInitResult) {
    		fprintf(
    			stderr,
    			"ERROR: %s\n",
    			glewGetErrorString(GlewInitResult)
    			);
    		exit(EXIT_FAILURE);
    	}
     
    	fprintf(
    		stdout,
    		"INFO: OpenGL Version: %s\n",
    		glGetString(GL_VERSION)
    	);
     
    	CreateShaders();
    	CreateVBO();
     
    	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    }
     
    void InitWindow(int argc, char* argv[])
    {
    	glutInit(&argc, argv);
     
    	glutInitContextVersion(3, 1);
    	glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
    	glutInitContextProfile(GLUT_CORE_PROFILE);
    	glutSetOption(
    		GLUT_ACTION_ON_WINDOW_CLOSE,
    		GLUT_ACTION_GLUTMAINLOOP_RETURNS
    	);
     
    	glutInitWindowSize(CurrentWidth, CurrentHeight);
     
    	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
     
    	WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX);
     
    	if(WindowHandle < 1) {
    		fprintf(
    			stderr,
    			"ERROR: Could not create a new rendering window.\n"
    		);
    		exit(EXIT_FAILURE);
    	}
     
    	glutReshapeFunc(ResizeFunction);
    	glutDisplayFunc(RenderFunction);
    	glutIdleFunc(IdleFunction);
    	glutTimerFunc(0, TimerFunction, 0);
    	glutCloseFunc(Cleanup);
    }
     
    void ResizeFunction(int Width, int Height)
    {
    	CurrentWidth = Width;
    	CurrentHeight = Height;
    	glViewport(0, 0, CurrentWidth, CurrentHeight);
    }
     
    void RenderFunction(void)  // Render the scene here
    {
    	++FrameCount;
     
    	//CreateShaders();
    	//CreateVBO();
     
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
    	glDrawArrays(GL_TRIANGLES, 0, 3);
     
    	glutSwapBuffers();
    	glutPostRedisplay();
    }
     
    void IdleFunction(void)
    {
    	glutPostRedisplay();
    }
     
    void TimerFunction(int Value)
    {
    	if (0 != Value) {
    		char* TempString = (char*)
    			malloc(512 + strlen(WINDOW_TITLE_PREFIX));
     
    		sprintf(
    			TempString,
    			"%s: %d Frames Per Second @ %d x %d",
    			WINDOW_TITLE_PREFIX,
    			FrameCount * 4,
    			CurrentWidth,
    			CurrentHeight
    		);
     
    		glutSetWindowTitle(TempString);
    		free(TempString);
    	}
     
    	FrameCount = 0;
    	glutTimerFunc(250, TimerFunction, 1);
    }
     
    void Cleanup(void)
    {
    	DestroyShaders();
    	DestroyVBO();
    }
     
    void CreateVBO(void)
    {
    	GLfloat Vertices[] = {
    		-0.8f, -0.8f, 0.0f, 1.0f,
    		 0.0f,  0.8f, 0.0f, 1.0f,
    		 0.8f, -0.8f, 0.0f, 1.0f
    	};
     
    	GLfloat Colors[] = {
    		1.0f, 0.0f, 0.0f, 1.0f,
    		0.0f, 1.0f, 0.0f, 1.0f,
    		0.0f, 0.0f, 1.0f, 1.0f
    	};
     
    	GLenum ErrorCheckValue = glGetError();
     
    	glGenVertexArrays(1, &VaoId);
    	glBindVertexArray(VaoId);
     
    	glGenBuffers(1, &VboId);
    	glBindBuffer(GL_ARRAY_BUFFER, VboId);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
    	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
    	glEnableVertexAttribArray(0);
     
    	glGenBuffers(1, &ColorBufferId);
    	glBindBuffer(GL_ARRAY_BUFFER, ColorBufferId);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(Colors), Colors, GL_STATIC_DRAW);
    	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
    	glEnableVertexAttribArray(1);
     
    	ErrorCheckValue = glGetError();
    	if (ErrorCheckValue != GL_NO_ERROR)
    	{
    		fprintf(
    			stderr,
    			"ERROR: Could not create a VBO: %s \n",
    			gluErrorString(ErrorCheckValue)
    		);
     
    		exit(-1);
    	}
     }
     
    void DestroyVBO(void)
    {
    	GLenum ErrorCheckValue = glGetError();
     
    	glDisableVertexAttribArray(1);
    	glDisableVertexAttribArray(0);
     
    	glBindBuffer(GL_ARRAY_BUFFER, 0);
     
    	glDeleteBuffers(1, &ColorBufferId);
    	glDeleteBuffers(1, &VboId);
     
    	glBindVertexArray(0);
    	glDeleteVertexArrays(1, &VaoId);
     
    	ErrorCheckValue = glGetError();
    	if (ErrorCheckValue != GL_NO_ERROR)
    	{
    		fprintf(
    			stderr,
    			"ERROR: Could not destroy the VBO: %s \n",
    			gluErrorString(ErrorCheckValue)
    		);
     
    		exit(-1);
    	}
    }
     
    void CreateShaders(void)
    {
    	GLenum ErrorCheckValue = glGetError();
     
    	VertexShaderId = glCreateShader(GL_VERTEX_SHADER);
    	glShaderSource(VertexShaderId, 1, &VertexShader, NULL);
    	glCompileShader(VertexShaderId);
     
    	FragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
    	glShaderSource(FragmentShaderId, 1, &FragmentShader, NULL);
    	glCompileShader(FragmentShaderId);
     
    	ProgramId = glCreateProgram();
    		glAttachShader(ProgramId, VertexShaderId);
    		glAttachShader(ProgramId, FragmentShaderId);
    	glLinkProgram(ProgramId);
    	glUseProgram(ProgramId); // This is the problem, but why? 
     
    	ErrorCheckValue = glGetError();
    	if (ErrorCheckValue != GL_NO_ERROR)
    	{
    		fprintf(
    			stderr,
    			"ERROR: Could not create the shaders: %s \n",
    			gluErrorString(ErrorCheckValue)
    		);
     
    		numberInput = getchar();
     
    		exit(-1);
    	}
    }
     
    void DestroyShaders(void)
    {
    	GLenum ErrorCheckValue = glGetError();
     
    	glUseProgram(0);
     
    	glDetachShader(ProgramId, VertexShaderId);
    	glDetachShader(ProgramId, FragmentShaderId);
     
    	glDeleteShader(FragmentShaderId);
    	glDeleteShader(VertexShaderId);
     
    	glDeleteProgram(ProgramId);
     
    	ErrorCheckValue = glGetError();
    	if (ErrorCheckValue != GL_NO_ERROR)
    	{
    		fprintf(
    			stderr,
    			"ERROR: Could not destroy the shaders: %s \n",
    			gluErrorString(ErrorCheckValue)
    		);
     
    		exit(-1);
    	}
    }
    If I comment out glUseProgram, I get the triangle displayed properly, but it's all white. I don't understand how the shader program could be failing to link; it's just a few lines. Can anyone see anything off with my code?

  2. #2
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,714
    This:

    layout(location=0)
    is not legal GLSL 1.30 syntax. You'll have to make more than a few changes to get around this. You have to use glBindAttribLocation on the program before linking to assign the vertex attributes to attribute indices.

  3. #3
    Intern Contributor
    Join Date
    Jun 2012
    Posts
    52
    Is 1.30 the highest version compatible with OGL 3.1? Or does a higher version of GLSL, that supports the (location=#) syntax, work with OGL 3.1?

    EDIT - Got it to work with glBindAttribLocation; thanks Alfonse! The newer GLSL syntax would've been nice, but that's what I get for having an Intel GPU.
    Last edited by fiodis; 09-11-2012 at 07:59 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •