Schnigges
Schnigges

Reputation: 1326

Setting up OpenGL program and shaders

After working with one program and one set of vertex / fragment shaders, I need to use more programs, so my initial setup function that didn't have any parameters wasn't sufficient anymore.

To my setup function, I pass the shader_program and the two shader sources. When I try to use the program in my display method, the GLuint program handle is zero. What I currently don't understand is why it all worked when I used fixed sources for my shaders. Could it be a C++ program and I'm passing the parameters in the wrong way? I'm not getting any error messages but nothing is rendered on screen.

Here's the code I use to call the shader setup function and the function itself:

// Variables
GLuint shader_program;

const GLchar *vertex_shader =   
"#version 330\n"
""
"layout (location = 0) in vec3 in_position;"
...
"";

// In my main function, I call this to set up the shaders
installShaders(shader_program, vertex_shader, fragment_shader);

// SET-UP-METHOD
void installShaders(GLuint program_handle, const GLchar *vertex_shader_source, const GLchar *fragment_shader_source)
{
// Handles for the shader objects
GLuint   vertex_shader_name;
GLuint fragment_shader_name;

// Status values 
GLint   vertex_shader_compiled;
GLint fragment_shader_compiled;
GLint      successfully_linked;

// Generate shader names
vertex_shader_name   = glCreateShader(GL_VERTEX_SHADER);
fragment_shader_name = glCreateShader(GL_FRAGMENT_SHADER);

// Specify the sources for the shaders
glShaderSource(  vertex_shader_name, 1, (const GLchar**)&vertex_shader_source  , NULL);
glShaderSource(fragment_shader_name, 1, (const GLchar**)&fragment_shader_source, NULL);

// Compile Vertex shader and check for errors
glCompileShader(vertex_shader_name);
glGetShaderiv(vertex_shader_name, GL_COMPILE_STATUS, &vertex_shader_compiled);
printShaderInfoLog(vertex_shader_name);

// Compile Fragment shader and check for errors
glCompileShader(fragment_shader_name);
glGetShaderiv(fragment_shader_name, GL_COMPILE_STATUS, &fragment_shader_compiled);
printShaderInfoLog(fragment_shader_name);

// Exit if the shaders couldn't be compiled correctly
if(!vertex_shader_compiled || !fragment_shader_compiled)
{
    printf("Shaders were not compiled correctly!\n");
    exit(EXIT_FAILURE);
}

// Generate program name
program_handle = glCreateProgram();

// Attach shaders to the program
glAttachShader(program_handle, vertex_shader_name);
glAttachShader(program_handle, fragment_shader_name);

// Link program and check for errors
glLinkProgram(program_handle);
glGetProgramiv(program_handle, GL_LINK_STATUS, &successfully_linked);
printProgramInfoLog(program_handle);

// Exit if the program couldn't be linked correctly
if(!successfully_linked)
{
    printf("Program was not linked correctly!\n");
    exit(EXIT_FAILURE);
}

// Set up initial values of uniform variables
glUseProgram(program_handle);

location_projectionMatrix = glGetUniformLocation(program_handle, "myProjectionMatrix");
printf("Location of the uniform -->myProjectionMatrix<--- : %i\n", location_projectionMatrix);
projectionMatrix = glm::mat4(1.0f);
glUniformMatrix4fv(location_projectionMatrix, 1, GL_FALSE, glm::value_ptr(projectionMatrix));

location_modelViewMatrix = glGetUniformLocation(program_handle, "myModelViewMatrix");
printf("Location of the uniform -->myModelViewMatrix<--- : %i\n", location_modelViewMatrix);
modelViewMatrix = glm::mat4(1.0f);
glUniformMatrix4fv(location_modelViewMatrix, 1, GL_FALSE, glm::value_ptr(modelViewMatrix));

glUseProgram(0);

// Everything worked
printf("Shaders were set up correctly!\n");
}

Upvotes: 3

Views: 1642

Answers (1)

radical7
radical7

Reputation: 9114

The issue is that the variable you store the GLSL shader program name (the value returned from glCreateShader) into is passed-by-value into the routine. As such, its value is lost when the function returns. Passing the value in by reference (as either a pointer or as a C++ reference), then the value will be preserved when the function exits, and you'll be able to reference the shader in other parts of your application.

Upvotes: 5

Related Questions