#include <windows.h>
#include <math.h>
#define PI (3.1415926535897932384626433832795)
#define PI2 (PI * 2.0)
#define W 128
#define H 128
#define SW (W*4)
#define SH (H*4)
#define R (50)
typedef unsigned long u32;
typedef float f32;
static char g_szWindowName[] = "dib";
static char g_szWindowClass[] = "dib32";
static HINSTANCE g_hInst;
static HWND g_hWnd;
static BITMAPINFO g_bi;
static u32 * p_dib;
// взято из OpenGL
float j15[] = {
0.285561f, 0.188437f,
0.360176f, -0.065688f,
-0.111751f, 0.275019f,
-0.055918f, -0.215197f,
-0.080231f, -0.470965f,
0.138721f, 0.409168f,
0.384120f, 0.458500f,
-0.454968f, 0.134088f,
0.179271f, -0.331196f,
-0.307049f, -0.364927f,
0.105354f, -0.010099f,
-0.154180f, 0.021794f,
-0.370135f, -0.116425f,
0.451636f, -0.300013f,
-0.370610f, 0.387504f };
void a_sincos_scale( float, float, float *, float * );
#pragma aux a_sincos_scale = \
"fsincos" \
"fmul st, st(2)" \
"fstp dword ptr [edx]" \
"fmulp st(1), st" \
"fstp dword ptr [eax]" \
parm [8087] [8087] [eax] [edx] \
modify [8087];
float inline q_circle_squared( int x, int y, float cx, float cy )
{
float dx, dy;
dx = cx - x;
dy = cy - y;
return dx * dx + dy * dy;
}
long circle_15xjitter( int x, int y, float cx, float cy, float r0, float r1, float phase )
{
int i, k, isec;
float jx, jy, r0s, r1s, d;
long sum;
r0s = r0 * r0;
r1s = r1 * r1;
for ( i = 0, sum = 0; i < (15<<1); i += 2 ) {
jx = cx + j15[i ];
jy = cy + j15[i+1];
isec = 0;
d = q_circle_squared( x, y, jx, jy );
if ( d < r0s ) isec = 1;
if ( !isec ) continue;
for ( k = 0; k < 6; k++ ) {
float xsin, ycos;
a_sincos_scale( phase, r0, &xsin, &ycos );
if ( q_circle_squared( x, y, xsin+jx, ycos+jy ) < r1s ) {
isec = 0;
break;
}
phase += PI * 2 / 6;
}
if ( isec ) sum += 0x11;
}
return sum;
}
static void test( void )
{
u32 c;
int x, y;
f32 cx, cy;
static f32 phase = 0.0f;
cx = cos( phase ) * 10.0f + (W / 2);
cy = sin( phase ) * 10.0f + (H / 2);
for ( y = 0; y < H; y++ )
for ( x = 0; x < W; x++ ) {
c = circle_15xjitter( x, y, (f32)W / 2, (f32)H / 2, H-(H/10), H-(H/3), phase );
c = (c << 16) | (c << 8) | c;
p_dib[W * y + x] = c;
}
phase += 0.01f;
}
static LRESULT CALLBACK wnd_proc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch ( uMsg ) {
case WM_NCHITTEST: return HTCAPTION;
case WM_PAINT: {
PAINTSTRUCT ps;
BeginPaint( hWnd, &ps );
StretchDIBits( ps.hdc, 0, 0, SW, SH, 0, 0, W, H, p_dib, &g_bi, DIB_RGB_COLORS, SRCCOPY );
EndPaint( hWnd, &ps );
} return 0;
case WM_KEYDOWN: if ( (int)wParam != VK_ESCAPE ) break;
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
int APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
MSG msg;
WNDCLASS wc;
HDC hdc;
g_hInst = hInst;
memset( &wc, 0, sizeof( WNDCLASS ) );
wc.style = CS_OWNDC | CS_DBLCLKS;
wc.lpfnWndProc = wnd_proc;
wc.hInstance = hInst;
wc.lpszClassName = g_szWindowClass;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
RegisterClass( &wc );
g_hWnd = CreateWindowEx( WS_EX_TOPMOST,
g_szWindowClass, g_szWindowName, WS_POPUP | WS_VISIBLE,
(GetSystemMetrics( SM_CXSCREEN ) >> 1) - (SW >> 1),
(GetSystemMetrics( SM_CYSCREEN ) >> 1) - (SH >> 1),
SW, SH, NULL, NULL, hInst, NULL );
memset( &g_bi, 0, sizeof( BITMAPINFO ) );
g_bi.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
g_bi.bmiHeader.biWidth = W;
g_bi.bmiHeader.biHeight = -H;
g_bi.bmiHeader.biPlanes = 1;
g_bi.bmiHeader.biBitCount = 32;
g_bi.bmiHeader.biCompression = BI_RGB;
p_dib = malloc( W * H * 4 );
memset( &msg, 0, sizeof( MSG ) );
while ( msg.message != WM_QUIT ) {
if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
TranslateMessage( &msg );
DispatchMessage( &msg );
} else {
memset( p_dib, 255, W * H * 4 );
test();
hdc = GetWindowDC( g_hWnd );
StretchDIBits( hdc, 0, 0, SW, SH, 0, 0, W, H, p_dib, &g_bi, DIB_RGB_COLORS, SRCCOPY );
ReleaseDC( g_hWnd, hdc );
Sleep( 50 );
}
}
free( p_dib );
DestroyWindow( g_hWnd );
UnregisterClass( g_szWindowClass, g_hInst );
return 0;
}