projectM-visualizer / projectm

projectM - Cross-platform Music Visualization Library. Open-source and Milkdrop-compatible.
https://discord.gg/mMrxAqaa3W
GNU Lesser General Public License v2.1
3.22k stars 365 forks source link

Interpret negative alpha in shapes and waveforms as full intensity #781

Closed dpw13 closed 4 months ago

dpw13 commented 4 months ago

Mostly fixes xtramartin(186).

dpw13 commented 4 months ago

image

kblaschke commented 4 months ago

It's not actually DirectX doing something different or wrong here, but the way how Milkdrop converts/passes the color into the vertex data. Milkdrop converts the float value times 255 to int and then masks away all bits except the last eight and assigns each color plus alpha to a 32-bit unsigned int representing an 8-bit RGBA color value:

                    v[0].Diffuse = 
                        ((((int)(*pState->m_shape[i].var_pf_a * 255 * alpha_mult)) & 0xFF) << 24) |
                        ((((int)(*pState->m_shape[i].var_pf_r * 255)) & 0xFF) << 16) |
                        ((((int)(*pState->m_shape[i].var_pf_g * 255)) & 0xFF) <<  8) |
                        ((((int)(*pState->m_shape[i].var_pf_b * 255)) & 0xFF)      );

This conversion will actually result in a sawtooth curve. We could perform a similar calculation to match the original code as closely as possible. In projectM's vertex attributes, each color is a float, and if you render negative color values, you'll always get black.