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
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;
}
/*+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+*/