diff --git a/GL/attributes.c b/GL/attributes.c index d466214..93449b0 100644 --- a/GL/attributes.c +++ b/GL/attributes.c @@ -8,6 +8,8 @@ #include "private.h" #include "platform.h" +#include "quantize.inl" + AttribPointerList ATTRIB_LIST; static const float ONE_OVER_TWO_FIVE_FIVE = 1.0f / 255.0f; @@ -21,6 +23,7 @@ GL_FORCE_INLINE GLsizei byte_size(GLenum type) { case GL_UNSIGNED_INT: return sizeof(GLuint); case GL_DOUBLE: return sizeof(GLdouble); case GL_UNSIGNED_INT_2_10_10_10_REV: return sizeof(GLuint); + case GL_HALF_FLOAT: return sizeof(GLhalf); case GL_FLOAT: default: return sizeof(GLfloat); } @@ -152,6 +155,9 @@ static ReadAttributeFunc calcReadPositionFunc(void) { case GL_FLOAT: return (ATTRIB_LIST.vertex.size == 3) ? _readPosition3f3f: _readPosition2f3f; + case GL_HALF_FLOAT: + return (ATTRIB_LIST.vertex.size == 3) ? _readPosition3f16_3f: + _readPosition2f16_3f; case GL_BYTE: case GL_UNSIGNED_BYTE: return (ATTRIB_LIST.vertex.size == 3) ? _readPosition3ub3f: @@ -160,6 +166,9 @@ static ReadAttributeFunc calcReadPositionFunc(void) { case GL_UNSIGNED_SHORT: return (ATTRIB_LIST.vertex.size == 3) ? _readPosition3us3f: _readPosition2us3f; + case GL_QUANTIZED_SHORT: + return (ATTRIB_LIST.vertex.size == 3) ? _readPosition3usq3f: + _readPosition2usq3f; case GL_INT: case GL_UNSIGNED_INT: return (ATTRIB_LIST.vertex.size == 3) ? _readPosition3ui3f: @@ -435,12 +444,16 @@ static ReadAttributeFunc calcReadUVFunc(void) { default: case GL_FLOAT: return _readTexcoord2f2f; + case GL_HALF_FLOAT: + return _readTexcoord2f16_2f; case GL_BYTE: case GL_UNSIGNED_BYTE: return _readTexcoord2ub2f; case GL_SHORT: case GL_UNSIGNED_SHORT: return _readTexcoord2us2f; + case GL_QUANTIZED_SHORT: + return _readTexcoord2usq2f; case GL_INT: case GL_UNSIGNED_INT: return _readTexcoord2ui2f; @@ -458,12 +471,16 @@ static ReadAttributeFunc calcReadSTFunc(void) { default: case GL_FLOAT: return _readTexcoord2f2f; + case GL_HALF_FLOAT: + return _readTexcoord2f16_2f; case GL_BYTE: case GL_UNSIGNED_BYTE: return _readTexcoord2ub2f; case GL_SHORT: case GL_UNSIGNED_SHORT: return _readTexcoord2us2f; + case GL_QUANTIZED_SHORT: + return _readTexcoord2usq2f; case GL_INT: case GL_UNSIGNED_INT: return _readTexcoord2ui2f; @@ -551,6 +568,9 @@ static ReadAttributeFunc calcReadNormalFunc(void) { default: return _readNormal3f3f; break; + case GL_HALF_FLOAT: + return _readNormal3f16_3f; + break; case GL_BYTE: case GL_UNSIGNED_BYTE: return _readNormal3ub3f; @@ -563,6 +583,9 @@ static ReadAttributeFunc calcReadNormalFunc(void) { case GL_UNSIGNED_INT: return _readNormal3ui3f; break; + case GL_QUANTIZED_SHORT: + return _readNormal3usq3f; + break; case GL_UNSIGNED_INT_2_10_10_10_REV: return _readNormal1i3f; break; diff --git a/GL/quantize.inl b/GL/quantize.inl new file mode 100644 index 0000000..48d3e0a --- /dev/null +++ b/GL/quantize.inl @@ -0,0 +1,103 @@ +GLushort _quantize( GLfloat v ) { + union { GLfloat f; GLuint ui; } u = {v}; + GLuint ui = u.ui; + + int s = (ui >> 16) & 0x8000; + int em = ui & 0x7fffffff; + + int h = (em - (112 << 23) + (1 << 12)) >> 13; + h = (em < (113 << 23)) ? 0 : h; + h = (em >= (143 << 23)) ? 0x7c00 : h; + h = (em > (255 << 23)) ? 0x7e00 : h; + + return (GLushort)(s | h); +} +GLfloat _dequantize( GLushort h ) { + GLuint s = (GLuint) (h & 0x8000) << 16; + int em = h & 0x7fff; + int r = (em + (112 << 10)) << 13; + r = (em < (1 << 10)) ? 0 : r; + r += (em >= (31 << 10)) ? (112 << 23) : 0; + + union { GLfloat f; GLuint ui; } u; + u.ui = s | r; + return u.f; +} + +// dequantize to float +static void _readPosition3usq3f(const GLubyte* in, GLubyte* out) { + const GLushort* input = (const GLushort*) in; + Vertex* it = (Vertex*)out; + + float x = _dequantize(input[0]); + float y = _dequantize(input[1]); + float z = _dequantize(input[2]); + float w = 1.0f; + TransformVertex(x, y, z, w, it->xyz, &it->w); +} +static void _readPosition2usq3f(const GLubyte* in, GLubyte* out) { + const GLushort* input = (const GLushort*) in; + Vertex* it = (Vertex*)out; + + float x = _dequantize(input[0]); + float y = _dequantize(input[1]); + float z = 0.0f; + float w = 1.0f; + TransformVertex(x, y, z, w, it->xyz, &it->w); +} +// convert from float16 to float32 +static void _readPosition3f16_3f(const GLubyte* in, GLubyte* out) { + const GLhalf* input = (const GLhalf*) in; + Vertex* it = (Vertex*)out; + + float x = (float) input[0]; + float y = (float) input[1]; + float z = (float) input[2]; + float w = 1.0f; + TransformVertex(x, y, z, w, it->xyz, &it->w); +} +static void _readPosition2f16_3f(const GLubyte* in, GLubyte* out) { + const GLhalf* input = (const GLhalf*) in; + Vertex* it = (Vertex*)out; + + float x = (float) input[0]; + float y = (float) input[1]; + float z = 0.0f; + float w = 1.0f; + TransformVertex(x, y, z, w, it->xyz, &it->w); +} +// dequantize to float +static void _readTexcoord2usq2f(const GLubyte* in, GLubyte* out) { + const GLushort* input = (const GLushort*) in; + float* output = (float*) out; + + output[0] = _dequantize(input[0]); + output[1] = _dequantize(input[1]); +} +// convert from float16 to float32 +static void _readTexcoord2f16_2f(const GLubyte* in, GLubyte* out) { + const GLhalf* input = (const GLhalf*) in; + float* output = (float*) out; + + output[0] = input[0]; + output[1] = input[1]; +} + +// +static void _readNormal3usq3f(const GLubyte* in, GLubyte* out) { + const GLushort* input = (const GLushort*) in; + float* output = (float*) out; + + output[0] = _dequantize(input[0]); + output[1] = _dequantize(input[1]); + output[2] = _dequantize(input[2]); +} + +static void _readNormal3f16_3f(const GLubyte* in, GLubyte* out) { + const GLhalf* input = (const GLhalf*) in; + float* output = (float*) out; + + output[0] = input[0]; + output[1] = input[1]; + output[2] = input[2]; +} \ No newline at end of file diff --git a/include/GL/gl.h b/include/GL/gl.h index f9deb0c..bda386a 100644 --- a/include/GL/gl.h +++ b/include/GL/gl.h @@ -18,6 +18,7 @@ __BEGIN_DECLS #include +#include "glquant.h" /* Primitive Types taken from GL for compatability */ /* Not all types are implemented in Open GL DC V.1.0 */ diff --git a/include/GL/glquant.h b/include/GL/glquant.h new file mode 100644 index 0000000..6151c3b --- /dev/null +++ b/include/GL/glquant.h @@ -0,0 +1,14 @@ +#pragma once + +#if __STDCPP_FLOAT16_T__ + #include +#endif + +#define GL_HALF_FLOAT 0x140B +#define GL_QUANTIZED_SHORT 0x140C + +#if __STDCPP_FLOAT16_T__ +#define GLhalf std::float16_t +#else +#define GLhalf unsigned short +#endif \ No newline at end of file