#ifndef _RC10_REGISTER_H #define _RC10_REGISTER_H #include #include #define RCP_NUM_GENERAL_COMBINERS 8 #define RCP_RGB 0 #define RCP_ALPHA 1 #define RCP_BLUE 2 #define RCP_NONE 3 typedef union _RegisterEnum { struct { #if BYTE_ORDER != BIG_ENDIAN unsigned int name :16; // OpenGL enum for register unsigned int channel : 2; // RCP_RGB, RCP_ALPHA, etc unsigned int readOnly : 1; // true or false unsigned int finalOnly : 1; // true or false unsigned int unused :12; #else unsigned int unused :12; unsigned int finalOnly : 1; // true or false unsigned int readOnly : 1; // true or false unsigned int channel : 2; // RCP_RGB, RCP_ALPHA, RCP_BLUE, RCP_NONE unsigned int name :16; // OpenGL enum for register #endif } bits; unsigned int word; } RegisterEnum; // No need for writeOnly flag, since DISCARD is the only register in that category // WARNING: Don't monkey with the above structure or this macro // unless you're absolutely sure of what you're doing! // This constant allocation makes validation *much* cleaner. #define RCP_SET_REGISTER_ENUM(name, channel, readonly, finalonly) \ ((finalonly << 19) | (readonly << 18) | (channel << 16) | name) #define RCP_FOG_RGB RCP_SET_REGISTER_ENUM(GL_FOG, RCP_RGB, 1, 0) #define RCP_FOG_ALPHA RCP_SET_REGISTER_ENUM(GL_FOG, RCP_ALPHA, 1, 1) #define RCP_FOG_BLUE RCP_SET_REGISTER_ENUM(GL_FOG, RCP_BLUE, 1, 0) #define RCP_FOG RCP_SET_REGISTER_ENUM(GL_FOG, RCP_NONE, 1, 0) #define RCP_PRIMARY_COLOR_RGB RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_RGB, 0, 0) #define RCP_PRIMARY_COLOR_ALPHA RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_ALPHA, 0, 0) #define RCP_PRIMARY_COLOR_BLUE RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_BLUE, 0, 0) #define RCP_PRIMARY_COLOR RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_NONE, 0, 0) #define RCP_SECONDARY_COLOR_RGB RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_RGB, 0, 0) #define RCP_SECONDARY_COLOR_ALPHA RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_ALPHA, 0, 0) #define RCP_SECONDARY_COLOR_BLUE RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_BLUE, 0, 0) #define RCP_SECONDARY_COLOR RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_NONE, 0, 0) #define RCP_SPARE0_RGB RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_RGB, 0, 0) #define RCP_SPARE0_ALPHA RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_ALPHA, 0, 0) #define RCP_SPARE0_BLUE RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_BLUE, 0, 0) #define RCP_SPARE0 RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_NONE, 0, 0) #define RCP_SPARE1_RGB RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_RGB, 0, 0) #define RCP_SPARE1_ALPHA RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_ALPHA, 0, 0) #define RCP_SPARE1_BLUE RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_BLUE, 0, 0) #define RCP_SPARE1 RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_NONE, 0, 0) #define RCP_TEXTURE0_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_RGB, 0, 0) #define RCP_TEXTURE0_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_ALPHA, 0, 0) #define RCP_TEXTURE0_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_BLUE, 0, 0) #define RCP_TEXTURE0 RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_NONE, 0, 0) #define RCP_TEXTURE1_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_RGB, 0, 0) #define RCP_TEXTURE1_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_ALPHA, 0, 0) #define RCP_TEXTURE1_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_BLUE, 0, 0) #define RCP_TEXTURE1 RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_NONE, 0, 0) #define RCP_TEXTURE2_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_RGB, 0, 0) #define RCP_TEXTURE2_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_ALPHA, 0, 0) #define RCP_TEXTURE2_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_BLUE, 0, 0) #define RCP_TEXTURE2 RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_NONE, 0, 0) #define RCP_TEXTURE3_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_RGB, 0, 0) #define RCP_TEXTURE3_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_ALPHA, 0, 0) #define RCP_TEXTURE3_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_BLUE, 0, 0) #define RCP_TEXTURE3 RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_NONE, 0, 0) #define RCP_CONST_COLOR0_RGB RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_RGB, 1, 0) #define RCP_CONST_COLOR0_ALPHA RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_ALPHA, 1, 0) #define RCP_CONST_COLOR0_BLUE RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_BLUE, 1, 0) #define RCP_CONST_COLOR0 RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_NONE, 1, 0) #define RCP_CONST_COLOR1_RGB RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_RGB, 1, 0) #define RCP_CONST_COLOR1_ALPHA RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_ALPHA, 1, 0) #define RCP_CONST_COLOR1_BLUE RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_BLUE, 1, 0) #define RCP_CONST_COLOR1 RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_NONE, 1, 0) #define RCP_ZERO_RGB RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_RGB, 1, 0) #define RCP_ZERO_ALPHA RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_ALPHA, 1, 0) #define RCP_ZERO_BLUE RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_BLUE, 1, 0) #define RCP_ZERO RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_NONE, 1, 0) #define RCP_ONE_RGB RCP_SET_REGISTER_ENUM(GL_ONE, RCP_RGB, 1, 0) #define RCP_ONE_ALPHA RCP_SET_REGISTER_ENUM(GL_ONE, RCP_ALPHA, 1, 0) #define RCP_ONE_BLUE RCP_SET_REGISTER_ENUM(GL_ONE, RCP_BLUE, 1, 0) #define RCP_ONE RCP_SET_REGISTER_ENUM(GL_ONE, RCP_NONE, 1, 0) #define RCP_DISCARD RCP_SET_REGISTER_ENUM(GL_DISCARD_NV, RCP_NONE, 0, 0) #define RCP_FINAL_PRODUCT RCP_SET_REGISTER_ENUM(GL_E_TIMES_F_NV, RCP_NONE, 1, 1) #define RCP_COLOR_SUM RCP_SET_REGISTER_ENUM(GL_SPARE0_PLUS_SECONDARY_COLOR_NV, RCP_NONE, 1, 1) #define MAP_CHANNEL(channel) ((RCP_RGB == (channel)) ? GL_RGB : (RCP_ALPHA == (channel) ? GL_ALPHA : GL_BLUE)) typedef union _BiasScaleEnum { struct { #if BYTE_ORDER != BIG_ENDIAN unsigned int bias :16; // OpenGL enum for bias unsigned int scale :16; // OpenGL enum for scale #else unsigned int scale :16; // OpenGL enum for scale unsigned int bias :16; // OpenGL enum for bias #endif } bits; unsigned int word; } BiasScaleEnum; // WARNING: Don't monkey with the above structure or this macro // unless you're absolutely sure of what you're doing! // This constant allocation makes validation *much* cleaner. #define RCP_SET_BIAS_SCALE_ENUM(bias, scale) ((scale << 16) | bias) #define RCP_BIAS_BY_NEGATIVE_ONE_HALF_SCALE_BY_TWO RCP_SET_BIAS_SCALE_ENUM(GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_SCALE_BY_TWO_NV) #define RCP_BIAS_BY_NEGATIVE_ONE_HALF RCP_SET_BIAS_SCALE_ENUM(GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_NONE) #define RCP_SCALE_BY_ONE_HALF RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_SCALE_BY_ONE_HALF_NV) #define RCP_SCALE_BY_ONE RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_NONE) #define RCP_SCALE_BY_TWO RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_SCALE_BY_TWO_NV) #define RCP_SCALE_BY_FOUR RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_SCALE_BY_FOUR_NV) class MappedRegisterStruct { public: void Init(RegisterEnum _reg, int _map = GL_UNSIGNED_IDENTITY_NV) { if (RCP_ONE == _reg.bits.name) { _reg.bits.name = RCP_ZERO; switch (_map) { case GL_UNSIGNED_IDENTITY_NV: _map = GL_UNSIGNED_INVERT_NV; break; case GL_UNSIGNED_INVERT_NV: _map = GL_UNSIGNED_IDENTITY_NV; break; case GL_EXPAND_NORMAL_NV: _map = GL_UNSIGNED_INVERT_NV; break; case GL_EXPAND_NEGATE_NV: _map = GL_EXPAND_NORMAL_NV; break; case GL_HALF_BIAS_NORMAL_NV: _map = GL_HALF_BIAS_NEGATE_NV; break; case GL_HALF_BIAS_NEGATE_NV: _map = GL_HALF_BIAS_NORMAL_NV; break; case GL_SIGNED_IDENTITY_NV: _map = GL_UNSIGNED_INVERT_NV; break; case GL_SIGNED_NEGATE_NV: _map = GL_EXPAND_NORMAL_NV; break; } } map = _map; reg = _reg; } int map; RegisterEnum reg; }; #ifdef TEST_BIT_FIELDS class RegisterEnumTest { public: RegisterEnumTest() { RegisterEnum reg; bool error = false; if (sizeof(reg.bits) != sizeof(reg.word)) error = true; reg.word = 0; reg.bits.name = 0xFFFF; if (RCP_SET_REGISTER_ENUM(0xFFFF, 0, 0, 0) != reg.word) error = true; reg.word = 0; reg.bits.channel = 3; if (RCP_SET_REGISTER_ENUM(0, 3, 0, 0) != reg.word) error = true; reg.word = 0; reg.bits.readOnly = true; if (RCP_SET_REGISTER_ENUM(0, 0, 1, 0) != reg.word) error = true; reg.word = 0; reg.bits.finalOnly = true; if (RCP_SET_REGISTER_ENUM(0, 0, 0, 1) != reg.word) error = true; if (error) { fprintf(stderr, "ERROR: Bit Fields were not compiled correctly in " __FILE__ "!\n"); exit(1); } } }; static RegisterEnumTest registerEnumTest; #endif #endif