Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 2 of 2 FirstFirst 12
Results 11 to 14 of 14

Thread: Speed of glGetUniformLocation

  1. #11
    Intern Newbie
    Join Date
    Dec 2013
    Posts
    45
    OK, that looks cool. Thanks I'll probably keep the program GLuint outside of the uniform class, however it is still pretty much the same idea.

  2. #12
    Intern Newbie
    Join Date
    Dec 2013
    Posts
    45
    If anyone is interested, here was my solution for the uniforms:
    Code :
    template <class T>
    class _UniformBase
    {
    protected:
        GLint Location;
        T Data;
     
        virtual void SetUniform() {/*Dummy*/};      // Must be implemented in child classes
     
    public:
        _UniformBase(): Location(-1) {}
        virtual ~_UniformBase() {}
     
        int Register(_Program Program, const char *Name_in)
        {
            Name = Name_in;
            if((Location = glGetUniformLocation(Program.GetHandle(), Name_in)) == -1) return 1;
            return 0;
        }
        T GetData()
        {
            return Data;
        }
        GLint GetLocation()
        {
            return Location;
        }
     
        void SetData(T Data_in)
        {
            Data = Data_in;
            SetUniform();
        }
    };
     
    template <class T>
    class _Uniform : public _UniformBase<T>
    {
        // Just a blank class for the template...the specializations extend the needed _UniformBase::SetUniform() method
    };
     
    template <>
    class _Uniform<glm::mat4> : public _UniformBase<glm::mat4>
    {
    protected:
        void SetUniform()
        {
            glUniformMatrix4fv(Location, 1, GL_FALSE, glm::value_ptr(Data));
        }
    };
     
    template <>
    class _Uniform<glm::vec3> : public _UniformBase<glm::vec3>
    {
    protected:
        void SetUniform()
        {
            glUniform3fv(Location, 1, glm::value_ptr(Data));
        }
    };
    I set it up so I have a single base class "_UniformBase" that implements everything but the code that actually sends the data to the driver. Then, I made a blank templated dummy class just to allow me to write the specialized classes for each type (in my case, so far, it only implements it for glm::vec3 and glm::mat4). I did it like this because, while all the other code could be written with the template, the GL calls could NOT be templated (i.e. Uniform3f vs Uniform4f vs UniformMatrix4f, etc...) and I didn't want to use a big switch as having all those conditional branches could seriously affect performance. In the end, it let me access the uniforms just like this:
    Code :
     
    _Uniform<glm::mat4> Perspective;
    Perspective.Register(Program, "perspective");
    Perspective.SetData(glm::perspective(75.0f, 1.0f, 0.5f, 5.0f));
    and similar for all the other ones.

  3. #13
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,107
    You can improve this a bit by testing if the value is the same as the one already loaded and skip the SetUniform call.

  4. #14
    Intern Newbie
    Join Date
    Dec 2013
    Posts
    45
    Good point, will do

Posting Permissions

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