domingo, 21 de julio de 2013

Ampliando librerías para OpenGL: GLEW, GL3W, vmath, ShaderLoader

Para poder seguir avanzando vamos a tener que utilizar unas librerías que nos van a hacer la vida más fácil.
  • GLEW es una librería que en tiempo de ejecución determina que extensiones de OpenGL son soportadas por el cliente.
  • GL3W librería que carga solo la funcionalidad básica de OpenGL 3/4.
    Esta librería se puede obtener directamente desde GitHub y hace falta Python para compilar el script que te descargas. Sólo hace falta para generar el script, después lo podemos desinstalar: 
    https://github.com/skaslev/gl3w
  • vmath y el cargador de shaders son dos herramientas que he obtenido con el set de ejemplos del libro: "OpenGL Programming Guide. Eight Edition"
    Se trata de dos librerías que, facilitan las operaciones con vectores y matrices (
    vmath) y la carga de shaders (LoadShaders). El código de las mismas es el siguiente:
    vmath.h
    #ifndef __VMATH_H__
    #define __VMATH_H__
    
    
    #define _USE_MATH_DEFINES  1 // Include constants defined in math.h
    #include <math.h>
    
    namespace vmath
    {
    
    template <typename T> 
    inline T radians(T angleInRadians)
    {
     return angleInRadians * static_cast<T>(180.0/M_PI);
    }
    
    template <const bool cond>
    class ensure
    {
    public:
        inline ensure() { switch (false) { case false: case cond: break; } }
    };
    
    template <typename T, const int len> class vecN;
    
    template <typename T, const int len>
    class vecN
    {
    public:
        typedef class vecN<T,len> my_type;
    
        // Default constructor does nothing, just like built-in types
        inline vecN()
        {
            // Uninitialized variable
        }
    
        // Copy constructor
        inline vecN(const vecN& that)
        {
            assign(that);
        }
    
        // Construction from scalar
        inline vecN(T s)
        {
            int n;
            for (n = 0; n < len; n++)
            {
                data[n] = s;
            }
        }
    
        // Assignment operator
        inline vecN& operator=(const vecN& that)
        {
            assign(that);
            return *this;
        }
    
        inline vecN operator+(const vecN& that) const
        {
            my_type result;
            int n;
            for (n = 0; n < len; n++)
                result.data[n] = data[n] + that.data[n];
            return result;
        }
    
        inline vecN& operator+=(const vecN& that)
        {
            return (*this = *this + that);
        }
    
        inline vecN operator-() const
        {
            my_type result;
            int n;
            for (n = 0; n < len; n++)
                result.data[n] = -data[n];
            return result;
        }
    
        inline vecN operator-(const vecN& that) const
        {
            my_type result;
            int n;
            for (n = 0; n < len; n++)
                result.data[n] = data[n] - that.data[n];
            return result;
        }
    
        inline vecN& operator-=(const vecN& that)
        {
            return (*this = *this - that);
        }
    
        inline vecN operator*(const vecN& that) const
        {
            my_type result;
            int n;
            for (n = 0; n < len; n++)
                result.data[n] = data[n] * that.data[n];
            return result;
        }
    
        inline vecN& operator*=(const vecN& that)
        {
            return (*this = *this * that);
        }
    
        inline vecN operator*(const T& that) const
        {
            my_type result;
            int n;
            for (n = 0; n < len; n++)
                result.data[n] = data[n] * that;
            return result;
        }
    
        inline vecN& operator*=(const T& that)
        {
            assign(*this * that);
    
            return *this;
        }
    
        inline vecN operator/(const vecN& that) const
        {
            my_type result;
            int n;
            for (n = 0; n < len; n++)
                result.data[n] = data[n] * that.data[n];
            return result;
        }
    
        inline vecN& operator/=(const vecN& that)
        {
            assign(*this * that);
    
            return *this;
        }
    
        inline vecN operator/(const T& that) const
        {
            my_type result;
            int n;
            for (n = 0; n < len; n++)
                result.data[n] = data[n] / that;
            return result;
        }
    
        inline vecN& operator/(const T& that)
        {
            assign(*this / that);
        }
    
        inline T& operator[](int n) { return data[n]; }
        inline const T& operator[](int n) const { return data[n]; }
    
        inline static int size(void) { return len; }
    
        inline operator const T* () const { return &data[0]; }
    
    protected:
        T data[len];
    
        inline void assign(const vecN& that)
        {
            int n;
            for (n = 0; n < len; n++)
                data[n] = that.data[n];
        }
    };
    
    template <typename T>
    class Tvec2 : public vecN<T,2>
    {
    public:
        typedef vecN<T,2> base;
    
        // Uninitialized variable
        inline Tvec2() {}
        // Copy constructor
        inline Tvec2(const base& v) : base(v) {}
    
        // vec2(x, y);
        inline Tvec2(T x, T y)
        {
            base::data[0] = x;
            base::data[1] = y;
        }
    };
    
    template <typename T>
    class Tvec3 : public vecN<T,3>
    {
    public:
        typedef vecN<T,3> base;
    
        // Uninitialized variable
        inline Tvec3() {}
    
        // Copy constructor
        inline Tvec3(const base& v) : base(v) {}
    
        // vec3(x, y, z);
        inline Tvec3(T x, T y, T z)
        {
            base::data[0] = x;
            base::data[1] = y;
            base::data[2] = z;
        }
    
        // vec3(v, z);
        inline Tvec3(const Tvec2<T>& v, T z)
        {
            base::data[0] = v[0];
            base::data[1] = v[1];
            base::data[2] = z;
        }
    
        // vec3(x, v)
        inline Tvec3(T x, const Tvec2<T>& v)
        {
            base::data[0] = x;
            base::data[1] = v[0];
            base::data[2] = v[1];
        }
    };
    
    template <typename T>
    class Tvec4 : public vecN<T,4>
    {
    public:
        typedef vecN<T,4> base;
    
        // Uninitialized variable
        inline Tvec4() {}
    
        // Copy constructor
        inline Tvec4(const base& v) : base(v) {}
    
        // vec4(x, y, z, w);
        inline Tvec4(T x, T y, T z, T w)
        {
            base::data[0] = x;
            base::data[1] = y;
            base::data[2] = z;
            base::data[3] = w;
        }
    
        // vec4(v, z, w);
        inline Tvec4(const Tvec2<T>& v, T z, T w)
        {
            base::data[0] = v[0];
            base::data[1] = v[1];
            base::data[2] = z;
            base::data[3] = w;
        }
    
        // vec4(x, v, w);
        inline Tvec4(T x, const Tvec2<T>& v, T w)
        {
            base::data[0] = x;
            base::data[1] = v[0];
            base::data[2] = v[1];
            base::data[3] = w;
        }
    
        // vec4(x, y, v);
        inline Tvec4(T x, T y, const Tvec2<T>& v)
        {
            base::data[0] = x;
            base::data[1] = y;
            base::data[2] = v[0];
            base::data[3] = v[1];
        }
    
        // vec4(v1, v2);
        inline Tvec4(const Tvec2<T>& u, const Tvec2<T>& v)
        {
            base::data[0] = u[0];
            base::data[1] = u[1];
            base::data[2] = v[0];
            base::data[3] = v[1];
        }
    
        // vec4(v, w);
        inline Tvec4(const Tvec3<T>& v, T w)
        {
            base::data[0] = v[0];
            base::data[1] = v[1];
            base::data[2] = v[2];
            base::data[3] = w;
        }
    
        // vec4(x, v);
        inline Tvec4(T x, const Tvec3<T>& v)
        {
            base::data[0] = x;
            base::data[1] = v[0];
            base::data[2] = v[1];
            base::data[3] = v[2];
        }
    };
    
    typedef Tvec2<float> vec2;
    typedef Tvec2<int> ivec2;
    typedef Tvec2<unsigned int> uvec2;
    typedef Tvec2<double> dvec2;
    
    typedef Tvec3<float> vec3;
    typedef Tvec3<int> ivec3;
    typedef Tvec3<unsigned int> uvec3;
    typedef Tvec3<double> dvec3;
    
    typedef Tvec4<float> vec4;
    typedef Tvec4<int> ivec4;
    typedef Tvec4<unsigned int> uvec4;
    typedef Tvec4<double> dvec4;
    
    template <typename T, int n>
    static inline const vecN<T,n> operator * (T x, const vecN<T,n>& v)
    {
        return v * x;
    }
    
    template <typename T>
    static inline const Tvec2<T> operator / (T x, const Tvec2<T>& v)
    {
        return Tvec2<T>(x / v[0], x / v[1]);
    }
    
    template <typename T>
    static inline const Tvec3<T> operator / (T x, const Tvec3<T>& v)
    {
        return Tvec3<T>(x / v[0], x / v[1], x / v[2]);
    }
    
    template <typename T>
    static inline const Tvec4<T> operator / (T x, const Tvec4<T>& v)
    {
        return Tvec4<T>(x / v[0], x / v[1], x / v[2], x / v[3]);
    }
    
    template <typename T, int len>
    static inline T dot(const vecN<T,len>& a, const vecN<T,len>& b)
    {
        int n;
        T total = T(0);
        for (n = 0; n < len; n++)
        {
            total += a[n] * b[n];
        }
        return total;
    }
    
    template <typename T>
    static inline vecN<T,3> cross(const vecN<T,3>& a, const vecN<T,3>& b)
    {
        return Tvec3<T>(a[1] * b[2] - b[1] * a[2],
                        a[2] * b[0] - b[2] * a[0],
                        a[0] * b[1] - b[0] * a[1]);
    }
    
    template <typename T, int len>
    static inline T length(const vecN<T,len>& v)
    {
        T result(0);
    
        for (int i = 0; i < v.size(); ++i)
        {
            result += v[i] * v[i];
        }
    
        return (T)sqrt(result);
    }
    
    template <typename T, int len>
    static inline vecN<T,len> normalize(const vecN<T,len>& v)
    {
        return v / length(v);
    }
    
    template <typename T, int len>
    static inline T distance(const vecN<T,len>& a, const vecN<T,len>& b)
    {
        return length(b - a);
    }
    
    template <typename T, const int w, const int h>
    class matNM
    {
    public:
        typedef class matNM<T,w,h> my_type;
        typedef class vecN<T,h> vector_type;
    
        // Default constructor does nothing, just like built-in types
        inline matNM()
        {
            // Uninitialized variable
        }
    
        // Copy constructor
        inline matNM(const matNM& that)
        {
            assign(that);
        }
    
        // Construction from element type
        // explicit to prevent assignment from T
        explicit inline matNM(T f)
        {
            for (int n = 0; n < w; n++)
            {
                data[n] = f;
            }
        }
    
        // Construction from vector
        inline matNM(const vector_type& v)
        {
            for (int n = 0; n < w; n++)
            {
                data[n] = v;
            }
        }
    
        // Assignment operator
        inline matNM& operator=(const my_type& that)
        {
            assign(that);
            return *this;
        }
    
        inline matNM operator+(const my_type& that) const
        {
            my_type result;
            int n;
            for (n = 0; n < w; n++)
                result.data[n] = data[n] + that.data[n];
            return result;
        }
    
        inline my_type& operator+=(const my_type& that)
        {
            return (*this = *this + that);
        }
    
        inline my_type operator-(const my_type& that) const
        {
            my_type result;
            int n;
            for (n = 0; n < w; n++)
                result.data[n] = data[n] - that.data[n];
            return result;
        }
    
        inline my_type& operator-=(const my_type& that)
        {
            return (*this = *this - that);
        }
    
        // Matrix multiply.
        // TODO: This only works for square matrices. Need more template skill to make a non-square version.
        inline my_type operator*(const my_type& that) const
        {
            ensure<w == h>();
    
            my_type result(0);
    
            for (int j = 0; j < w; j++)
            {
                for (int i = 0; i < h; i++)
                {
                    T sum(0);
    
                    for (int n = 0; n < w; n++)
                    {
                        sum += data[n][i] * that[j][n];
                    }
    
                    result[j][i] = sum;
                }
            }
    
            return result;
        }
    
        inline my_type& operator*=(const my_type& that)
        {
            return (*this = *this * that);
        }
    
        inline vector_type& operator[](int n) { return data[n]; }
        inline const vector_type& operator[](int n) const { return data[n]; }
        inline operator T*() { return &data[0][0]; }
        inline operator const T*() const { return &data[0][0]; }
    
        inline matNM<T,h,w> transpose(void) const
        {
            matNM<T,h,w> result;
            int x, y;
    
            for (y = 0; y < w; y++)
            {
                for (x = 0; x < h; x++)
                {
                    result[x][y] = data[y][x];
                }
            }
    
            return result;
        }
    
        static inline my_type identity()
        {
            ensure<w == h>();
    
            my_type result(0);
    
            for (int i = 0; i < w; i++)
            {
                result[i][i] = 1;
            }
    
            return result;
        }
    
        static inline int width(void) { return w; }
        static inline int height(void) { return h; }
    
    protected:
        // Column primary data (essentially, array of vectors)
        vecN<T,h> data[w];
    
        // Assignment function - called from assignment operator and copy constructor.
        inline void assign(const matNM& that)
        {
            int n;
            for (n = 0; n < w; n++)
                data[n] = that.data[n];
        }
    };
    
    /*
    template <typename T, const int N>
    class TmatN : public matNM<T,N,N>
    {
    public:
        typedef matNM<T,N,N> base;
        typedef TmatN<T,N> my_type;
    
        inline TmatN() {}
        inline TmatN(const my_type& that) : base(that) {}
        inline TmatN(float f) : base(f) {}
        inline TmatN(const vecN<T,4>& v) : base(v) {}
    
        inline my_type transpose(void)
        {
            my_type result;
            int x, y;
    
            for (y = 0; y < h; y++)
            {
                for (x = 0; x < h; x++)
                {
                    result[x][y] = data[y][x];
                }
            }
    
            return result;
        }
    };
    */
    
    template <typename T>
    class Tmat4 : public matNM<T,4,4>
    {
    public:
        typedef matNM<T,4,4> base;
        typedef Tmat4<T> my_type;
    
        inline Tmat4() {}
        inline Tmat4(const my_type& that) : base(that) {}
        inline Tmat4(const base& that) : base(that) {}
        inline Tmat4(const vecN<T,4>& v) : base(v) {}
        inline Tmat4(const vecN<T,4>& v0,
                     const vecN<T,4>& v1,
                     const vecN<T,4>& v2,
                     const vecN<T,4>& v3)
        {
            base::data[0] = v0;
            base::data[1] = v1;
            base::data[2] = v2;
            base::data[3] = v3;
        }
    };
    
    typedef Tmat4<float> mat4;
    typedef Tmat4<int> imat4;
    typedef Tmat4<unsigned int> umat4;
    typedef Tmat4<double> dmat4;
    
    static inline mat4 frustum(float left, float right, float bottom, float top, float n, float f)
    {
        mat4 result(mat4::identity());
    
        if ((right == left) ||
            (top == bottom) ||
            (n == f) ||
            (n < 0.0) ||
            (f < 0.0))
           return result;
    
        result[0][0] = (2.0f * n) / (right - left);
        result[1][1] = (2.0f * n) / (top - bottom);
    
        result[2][0] = (right + left) / (right - left);
        result[2][1] = (top + bottom) / (top - bottom);
        result[2][2] = -(f + n) / (f - n);
        result[2][3]= -1.0f;
    
        result[3][2] = -(2.0f * f * n) / (f - n);
        result[3][3] =  0.0f;
    
        return result;
    }
    
    static inline mat4 perspective(float fovy /* in degrees */, float aspect, float n, float f)
    {
     float  top = n * tan(radians(0.5f*fovy)); // bottom = -top
     float  right = top * aspect; // left = -right
     return frustum(-right, right, -top, top, n, f);
    }
    
    template <typename T>
    static inline Tmat4<T> lookat(vecN<T,3> eye, vecN<T,3> center, vecN<T,3> up)
    {
        const Tvec3<T> f = normalize(center - eye);
        const Tvec3<T> upN = normalize(up);
        const Tvec3<T> s = cross(f, upN);
        const Tvec3<T> u = cross(s, f);
        const Tmat4<T> M = Tmat4<T>(Tvec4<T>(s[0], u[0], -f[0], T(0)),
                                    Tvec4<T>(s[1], u[1], -f[1], T(0)),
                                    Tvec4<T>(s[2], u[2], -f[2], T(0)),
                                    Tvec4<T>(T(0), T(0), T(0), T(1)));
    
    
        return M * translate(-eye);
    }
    
    template <typename T>
    static inline Tmat4<T> translate(T x, T y, T z)
    {
        return Tmat4<T>(Tvec4<T>(1.0f, 0.0f, 0.0f, 0.0f),
                        Tvec4<T>(0.0f, 1.0f, 0.0f, 0.0f),
                        Tvec4<T>(0.0f, 0.0f, 1.0f, 0.0f),
                        Tvec4<T>(x, y, z, 1.0f));
    }
    
    template <typename T>
    static inline Tmat4<T> translate(const vecN<T,3>& v)
    {
        return translate(v[0], v[1], v[2]);
    }
    
    template <typename T>
    static inline Tmat4<T> scale(T x, T y, T z)
    {
        return Tmat4<T>(Tvec4<T>(x, 0.0f, 0.0f, 0.0f),
                        Tvec4<T>(0.0f, y, 0.0f, 0.0f),
                        Tvec4<T>(0.0f, 0.0f, z, 0.0f),
                        Tvec4<T>(0.0f, 0.0f, 0.0f, 1.0f));
    }
    
    template <typename T>
    static inline Tmat4<T> scale(const Tvec4<T>& v)
    {
        return scale(v[0], v[1], v[2]);
    }
    
    template <typename T>
    static inline Tmat4<T> scale(T x)
    {
        return Tmat4<T>(Tvec4<T>(x, 0.0f, 0.0f, 0.0f),
                        Tvec4<T>(0.0f, x, 0.0f, 0.0f),
                        Tvec4<T>(0.0f, 0.0f, x, 0.0f),
                        Tvec4<T>(0.0f, 0.0f, 0.0f, 1.0f));
    }
    
    template <typename T>
    static inline Tmat4<T> rotate(T angle, T x, T y, T z)
    {
        Tmat4<T> result;
    
        const T x2 = x * x;
        const T y2 = y * y;
        const T z2 = z * z;
        float rads = float(angle) * 0.0174532925f;
        const float c = cosf(rads);
        const float s = sinf(rads);
        const float omc = 1.0f - c;
    
        result[0] = Tvec4<T>(T(x2 * omc + c), T(y * x * omc + z * s), T(x * z * omc - y * s), T(0));
        result[1] = Tvec4<T>(T(x * y * omc - z * s), T(y2 * omc + c), T(y * z * omc + x * s), T(0));
        result[2] = Tvec4<T>(T(x * z * omc + y * s), T(y * z * omc - x * s), T(z2 * omc + c), T(0));
        result[3] = Tvec4<T>(T(0), T(0), T(0), T(1));
    
        return result;
    }
    
    template <typename T>
    static inline Tmat4<T> rotate(T angle, const vecN<T,3>& v)
    {
        return rotate<T>(angle, v[0], v[1], v[2]);
    }
    
    #ifdef min
    #undef min
    #endif
    
    template <typename T>
    static inline T min(T a, T b)
    {
        return a < b ? a : b;
    }
    
    #ifdef max
    #undef max
    #endif
    
    template <typename T>
    static inline T max(T a, T b)
    {
        return a >= b ? a : b;
    }
    
    template <typename T, const int N>
    static inline vecN<T,N> min(const vecN<T,N>& x, const vecN<T,N>& y)
    {
        vecN<T,N> t;
        int n;
    
        for (n = 0; n < N; n++)
        {
            t[n] = min(x[n], y[n]);
        }
    
        return t;
    }
    
    template <typename T, const int N>
    static inline vecN<T,N> max(const vecN<T,N>& x, const vecN<T,N>& y)
    {
        vecN<T,N> t;
        int n;
    
        for (n = 0; n < N; n++)
        {
            t[n] = max<T>(x[n], y[n]);
        }
    
        return t;
    }
    
    template <typename T, const int N>
    static inline vecN<T,N> clamp(const vecN<T,N>& x, const vecN<T,N>& minVal, const vecN<T,N>& maxVal)
    {
        return min<T>(max<T>(x, minVal), maxVal);
    }
    
    template <typename T, const int N>
    static inline vecN<T,N> smoothstep(const vecN<T,N>& edge0, const vecN<T,N>& edge1, const vecN<T,N>& x)
    {
        vecN<T,N> t;
        t = clamp((x - edge0) / (edge1 - edge0), vecN<T,N>(T(0)), vecN<T,N>(T(1)));
        return t * t * (vecN<T,N>(T(3)) - vecN<T,N>(T(2)) * t);
    }
    
    template <typename T, const int N, const int M>
    static inline matNM<T,N,M> matrixCompMult(const matNM<T,N,M>& x, const matNM<T,N,M>& y)
    {
        matNM<T,N,M> result;
        int i, j;
    
        for (j = 0; j < M; ++j)
        {
            for (i = 0; i < N; ++i)
            {
                result[i][j] = x[i][j] * y[i][j];
            }
        }
    
        return result;
    }
    
    template <typename T, const int N, const int M>
    static inline vecN<T,N> operator*(const vecN<T,M>& vec, const matNM<T,N,M>& mat)
    {
        int n, m;
        vecN<T,N> result(T(0));
    
        for (m = 0; m < M; m++)
        {
            for (n = 0; n < N; n++)
            {
                result[n] += vec[m] * mat[n][m];
            }
        }
    
        return result;
    }
    
    };
    
    #endif /* __VMATH_H__ */
    
    

    LoadShaders.h
    //////////////////////////////////////////////////////////////////////////////
    //
    //  --- LoadShaders.h ---
    //
    //////////////////////////////////////////////////////////////////////////////
    
    #ifndef __LOAD_SHADERS_H__
    #define __LOAD_SHADERS_H__
    
    #include <GL/gl.h>
    
    #ifdef __cplusplus
    extern "C" {
    #endif  // __cplusplus
    
    //----------------------------------------------------------------------------
    //
    //  LoadShaders() takes an array of ShaderFile structures, each of which
    //    contains the type of the shader, and a pointer a C-style character
    //    string (i.e., a NULL-terminated array of characters) containing the
    //    entire shader source.
    //
    //  The array of structures is terminated by a final Shader with the
    //    "type" field set to GL_NONE.
    //
    //  LoadShaders() returns the shader program value (as returned by
    //    glCreateProgram()) on success, or zero on failure. 
    //
    
    typedef struct {
        GLenum       type;
        const char*  filename;
        GLuint       shader;
    } ShaderInfo;
    
    GLuint LoadShaders( ShaderInfo* );
    
    //----------------------------------------------------------------------------
    
    #ifdef __cplusplus
    };
    #endif // __cplusplus
    
    #endif // __LOAD_SHADERS_H__
    
    

    LoadShaders.cpp
    //////////////////////////////////////////////////////////////////////////////
    //
    //  --- LoadShaders.cxx ---
    //
    //////////////////////////////////////////////////////////////////////////////
    
    #include <cstdlib>
    #include <iostream>
    #include <cstdio>
    
    #define GLEW_STATIC
    #include <GL/glew.h>
    #include "LoadShaders.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif // __cplusplus
    
    //----------------------------------------------------------------------------
    
    static const GLchar*
    ReadShader( const char* filename )
    {
    
        FILE* infile = fopen( filename, "rb" );
    
        if ( !infile ) {
    #ifdef _DEBUG
            std::cerr << "Unable to open file '" << filename << "'" << std::endl;
    #endif /* DEBUG */
            return NULL;
        }
    
        fseek( infile, 0, SEEK_END );
        int len = ftell( infile );
        fseek( infile, 0, SEEK_SET );
    
        GLchar* source = new GLchar[len+1];
    
        fread( source, 1, len, infile );
        fclose( infile );
    
        source[len] = 0;
    
        return const_cast<const GLchar*>(source);
    }
    
    //----------------------------------------------------------------------------
    
    GLuint
    LoadShaders( ShaderInfo* shaders )
    {
        if(glewInit()){
            std::cerr << "Unable to initialize GLEW..." << std::endl;
        }
        if ( shaders == NULL ) { return 0; }
    
        GLuint program = glCreateProgram();
    
        ShaderInfo* entry = shaders;
        while ( entry->type != GL_NONE ) {
            GLuint shader = glCreateShader( entry->type );
    
            entry->shader = shader;
    
            const GLchar* source = ReadShader( entry->filename );
            if ( source == NULL ) {
                for ( entry = shaders; entry->type != GL_NONE; ++entry ) {
                    glDeleteShader( entry->shader );
                    entry->shader = 0;
                }
    
                return 0;
            }
    
            glShaderSource( shader, 1, &source, NULL );
            delete [] source;
    
            glCompileShader( shader );
    
            GLint compiled;
            glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
            if ( !compiled ) {
    #ifdef _DEBUG
                GLsizei len;
                glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &len );
    
                GLchar* log = new GLchar[len+1];
                glGetShaderInfoLog( shader, len, &len, log );
                std::cerr << "Shader compilation failed: " << log << std::endl;
                delete [] log;
    #endif /* DEBUG */
    
                return 0;
            }
    
            glAttachShader( program, shader );
            
            ++entry;
        }
    
    #ifdef GL_VERSION_4_1
        if ( GLEW_VERSION_4_1 ) {
            // glProgramParameteri( program, GL_PROGRAM_SEPARABLE, GL_TRUE );
        }
    #endif /* GL_VERSION_4_1 */
        
        glLinkProgram( program );
    
        GLint linked;
        glGetProgramiv( program, GL_LINK_STATUS, &linked );
        if ( !linked ) {
    #ifdef _DEBUG
            GLsizei len;
            glGetProgramiv( program, GL_INFO_LOG_LENGTH, &len );
    
            GLchar* log = new GLchar[len+1];
            glGetProgramInfoLog( program, len, &len, log );
            std::cerr << "Shader linking failed: " << log << std::endl;
            delete [] log;
    #endif /* DEBUG */
    
            for ( entry = shaders; entry->type != GL_NONE; ++entry ) {
                glDeleteShader( entry->shader );
                entry->shader = 0;
            }
            
            return 0;
        }
    
        return program;
    }
    
    //----------------------------------------------------------------------------
    #ifdef __cplusplus
    }
    #endif // __cplusplus

    No se si son las mejores pero nos vienen al pelo.
Ademas, hay que cambiar las opciones de las librerías incluidas en el proyecto, ahora hay que añadir: glew32. El orden de inclusión importa por lo que copio, pego y modifico el que ya teníamos en el post de configuración de Eclipse.
  1. mingw32
  2. glew32
  3. opengl32
  4. SDL2main
  5. SDL2

No hay comentarios:

Publicar un comentario