16-bit floats and GL_HALF_FLOAT

后端 未结 3 1590
囚心锁ツ
囚心锁ツ 2021-01-11 18:19

I\'m looking for/writing a C++ implementation of a 16-bit floating point number to use with OpenGL vertex buffers (texture coordinates, normals, etc). Here are my requireme

3条回答
  •  囚心锁ツ
    2021-01-11 18:40

    Edit: The most obvious error appears in your VertexHalf structure. You have an element of padding. Yet when you specify your glVertexAttribPointer you specify a 0 in the stride which indicates it is tightly packed. So you can either change VertexHalf to remove the padding or change your glVertexAttribPointer to have a stride of 8 bytes.

    I use the following class with DirectX for float16 support and it works perfectly.

    Float16.h:

    #ifndef THE__FLOAT_16_H_
    #define THE__FLOAT_16_H_
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    extern short FloatToFloat16( float value );
    extern float Float16ToFloat( short value );
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    class Float16
    {
    protected:
        short mValue;
    public:
        Float16();
        Float16( float value );
        Float16( const Float16& value );
    
        operator float();
        operator float() const;
    
        friend Float16 operator + ( const Float16& val1, const Float16& val2 );
        friend Float16 operator - ( const Float16& val1, const Float16& val2 );
        friend Float16 operator * ( const Float16& val1, const Float16& val2 );
        friend Float16 operator / ( const Float16& val1, const Float16& val2 );
    
        Float16& operator =( const Float16& val );
        Float16& operator +=( const Float16& val );
        Float16& operator -=( const Float16& val );
        Float16& operator *=( const Float16& val );
        Float16& operator /=( const Float16& val );
        Float16& operator -();
    };
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    inline Float16::Float16()
    {
    }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    inline Float16::Float16( float value )
    {
        mValue  = FloatToFloat16( value );
    }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    inline Float16::Float16( const Float16 &value )
    {
        mValue  = value.mValue;
    }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    inline Float16::operator float()
    {
        return Float16ToFloat( mValue );
    }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    inline Float16::operator float() const
    {
        return Float16ToFloat( mValue );
    }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    inline Float16& Float16::operator =( const Float16& val )
    {
        mValue  = val.mValue;
    }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    inline Float16& Float16::operator +=( const Float16& val )
    {
        *this   = *this + val;
        return *this;
    }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    inline Float16& Float16::operator -=( const Float16& val )
    {
        *this   = *this - val;
        return *this;
    
    }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    inline Float16& Float16::operator *=( const Float16& val )
    {
        *this   = *this * val;
        return *this;
    }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    inline Float16& Float16::operator /=( const Float16& val )
    {
        *this   = *this / val;
        return *this;
    }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    inline Float16& Float16::operator -()
    {
        *this   = Float16( -(float)*this );
        return *this;
    }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    /*+----+                                 Friends                                       +----+*/
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    inline Float16 operator + ( const Float16& val1, const Float16& val2 )
    {
        return Float16( (float)val1 + (float)val2 );
    }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    inline Float16 operator - ( const Float16& val1, const Float16& val2 )
    {
        return Float16( (float)val1 - (float)val2 );
    }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    inline Float16 operator * ( const Float16& val1, const Float16& val2 )
    {
        return Float16( (float)val1 * (float)val2 );
    }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    inline Float16 operator / ( const Float16& val1, const Float16& val2 )
    {
        return Float16( (float)val1 / (float)val2 );
    }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    
    #endif
    

    Float16.cpp:

    #include "Types/Float16.h"
    
    //#include 
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    
    short FloatToFloat16( float value )
    {
        short   fltInt16;
        int     fltInt32;
        memcpy( &fltInt32, &value, sizeof( float ) );
        fltInt16    =  ((fltInt32 & 0x7fffffff) >> 13) - (0x38000000 >> 13);
        fltInt16    |= ((fltInt32 & 0x80000000) >> 16);
    
        return fltInt16;
    }
    

    /+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+/

    float Float16ToFloat( short fltInt16 )
    {
        int fltInt32    =  ((fltInt16 & 0x8000) << 16);
        fltInt32        |= ((fltInt16 & 0x7fff) << 13) + 0x38000000;
    
        float fRet;
        memcpy( &fRet, &fltInt32, sizeof( float ) );
        return fRet;
     }
    
    /*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/
    

提交回复
热议问题