mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
Add packed unsigned 11/10/10-bit floating point vertex format
This commit is contained in:
parent
aac24a3a13
commit
fdc8918946
@ -92,7 +92,8 @@ munge_format_impl(const GeomVertexFormat *orig,
|
||||
// and texture coordinates.
|
||||
const GeomVertexColumn *vertex_type = orig->get_vertex_column();
|
||||
if (vertex_type != (GeomVertexColumn *)NULL &&
|
||||
vertex_type->get_numeric_type() == NT_int8) {
|
||||
(vertex_type->get_numeric_type() == NT_int8 ||
|
||||
vertex_type->get_numeric_type() == NT_uint8)) {
|
||||
int vertex_array = orig->get_array_with(InternalName::get_vertex());
|
||||
|
||||
PT(GeomVertexArrayFormat) new_array_format = new_format->modify_array(vertex_array);
|
||||
@ -102,7 +103,29 @@ munge_format_impl(const GeomVertexFormat *orig,
|
||||
(InternalName::get_vertex(), 3, NT_int16,
|
||||
C_point, vertex_type->get_start(), vertex_type->get_column_alignment());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Convert packed formats that OpenGL may not understand.
|
||||
for (int i = 0; i < orig->get_num_columns(); ++i) {
|
||||
const GeomVertexColumn *column = orig->get_column(i);
|
||||
int array = orig->get_array_with(column->get_name());
|
||||
|
||||
if (column->get_numeric_type() == NT_packed_dabc &&
|
||||
!glgsg->_supports_packed_dabc) {
|
||||
// Unpack the packed ARGB color into its four byte components.
|
||||
PT(GeomVertexArrayFormat) array_format = new_format->modify_array(array);
|
||||
array_format->add_column(column->get_name(), 4, NT_uint8, C_color,
|
||||
column->get_start(), column->get_column_alignment());
|
||||
|
||||
} else if (column->get_numeric_type() == NT_packed_ufloat &&
|
||||
!glgsg->_supports_packed_ufloat) {
|
||||
// Unpack to three 32-bit floats. (In future, should try 16-bit float)
|
||||
PT(GeomVertexArrayFormat) array_format = new_format->modify_array(array);
|
||||
array_format->add_column(column->get_name(), 3, NT_float32,
|
||||
column->get_contents(), column->get_start(),
|
||||
column->get_column_alignment());
|
||||
}
|
||||
}
|
||||
#endif // !OPENGLES
|
||||
|
||||
const GeomVertexColumn *color_type = orig->get_color_column();
|
||||
if (color_type != (GeomVertexColumn *)NULL &&
|
||||
@ -116,8 +139,8 @@ munge_format_impl(const GeomVertexFormat *orig,
|
||||
|
||||
// Replace the existing color format with the new format.
|
||||
new_array_format->add_column
|
||||
(InternalName::get_color(), 4, NT_uint8,
|
||||
C_color, color_type->get_start(), color_type->get_column_alignment());
|
||||
(InternalName::get_color(), 4, NT_uint8, C_color,
|
||||
color_type->get_start(), color_type->get_column_alignment());
|
||||
}
|
||||
|
||||
if (animation.get_animation_type() == AT_hardware) {
|
||||
@ -259,7 +282,8 @@ premunge_format_impl(const GeomVertexFormat *orig) {
|
||||
// and texture coordinates.
|
||||
const GeomVertexColumn *vertex_type = orig->get_vertex_column();
|
||||
if (vertex_type != (GeomVertexColumn *)NULL &&
|
||||
vertex_type->get_numeric_type() == NT_int8) {
|
||||
(vertex_type->get_numeric_type() == NT_int8 ||
|
||||
vertex_type->get_numeric_type() == NT_uint8)) {
|
||||
int vertex_array = orig->get_array_with(InternalName::get_vertex());
|
||||
|
||||
PT(GeomVertexArrayFormat) new_array_format = new_format->modify_array(vertex_array);
|
||||
@ -269,23 +293,29 @@ premunge_format_impl(const GeomVertexFormat *orig) {
|
||||
(InternalName::get_vertex(), 3, NT_int16,
|
||||
C_point, vertex_type->get_start(), vertex_type->get_column_alignment());
|
||||
}
|
||||
#endif
|
||||
|
||||
const GeomVertexColumn *color_type = orig->get_color_column();
|
||||
if (color_type != (GeomVertexColumn *)NULL &&
|
||||
color_type->get_numeric_type() == NT_packed_dabc &&
|
||||
// Convert packed formats that OpenGL may not understand.
|
||||
for (int i = 0; i < orig->get_num_columns(); ++i) {
|
||||
const GeomVertexColumn *column = orig->get_column(i);
|
||||
int array = orig->get_array_with(column->get_name());
|
||||
|
||||
if (column->get_numeric_type() == NT_packed_dabc &&
|
||||
!glgsg->_supports_packed_dabc) {
|
||||
// We need to convert the color format; OpenGL doesn't support the
|
||||
// byte order of DirectX's packed ARGB format.
|
||||
int color_array = orig->get_array_with(InternalName::get_color());
|
||||
// Unpack the packed ARGB color into its four byte components.
|
||||
PT(GeomVertexArrayFormat) array_format = new_format->modify_array(array);
|
||||
array_format->add_column(column->get_name(), 4, NT_uint8, C_color,
|
||||
column->get_start(), column->get_column_alignment());
|
||||
|
||||
PT(GeomVertexArrayFormat) new_array_format = new_format->modify_array(color_array);
|
||||
|
||||
// Replace the existing color format with the new format.
|
||||
new_array_format->add_column
|
||||
(InternalName::get_color(), 4, NT_uint8,
|
||||
C_color, color_type->get_start(), color_type->get_column_alignment());
|
||||
} else if (column->get_numeric_type() == NT_packed_ufloat &&
|
||||
!glgsg->_supports_packed_ufloat) {
|
||||
// Unpack to three 32-bit floats. (In future, should try 16-bit float)
|
||||
PT(GeomVertexArrayFormat) array_format = new_format->modify_array(array);
|
||||
array_format->add_column(column->get_name(), 3, NT_float32,
|
||||
column->get_contents(), column->get_start(),
|
||||
column->get_column_alignment());
|
||||
}
|
||||
}
|
||||
#endif // !OPENGLES
|
||||
|
||||
CPT(GeomVertexFormat) format = GeomVertexFormat::register_format(new_format);
|
||||
|
||||
|
@ -1012,10 +1012,13 @@ reset() {
|
||||
|
||||
#ifdef OPENGLES
|
||||
_supports_packed_dabc = false;
|
||||
_supports_packed_ufloat = false;
|
||||
#else
|
||||
_supports_packed_dabc = is_at_least_gl_version(3, 2) ||
|
||||
has_extension("GL_ARB_vertex_array_bgra") ||
|
||||
has_extension("GL_EXT_vertex_array_bgra");
|
||||
_supports_packed_ufloat = is_at_least_gl_version(4, 4) ||
|
||||
has_extension("GL_ARB_vertex_type_10f_11f_11f_rev");
|
||||
#endif
|
||||
|
||||
_supports_multisample =
|
||||
@ -7380,6 +7383,13 @@ get_numeric_type(Geom::NumericType numeric_type) {
|
||||
|
||||
case Geom::NT_int32:
|
||||
return GL_INT;
|
||||
|
||||
case Geom::NT_packed_ufloat:
|
||||
#ifndef OPENGLES
|
||||
return GL_UNSIGNED_INT_10F_11F_11F_REV;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
GLCAT.error()
|
||||
|
@ -713,6 +713,7 @@ public:
|
||||
bool _supports_bgr;
|
||||
bool _supports_rescale_normal;
|
||||
bool _supports_packed_dabc;
|
||||
bool _supports_packed_ufloat;
|
||||
|
||||
PFNGLACTIVETEXTUREPROC _glActiveTexture;
|
||||
#ifndef OPENGLES_2
|
||||
|
@ -2002,8 +2002,8 @@ glsl_compile_and_link() {
|
||||
// glsl_report_shader_errors(*it);
|
||||
//}
|
||||
|
||||
// Under core OpenGL, we have to make sure that we bind something to
|
||||
// attribute 0. Make sure that this is the position array.
|
||||
// Under OpenGL's compatibility profile, we have to make sure that we bind
|
||||
// something to attribute 0. Make sure that this is the position array.
|
||||
_glgsg->_glBindAttribLocation(_glsl_program, 0, "p3d_Vertex");
|
||||
_glgsg->_glBindAttribLocation(_glsl_program, 0, "vertex");
|
||||
|
||||
|
@ -110,6 +110,9 @@ operator << (ostream &out, GeomEnums::NumericType numeric_type) {
|
||||
|
||||
case GeomEnums::NT_int32:
|
||||
return out << "int32";
|
||||
|
||||
case GeomEnums::NT_packed_ufloat:
|
||||
return out << "packed_ufloat";
|
||||
}
|
||||
|
||||
return out << "**invalid numeric type (" << (int)numeric_type << ")**";
|
||||
|
@ -186,6 +186,7 @@ PUBLISHED:
|
||||
NT_int8, // An integer -128..127
|
||||
NT_int16, // An integer -32768..32767
|
||||
NT_int32, // An integer -2147483648..2147483647
|
||||
NT_packed_ufloat,// Three 10/11-bit float components packed in a uint32
|
||||
};
|
||||
|
||||
// The contents determine the semantic meaning of a numeric value
|
||||
|
@ -153,6 +153,7 @@ output(ostream &out) const {
|
||||
break;
|
||||
|
||||
case NT_stdfloat:
|
||||
case NT_packed_ufloat:
|
||||
out << "?";
|
||||
break;
|
||||
}
|
||||
@ -214,6 +215,11 @@ setup() {
|
||||
case NT_stdfloat:
|
||||
nassertv(false);
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
_component_bytes = 4; // sizeof(PN_uint32)
|
||||
_num_values *= 3;
|
||||
break;
|
||||
}
|
||||
|
||||
if (_contents == C_matrix) {
|
||||
@ -483,6 +489,12 @@ get_data1f(const unsigned char *pointer) {
|
||||
case NT_int32:
|
||||
return *(const PN_int32 *)pointer;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
{
|
||||
PN_uint32 dword = *(const PN_uint32 *)pointer;
|
||||
return GeomVertexData::unpack_ufloat_a(dword);
|
||||
}
|
||||
|
||||
default:
|
||||
nassertr(false, 0.0f);
|
||||
}
|
||||
@ -578,6 +590,10 @@ get_data2f(const unsigned char *pointer) {
|
||||
_v2.set(pi[0], pi[1]);
|
||||
}
|
||||
return _v2;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertr(false, _v2);
|
||||
return _v2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -682,6 +698,15 @@ get_data3f(const unsigned char *pointer) {
|
||||
_v3.set(pi[0], pi[1], pi[2]);
|
||||
}
|
||||
return _v3;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
{
|
||||
PN_uint32 dword = *(const PN_uint32 *)pointer;
|
||||
_v3.set(GeomVertexData::unpack_ufloat_a(dword),
|
||||
GeomVertexData::unpack_ufloat_b(dword),
|
||||
GeomVertexData::unpack_ufloat_c(dword));
|
||||
}
|
||||
return _v3;
|
||||
}
|
||||
}
|
||||
|
||||
@ -795,6 +820,10 @@ get_data4f(const unsigned char *pointer) {
|
||||
_v4.set(pi[0], pi[1], pi[2], pi[3]);
|
||||
}
|
||||
return _v4;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertr(false, _v4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -837,8 +866,8 @@ get_data1d(const unsigned char *pointer) {
|
||||
return *(const PN_float64 *)pointer;
|
||||
|
||||
case NT_stdfloat:
|
||||
nassertr(false, 0.0f);
|
||||
return 0.0f;
|
||||
nassertr(false, 0.0);
|
||||
return 0.0;
|
||||
|
||||
case NT_int8:
|
||||
return *(const PN_int8 *)pointer;
|
||||
@ -848,9 +877,15 @@ get_data1d(const unsigned char *pointer) {
|
||||
|
||||
case NT_int32:
|
||||
return *(const PN_int32 *)pointer;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
{
|
||||
PN_uint32 dword = *(const PN_uint32 *)pointer;
|
||||
return GeomVertexData::unpack_ufloat_a(dword);
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -941,6 +976,10 @@ get_data2d(const unsigned char *pointer) {
|
||||
_v2d.set(pi[0], pi[1]);
|
||||
}
|
||||
return _v2d;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertr(false, _v2d);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1045,6 +1084,15 @@ get_data3d(const unsigned char *pointer) {
|
||||
_v3d.set(pi[0], pi[1], pi[2]);
|
||||
}
|
||||
return _v3d;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
{
|
||||
PN_uint32 dword = *(const PN_uint32 *)pointer;
|
||||
_v3d.set(GeomVertexData::unpack_ufloat_a(dword),
|
||||
GeomVertexData::unpack_ufloat_b(dword),
|
||||
GeomVertexData::unpack_ufloat_c(dword));
|
||||
}
|
||||
return _v3d;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1158,6 +1206,10 @@ get_data4d(const unsigned char *pointer) {
|
||||
_v4d.set(pi[0], pi[1], pi[2], pi[3]);
|
||||
}
|
||||
return _v4d;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertr(false, _v4d);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1211,6 +1263,12 @@ get_data1i(const unsigned char *pointer) {
|
||||
|
||||
case NT_int32:
|
||||
return *(const PN_int32 *)pointer;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
{
|
||||
PN_uint32 dword = *(const PN_uint32 *)pointer;
|
||||
return (int)GeomVertexData::unpack_ufloat_a(dword);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1302,6 +1360,10 @@ get_data2i(const unsigned char *pointer) {
|
||||
_v2i.set(pi[0], pi[1]);
|
||||
}
|
||||
return _v2i;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertr(false, _v2i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1403,6 +1465,15 @@ get_data3i(const unsigned char *pointer) {
|
||||
_v3i.set(pi[0], pi[1], pi[2]);
|
||||
}
|
||||
return _v3i;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
{
|
||||
PN_uint32 dword = *(const PN_uint32 *)pointer;
|
||||
_v3i.set((int)GeomVertexData::unpack_ufloat_a(dword),
|
||||
(int)GeomVertexData::unpack_ufloat_b(dword),
|
||||
(int)GeomVertexData::unpack_ufloat_c(dword));
|
||||
}
|
||||
return _v3i;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1513,6 +1584,10 @@ get_data4i(const unsigned char *pointer) {
|
||||
_v4i.set(pi[0], pi[1], pi[2], pi[3]);
|
||||
}
|
||||
return _v4i;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertr(false, _v4i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1569,6 +1644,10 @@ set_data1f(unsigned char *pointer, float data) {
|
||||
case NT_int32:
|
||||
*(PN_int32 *)pointer = (int)data;
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertv(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1596,6 +1675,7 @@ set_data2f(unsigned char *pointer, const LVecBase2f &data) {
|
||||
switch (_column->get_num_values()) {
|
||||
case 1:
|
||||
set_data1f(pointer, data[0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
switch (_column->get_numeric_type()) {
|
||||
@ -1671,6 +1751,10 @@ set_data2f(unsigned char *pointer, const LVecBase2f &data) {
|
||||
pi[1] = (int)data[1];
|
||||
}
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertv(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1782,6 +1866,10 @@ set_data3f(unsigned char *pointer, const LVecBase3f &data) {
|
||||
pi[2] = (int)data[2];
|
||||
}
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
*(PN_uint32 *)pointer = GeomVertexData::pack_ufloat(data[0], data[1], data[2]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1904,6 +1992,10 @@ set_data4f(unsigned char *pointer, const LVecBase4f &data) {
|
||||
pi[3] = (int)data[3];
|
||||
}
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertv(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1959,6 +2051,10 @@ set_data1d(unsigned char *pointer, double data) {
|
||||
case NT_int32:
|
||||
*(PN_int32 *)pointer = (int)data;
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertv(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2061,6 +2157,10 @@ set_data2d(unsigned char *pointer, const LVecBase2d &data) {
|
||||
pi[1] = (int)data[1];
|
||||
}
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertv(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2172,6 +2272,10 @@ set_data3d(unsigned char *pointer, const LVecBase3d &data) {
|
||||
pi[2] = (int)data[2];
|
||||
}
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
*(PN_uint32 *)pointer = GeomVertexData::pack_ufloat(data[0], data[1], data[2]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2294,6 +2398,10 @@ set_data4d(unsigned char *pointer, const LVecBase4d &data) {
|
||||
pi[3] = (int)data[3];
|
||||
}
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertv(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2353,6 +2461,10 @@ set_data1i(unsigned char *pointer, int data) {
|
||||
case NT_int32:
|
||||
*(PN_int32 *)pointer = data;
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertv(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2453,6 +2565,10 @@ set_data2i(unsigned char *pointer, const LVecBase2i &data) {
|
||||
pi[1] = data[1];
|
||||
}
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertv(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2561,6 +2677,10 @@ set_data3i(unsigned char *pointer, const LVecBase3i &data) {
|
||||
pi[2] = data[2];
|
||||
}
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
*(PN_uint32 *)pointer = GeomVertexData::pack_ufloat(data[0], data[1], data[2]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2680,6 +2800,10 @@ set_data4i(unsigned char *pointer, const LVecBase4i &data) {
|
||||
pi[3] = data[3];
|
||||
}
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertv(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2839,6 +2963,10 @@ get_data4f(const unsigned char *pointer) {
|
||||
_v4.set(pi[0], pi[1], pi[2], pi[3]);
|
||||
}
|
||||
return _v4;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertr(false, _v4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2999,6 +3127,10 @@ get_data4d(const unsigned char *pointer) {
|
||||
_v4d.set(pi[0], pi[1], pi[2], pi[3]);
|
||||
}
|
||||
return _v4d;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertr(false, _v4d);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3160,6 +3292,10 @@ set_data4f(unsigned char *pointer, const LVecBase4f &data) {
|
||||
pi[3] = (int)data[3];
|
||||
}
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertv(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -3320,6 +3456,10 @@ set_data4d(unsigned char *pointer, const LVecBase4d &data) {
|
||||
pi[3] = (int)data[3];
|
||||
}
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertv(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -3443,6 +3583,15 @@ get_data3f(const unsigned char *pointer) {
|
||||
case NT_int32:
|
||||
nassertr(false, _v3);
|
||||
return _v3;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
{
|
||||
PN_uint32 dword = *(const PN_uint32 *)pointer;
|
||||
_v3.set(GeomVertexData::unpack_ufloat_a(dword),
|
||||
GeomVertexData::unpack_ufloat_b(dword),
|
||||
GeomVertexData::unpack_ufloat_c(dword));
|
||||
}
|
||||
return _v3;
|
||||
}
|
||||
} else {
|
||||
const LVecBase4f &v4 = get_data4f(pointer);
|
||||
@ -3528,6 +3677,7 @@ get_data4f(const unsigned char *pointer) {
|
||||
case NT_int8:
|
||||
case NT_int16:
|
||||
case NT_int32:
|
||||
case NT_packed_ufloat:
|
||||
nassertr(false, _v4);
|
||||
return _v4;
|
||||
}
|
||||
@ -3652,6 +3802,15 @@ get_data3d(const unsigned char *pointer) {
|
||||
case NT_int32:
|
||||
nassertr(false, _v3d);
|
||||
return _v3d;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
{
|
||||
PN_uint32 dword = *(const PN_uint32 *)pointer;
|
||||
_v3d.set(GeomVertexData::unpack_ufloat_a(dword),
|
||||
GeomVertexData::unpack_ufloat_b(dword),
|
||||
GeomVertexData::unpack_ufloat_c(dword));
|
||||
}
|
||||
return _v3d;
|
||||
}
|
||||
} else {
|
||||
const LVecBase4d &v4 = get_data4d(pointer);
|
||||
@ -3737,6 +3896,7 @@ get_data4d(const unsigned char *pointer) {
|
||||
case NT_int8:
|
||||
case NT_int16:
|
||||
case NT_int32:
|
||||
case NT_packed_ufloat:
|
||||
nassertr(false, _v4d);
|
||||
return _v4d;
|
||||
}
|
||||
@ -3850,6 +4010,10 @@ set_data3f(unsigned char *pointer, const LVecBase3f &data) {
|
||||
case NT_int32:
|
||||
nassertv(false);
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
*(PN_uint32 *)pointer = GeomVertexData::pack_ufloat(data[0], data[1], data[2]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
set_data4f(pointer, LVecBase4f(data[0], data[1], data[2], 1.0f));
|
||||
@ -3942,6 +4106,10 @@ set_data4f(unsigned char *pointer, const LVecBase4f &data) {
|
||||
case NT_int32:
|
||||
nassertv(false);
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertv(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4053,6 +4221,10 @@ set_data3d(unsigned char *pointer, const LVecBase3d &data) {
|
||||
case NT_int32:
|
||||
nassertv(false);
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
*(PN_uint32 *)pointer = GeomVertexData::pack_ufloat(data[0], data[1], data[2]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
set_data4d(pointer, LVecBase4d(data[0], data[1], data[2], 1.0f));
|
||||
@ -4145,6 +4317,10 @@ set_data4d(unsigned char *pointer, const LVecBase4d &data) {
|
||||
case NT_int32:
|
||||
nassertv(false);
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
nassertv(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -403,6 +403,150 @@ unpack_abcd_d(PN_uint32 data) {
|
||||
return data & 0xff;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::pack_ufloat
|
||||
// Access: Public, Static
|
||||
// Description: Packs three float values in an unsigned 32-bit int.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PN_uint32 GeomVertexData::
|
||||
pack_ufloat(float a, float b, float c) {
|
||||
// Since we have to clamp both low exponents and negative numbers to 0,
|
||||
// it's easier to see a float as having a 9-bit signed exponent.
|
||||
union {
|
||||
PN_int32 _packed;
|
||||
float _float;
|
||||
} f0, f1, f2;
|
||||
|
||||
f0._float = a;
|
||||
f1._float = b;
|
||||
f2._float = c;
|
||||
|
||||
// There are several cases here:
|
||||
// 1. exponent 0xff: NaN or infinity (negative infinity excluded)
|
||||
// 2. exponent too large: clamped to maximum value
|
||||
// 3. normalized float
|
||||
// 4. exponent 0: denormal float
|
||||
// 5. zero or anything negative, clamped to 0
|
||||
|
||||
PN_uint32 packed = 0;
|
||||
|
||||
if ((f0._packed & 0x7f800000) == 0x7f800000 && (unsigned)f0._packed != 0xff800000u) {
|
||||
packed |= (f0._packed >> 17) & 0x7ffu;
|
||||
} else if (f0._packed >= 0x47800000) {
|
||||
packed |= 0x7bf;
|
||||
} else if (f0._packed >= 0x38800000) {
|
||||
packed |= (f0._packed >> 17) - 0x1c00;
|
||||
} else if (f0._packed >= 0x35000000) {
|
||||
packed |= ((f0._packed & 0x7c0000u) | 0x800000u) >> (130 - (f0._packed >> 23));
|
||||
}
|
||||
|
||||
if ((f1._packed & 0x7f800000) == 0x7f800000 && (unsigned)f1._packed != 0xff800000u) {
|
||||
packed |= (f1._packed >> 6) & 0x3ff800u;
|
||||
} else if (f1._packed >= 0x47800000) {
|
||||
packed |= 0x3df800;
|
||||
} else if (f1._packed >= 0x38800000) {
|
||||
packed |= ((f1._packed >> 6) - 0xe00000) & 0x3ff800;
|
||||
} else if (f1._packed >= 0x35000000) {
|
||||
packed |= (((f1._packed & 0x7c0000u) | 0x800000u) >> (119 - (f1._packed >> 23))) & 0x1f800u;
|
||||
}
|
||||
|
||||
if ((f2._packed & 0x7f800000) == 0x7f800000 && (unsigned)f2._packed != 0xff800000u) {
|
||||
packed |= (f2._packed & 0x0ffe0000u) << 4;
|
||||
} else if (f2._packed >= 0x47800000) {
|
||||
packed |= 0xf7c00000;
|
||||
} else if (f2._packed >= 0x38800000) {
|
||||
packed |= ((f2._packed - 0x38000000) << 4) & 0xffc00000;
|
||||
} else if (f2._packed >= 0x35000000) {
|
||||
packed |= ((((f2._packed << 3) & 0x03c00000u) | 0x04000000u) >> (112 - (f2._packed >> 23))) & 0x07c00000u;
|
||||
}
|
||||
|
||||
return packed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::unpack_ufloat_a
|
||||
// Access: Public, Static
|
||||
// Description: Unpacks an unsigned float11 value from an uint32.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float GeomVertexData::
|
||||
unpack_ufloat_a(PN_uint32 data) {
|
||||
if ((data & 0x7c0) == 0) {
|
||||
// Denormal float (includes zero).
|
||||
return ldexpf((data & 63) / 64.0f, -14);
|
||||
}
|
||||
|
||||
union {
|
||||
PN_uint32 _packed;
|
||||
float _float;
|
||||
} value;
|
||||
value._packed = ((data & 0x7ff) << 17);
|
||||
|
||||
if ((data & 0x7c0) == 0x7c0) {
|
||||
// Infinity / NaN
|
||||
value._packed |= 0x7f800000;
|
||||
} else {
|
||||
value._packed += 0x38000000;
|
||||
}
|
||||
|
||||
return value._float;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::unpack_ufloat_b
|
||||
// Access: Public, Static
|
||||
// Description: Unpacks an unsigned float11 value from an uint32.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float GeomVertexData::
|
||||
unpack_ufloat_b(PN_uint32 data) {
|
||||
if ((data & 0x3e0000) == 0) {
|
||||
// Denormal float (includes zero).
|
||||
return ldexpf(((data >> 11) & 63) / 64.0f, -14);
|
||||
}
|
||||
|
||||
union {
|
||||
PN_uint32 _packed;
|
||||
float _float;
|
||||
} value;
|
||||
value._packed = ((data & 0x3ff800) << 6);
|
||||
|
||||
if ((data & 0x3e0000) == 0x3e0000) {
|
||||
// Infinity / NaN
|
||||
value._packed |= 0x7f800000;
|
||||
} else {
|
||||
value._packed += 0x38000000;
|
||||
}
|
||||
|
||||
return value._float;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::unpack_ufloat_c
|
||||
// Access: Public, Static
|
||||
// Description: Unpacks an unsigned float10 value from an uint32.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float GeomVertexData::
|
||||
unpack_ufloat_c(PN_uint32 data) {
|
||||
if ((data & 0xf8000000u) == 0) {
|
||||
// Denormal float (includes zero).
|
||||
return ldexpf(((data >> 22) & 31) / 32.0f, -14);
|
||||
}
|
||||
|
||||
union {
|
||||
PN_uint32 _packed;
|
||||
float _float;
|
||||
} value;
|
||||
value._packed = ((data & 0xffc00000u) >> 4);
|
||||
|
||||
if ((data & 0xf8000000u) == 0xf8000000u) {
|
||||
// Infinity / NaN
|
||||
value._packed |= 0x7f800000;
|
||||
} else {
|
||||
value._packed += 0x38000000;
|
||||
}
|
||||
|
||||
return value._float;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::add_transform
|
||||
// Access: Private, Static
|
||||
|
@ -2579,7 +2579,7 @@ set_num_rows(int n) {
|
||||
while (pointer < stop) {
|
||||
PN_float64 *pi = (PN_float64 *)pointer;
|
||||
for (int i = 0; i < num_values; i++) {
|
||||
pi[i] = 1.0f;
|
||||
pi[i] = 1.0;
|
||||
}
|
||||
pointer += stride;
|
||||
}
|
||||
@ -2591,6 +2591,14 @@ set_num_rows(int n) {
|
||||
case NT_int32:
|
||||
// Shouldn't have this type in the format.
|
||||
nassertr(false, false);
|
||||
break;
|
||||
|
||||
case NT_packed_ufloat:
|
||||
while (pointer < stop) {
|
||||
*(PN_int32 *)pointer = 0x781e03c0;
|
||||
pointer += stride;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,6 +176,11 @@ public:
|
||||
static INLINE unsigned int unpack_abcd_c(PN_uint32 data);
|
||||
static INLINE unsigned int unpack_abcd_d(PN_uint32 data);
|
||||
|
||||
static INLINE PN_uint32 pack_ufloat(float a, float b, float c);
|
||||
static INLINE float unpack_ufloat_a(PN_uint32 data);
|
||||
static INLINE float unpack_ufloat_b(PN_uint32 data);
|
||||
static INLINE float unpack_ufloat_c(PN_uint32 data);
|
||||
|
||||
private:
|
||||
static void bytewise_copy(unsigned char *to, int to_stride,
|
||||
const unsigned char *from, int from_stride,
|
||||
|
Loading…
x
Reference in New Issue
Block a user