Original Post
I've been looking at some MMX routines, but I still don't fully understand them. How do they operate on the entire pixel at once? I'm using a DIBSection to do all my drawing, so all the drawing is by setting the bits... but apparently I don't understand something.
bi.bmiHeader.biSize = sizeof(BITMAPINFO);
bi.bmiHeader.biWidth = SCENE_WIDTH;
bi.bmiHeader.biHeight = -SCENE_HEIGHT; //top down DIB
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
hdc = GetDC(hwnd);
hdcMem = CreateCompatibleDC(hdc);
hDib = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (LPVOID*)&lpBits, 0, 0);
SelectObject(hdcMem, (HGDIOBJ)hDib); Setup is typical enough... Here's what I was doing... lpBits was a BYTE* and drawing like this is flawless. (which is basically from the MMX article)
BYTE* dst = lpBits + (y * SCENE_WIDTH + x) << 2;
dst[0] = a * (b - dst[0]) / 255 + dst[0];
dst[1] = a * (g - dst[1]) / 255 + dst[1];
dst[2] = a * (r - dst[2]) / 255 + dst[2];
I figured I could just do something like this though... color is a colorref / dword.
DWORD* dst = lpBits + (y * SCENE_WIDTH + x);
*dst = a * (color - *dst) / 255 + *dst;
I've ran the math, and it seems to give the right colors / results. #include <iostream>
#include <iomanip>
using namespace std;
unsigned int FakeBlend(char a, unsigned int color, unsigned int dest){
return (a * (color - dest) / 255 + dest);
}
int main()
{
unsigned int alpha;
for(int i = 0; i < 255; i++){
alpha = FakeBlend(i, 0x00FFFF00, 0x00FF0000);
cout << hex << alpha << endl;
}
return 0;
} Except past 128 something funky seems to go on. 00 FF 7F 00... @ 128 01 FF 81 01... @ 129 I'm pretty sure that this 01 is what is my undoing. 0x00FFFF00 - 0x01FF8101 = -0x00FF8201 or CLEARLY WRONG. Any subtraction against 0x00 blows up the entire routine. For example: yellow 0x00FFFF00 blending against a white backround 0x00FFFFFF will end in disaster. Anyone have any idea for a solution to this, or a better way to go about this?