-2

I'm writing a simplistic shader manager so I don't have to write repeditive code all the time involving my shader and I have ran into a few problems, here is the function the error appears in:

void ShaderManager::create_program(std::string name)  {
    GLuint vertexshader;
    GLuint fragmentshader;

    GLint link_ok = GL_FALSE;

    if ((vertexshader = create_shader(name + ".v.glsl", GL_VERTEX_SHADER)) == 0)  {
        print_shader_errors(&vertexshader);
    }

    if ((fragmentshader = create_shader(name + ".f.glsl", GL_FRAGMENT_SHADER)) == 0)  {
        print_shader_errors(&fragmentshader);
    }

    program_values.emplace_back(glCreateProgram());
    program_keys.emplace_back(name);
    glAttachShader(program_values.at(program_values.size()), vertexshader);
    glAttachShader(program_values.at(program_values.size()), fragmentshader);
    glLinkProgram(program_values.at(program_values.size()));

    glGetProgramiv(program_values.at(program_values.size()), GL_LINK_STATUS, &link_ok);

    if (!link_ok)  {
        std::cout << "The shaders did not link correctly." << "\n";
    }
}

Every single private static member I attempt to access says the same thing:

Generator\src\ShaderManager.cpp|33|undefined reference to ShaderManager::program_values'

My header file looks like:

#ifndef SHADERMANAGER_H
#define SHADERMANAGER_H

#include <string>
#include <vector>

#include <GL/glew.h>
#include <GL/glu.h>
#include <GL/gl.h>

class ShaderManager {
    public:
        ShaderManager();
        virtual ~ShaderManager();

        static GLuint get_program(std::string shader_name);
        static int get_index_of_program_key(std::string program_name);

        static void create_program(std::string name);
        static bool bind_attribute(std::string shader_name, std::string attribute_name);
        static bool bind_uniform(std::string shader_name, std::string uniform_name);

    protected:
    private:
        static std::vector<GLuint> program_values;
        static std::vector<std::string> program_keys;

        static std::vector<GLuint> attribute_values;
        static std::vector<std::string> attribute_keys;

        static std::vector<GLuint> uniform_values;
        static std::vector<std::string> uniform_keys;


        static void print_shader_errors(GLuint *shader);
        static const char* file_read(std::string filename);
        static GLuint create_shader(std::string filename, GLenum type);
};

#endif // SHADERMANAGER_H
Darestium
  • 643
  • 2
  • 11
  • 29

2 Answers2

3

First, you are accesing program_values.at( program_values.size() ), which is accessing element after last element (index start at 0 not 1) and std::vector::at() function will throw an out_of_range exception. This is correct code for access last element: program_values.at( program_values.size() - 1 ) or shorter program_values.back().

Second, if you declare any static member, you need to define it in one cpp file, like this:

std::vector<GLuint> ShaderManager::program_values;
std::vector<std::string> ShaderManager::program_keys;

std::vector<GLuint> ShaderManager::attribute_values;
std::vector<std::string> ShaderManager::attribute_keys;

std::vector<GLuint> ShaderManager::uniform_values;
std::vector<std::string> ShaderManager::uniform_keys;
ErikEsTT
  • 356
  • 1
  • 3
  • 14
  • "which is buffer overflow" it's not buffer overflow but out of range accessing, btw at() throws exception when you provide wrong index – Mr.Anubis Aug 07 '12 at 11:41
  • Yes, it will throw out_of_range exception, which can by buffer overflow, of underflow (meaning buffer as vector elements, not allocated memory). – ErikEsTT Aug 07 '12 at 11:59
  • jeez!!, if you call that thing buffer overflow/underflow then why didn't standard chose out_of_range exception name to be buffer overflow/underflow ? – Mr.Anubis Aug 07 '12 at 15:44
  • Had already +1'ed (upvoted) at first look at answer, can't any more :P – Mr.Anubis Aug 07 '12 at 18:02
1

In class definition you only declared static member program_values. In some .cpp file (best choice would be file with all class methods definitions) you need to define it - like this

std::vector<GLuint> ShaderManager::program_values;

or

std::vector<GLuint> ShaderManager::program_values(some_constructor_parameters);
Tadeusz Kopec for Ukraine
  • 12,283
  • 6
  • 56
  • 83