From 11cd54bc0b717c06151e499fc2fc7afc3317a387 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Mon, 18 Nov 2019 17:39:09 +0000 Subject: [PATCH] Add partial support for GL_ARB_vertex_type_2_10_10_10_rev and also GL_NORMALIZE --- GL/draw.c | 51 ++++++++++++++++++++++++++++++++++++++++++- GL/immediate.c | 28 +++++++++++++++++++----- GL/private.h | 2 ++ GL/state.c | 13 ++++++++++- include/gl.h | 2 ++ samples/lights/main.c | 2 ++ 6 files changed, 90 insertions(+), 8 deletions(-) diff --git a/GL/draw.c b/GL/draw.c index b1f98ef..bef822f 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "../include/gl.h" #include "../include/glext.h" @@ -102,6 +103,7 @@ static inline GLuint byte_size(GLenum type) { case GL_INT: return sizeof(GLint); 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_FLOAT: default: return sizeof(GLfloat); } @@ -128,6 +130,32 @@ static void _readVertexData3f3f(const float* input, GLuint count, GLubyte stride } } + +static inline float conv_i10_to_norm_float(int i10) { + struct attr_bits_10 { + signed int x:10; + } val; + + val.x = i10; + + return (2.0F * (float)val.x + 1.0F) * (1.0F / 1023.0F); +} + +// 10:10:10:2REV format +static void _readVertexData1ui3f(const GLuint* input, GLuint count, GLubyte stride, float* output) { + ITERATE(count) { + int inp = *input; + output[0] = conv_i10_to_norm_float((inp) & 0x3ff); + output[1] = conv_i10_to_norm_float(((inp) >> 10) & 0x3ff); + output[2] = conv_i10_to_norm_float(((inp) >> 20) & 0x3ff); + + // fprintf(stderr, "%d -> %f %f %f\n", inp, output[0], output[1], output[2]); + + input = (GLuint*) (((GLubyte*) input) + stride); + output = (GLfloat*) (((GLubyte*) output) + sizeof(VertexExtra)); + } +} + /* VE == VertexExtra */ static void _readVertexData3f3fVE(const float* input, GLuint count, GLubyte stride, float* output) { ITERATE(count) { @@ -748,7 +776,7 @@ static inline void _readNormalData(const GLuint first, const GLuint count, Verte const GLuint nstride = (NORMAL_POINTER.stride) ? NORMAL_POINTER.stride : NORMAL_POINTER.size * byte_size(NORMAL_POINTER.type); const void* nptr = ((GLubyte*) NORMAL_POINTER.ptr + (first * nstride)); - if(NORMAL_POINTER.size == 3) { + if(NORMAL_POINTER.size == 3 || NORMAL_POINTER.type == GL_UNSIGNED_INT_2_10_10_10_REV) { switch(NORMAL_POINTER.type) { case GL_DOUBLE: case GL_FLOAT: @@ -766,12 +794,33 @@ static inline void _readNormalData(const GLuint first, const GLuint count, Verte case GL_UNSIGNED_INT: _readVertexData3ui3fVE(nptr, count, nstride, extra->nxyz); break; + case GL_UNSIGNED_INT_2_10_10_10_REV: + _readVertexData1ui3f(nptr, count, nstride, extra->nxyz); + break; default: assert(0 && "Not Implemented"); } } else { assert(0 && "Not Implemented"); } + + if(_glIsNormalizeEnabled()) { + GLubyte* ptr = (GLubyte*) extra->nxyz; + GLfloat l; + ITERATE(count) { + GLfloat* n = (GLfloat*) ptr; + + vec3f_length(n[0], n[1], n[2], l); + + l = 1.0f / l; + + n[0] *= l; + n[1] *= l; + n[2] *= l; + + ptr += sizeof(VertexExtra); + } + } } static inline void _readDiffuseData(const GLuint first, const GLuint count, Vertex* output) { diff --git a/GL/immediate.c b/GL/immediate.c index ae3ad7a..69b6870 100644 --- a/GL/immediate.c +++ b/GL/immediate.c @@ -38,11 +38,11 @@ static AttribPointer NORMAL_ATTRIB; void _glInitImmediateMode(GLuint initial_size) { aligned_vector_init(&VERTICES, sizeof(GLVertexKOS)); aligned_vector_init(&ST_COORDS, sizeof(GLfloat)); - aligned_vector_init(&NORMALS, sizeof(GLfloat)); + aligned_vector_init(&NORMALS, sizeof(GLuint)); aligned_vector_reserve(&VERTICES, initial_size); aligned_vector_reserve(&ST_COORDS, initial_size * 2); - aligned_vector_reserve(&NORMALS, initial_size * 3); + aligned_vector_reserve(&NORMALS, initial_size); VERTEX_ATTRIB.ptr = VERTICES.data + sizeof(uint32_t); VERTEX_ATTRIB.size = 3; @@ -61,8 +61,8 @@ void _glInitImmediateMode(GLuint initial_size) { NORMAL_ATTRIB.ptr = NORMALS.data; NORMAL_ATTRIB.stride = 0; - NORMAL_ATTRIB.type = GL_FLOAT; - NORMAL_ATTRIB.size = 3; + NORMAL_ATTRIB.type = GL_UNSIGNED_INT_2_10_10_10_REV; + NORMAL_ATTRIB.size = 1; ST_ATTRIB.ptr = ST_COORDS.data; ST_ATTRIB.stride = 0; @@ -141,10 +141,25 @@ void APIENTRY glColor3fv(const GLfloat* v) { COLOR[3] = 255; } +static inline uint32_t pack_vertex_attribute_vec3_1ui(float x, float y, float z) { + struct attr_bits_10 { + signed int x:10; + }; + + struct attr_bits_10 xi, yi, zi; + xi.x = x * 511.0f; + yi.x = y * 511.0f; + zi.x = z * 511.0f; + + int ret = (xi.x) | (yi.x << 10) | (zi.x << 20); + + return ret; +} + void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z) { GLVertexKOS* vert = aligned_vector_extend(&VERTICES, 1); GLfloat* st = aligned_vector_extend(&ST_COORDS, 2); - GLfloat* n = aligned_vector_extend(&NORMALS, 3); + GLuint* n = aligned_vector_extend(&NORMALS, 1); vert->x = x; vert->y = y; @@ -157,8 +172,9 @@ void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z) { vert->bgra[B8IDX] = COLOR[2]; vert->bgra[A8IDX] = COLOR[3]; + *n = pack_vertex_attribute_vec3_1ui(NORMAL[0], NORMAL[1], NORMAL[2]); + memcpy(st, ST_COORD, sizeof(GLfloat) * 2); - memcpy(n, NORMAL, sizeof(GLfloat) * 3); } void APIENTRY glVertex3fv(const GLfloat* v) { diff --git a/GL/private.h b/GL/private.h index 35d3407..d079269 100644 --- a/GL/private.h +++ b/GL/private.h @@ -316,6 +316,8 @@ GLboolean _glIsLightingEnabled(); GLboolean _glIsLightEnabled(GLubyte light); GLboolean _glIsColorMaterialEnabled(); +GLboolean _glIsNormalizeEnabled(); + GLboolean _glRecalcFastPath(); typedef struct { diff --git a/GL/state.c b/GL/state.c index 239f5d9..e40295b 100644 --- a/GL/state.c +++ b/GL/state.c @@ -32,6 +32,7 @@ static GLboolean SHARED_PALETTE_ENABLED = GL_FALSE; static GLboolean ALPHA_TEST_ENABLED = GL_FALSE; +static GLboolean NORMALIZE_ENABLED = GL_FALSE; GLboolean _glIsSharedTexturePaletteEnabled() { return SHARED_PALETTE_ENABLED; @@ -83,6 +84,10 @@ static GLenum BLEND_SFACTOR = GL_ONE; static GLenum BLEND_DFACTOR = GL_ZERO; static GLboolean BLEND_ENABLED = GL_FALSE; +GLboolean _glIsNormalizeEnabled() { + return NORMALIZE_ENABLED; +} + GLboolean _glIsBlendingEnabled() { return BLEND_ENABLED; } @@ -333,6 +338,9 @@ GLAPI void APIENTRY glEnable(GLenum cap) { case GL_NEARZ_CLIPPING_KOS: _glEnableClipping(GL_TRUE); break; + case GL_NORMALIZE: + NORMALIZE_ENABLED = GL_TRUE; + break; default: break; } @@ -387,6 +395,9 @@ GLAPI void APIENTRY glDisable(GLenum cap) { case GL_NEARZ_CLIPPING_KOS: _glEnableClipping(GL_FALSE); break; + case GL_NORMALIZE: + NORMALIZE_ENABLED = GL_FALSE; + break; default: break; } @@ -671,7 +682,7 @@ const GLubyte *glGetString(GLenum name) { return (const GLubyte*) "1.2 (partial) - GLdc 1.1"; case GL_EXTENSIONS: - return (const GLubyte*) "GL_ARB_framebuffer_object, GL_ARB_multitexture, GL_ARB_texture_rg, GL_EXT_paletted_texture, GL_EXT_shared_texture_palette, GL_KOS_multiple_shared_palette, GL_ARB_vertex_array_bgra"; + return (const GLubyte*) "GL_ARB_framebuffer_object, GL_ARB_multitexture, GL_ARB_texture_rg, GL_EXT_paletted_texture, GL_EXT_shared_texture_palette, GL_KOS_multiple_shared_palette, GL_ARB_vertex_array_bgra, GL_ARB_vertex_type_2_10_10_10_rev"; } return (const GLubyte*) "GL_KOS_ERROR: ENUM Unsupported\n"; diff --git a/include/gl.h b/include/gl.h index a1d2f57..7679abf 100644 --- a/include/gl.h +++ b/include/gl.h @@ -335,6 +335,8 @@ __BEGIN_DECLS #define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 #define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 + #define GL_COLOR_INDEX 0x1900 #define GL_RED 0x1903 #define GL_GREEN 0x1904 diff --git a/samples/lights/main.c b/samples/lights/main.c index a0e94fc..ea867e5 100644 --- a/samples/lights/main.c +++ b/samples/lights/main.c @@ -181,6 +181,8 @@ void InitGL(int Width, int Height) glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0); glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 4.5 / 100); glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 75.0f / (100 * 100)); + + glEnable(GL_NORMALIZE); }