(rebased) experimental support for parsing from a float16 mesh (or a float32-quantized-as-ushort mesh)

This commit is contained in:
ecker 2026-07-24 16:07:09 -05:00
parent a1cd80a8db
commit 971d3d37e6
4 changed files with 141 additions and 0 deletions

View File

@ -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;

103
GL/quantize.inl Normal file
View File

@ -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];
}

View File

@ -18,6 +18,7 @@
__BEGIN_DECLS
#include <math.h>
#include "glquant.h"
/* Primitive Types taken from GL for compatability */
/* Not all types are implemented in Open GL DC V.1.0 */

14
include/GL/glquant.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#if __STDCPP_FLOAT16_T__
#include <stdfloat>
#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