 update :
i got most of the error's removed
2 error remains :
i got a back picture on screen
i can't find 'black.bmp' on my pc
#include <windows.h>
#include <string>
#include <math.h>
#include <tchar.h>
const int winx = 800 ;
const int winy = 600 ;
#define SMALL 1e-300
#define PI 3.14159265358979323846
class d3d
{
public :
double x , y , z ;
d3d()
{
x = 0.0 ;
y = 0.0 ;
z = 0.0 ;
}
d3d( double X , double Y , double Z )
{
x = X ;
y = Y ;
z = Z ;
}
void fill( double X , double Y , double Z )
{
x = X ;
y = Y ;
z = Z ;
}
unsigned long toColor()
{
return (unsigned long)
( floor( x * 255 ) +
floor( y * 255 ) * 256 +
floor( z * 255 ) * 256 * 256 ) ;
}
} ;
d3d operator + ( d3d a , d3d b )
{
return d3d( a.x + b.x ,
a.y + b.y ,
a.z + b.z ) ;
}
d3d operator - ( d3d a , d3d b )
{
return d3d( a.x - b.x ,
a.y - b.y ,
a.z - b.z ) ;
}
d3d operator / ( d3d a , double b )
{
return d3d( a.x / b ,
a.y / b ,
a.z / b ) ;
}
d3d operator * ( d3d a , double b )
{
return d3d( a.x * b ,
a.y * b ,
a.z * b ) ;
}
double dot( d3d a , d3d b )
{
return a.x * b.x
+ a.y * b.y
+ a.z * b.z ;
}
double length( d3d a )
{
return sqrt( dot( a , a ) ) ;
}
d3d normalize( d3d a )
{
return a / length( a ) ;
}
double getAngle( d3d a , d3d b )
{
double d , la , lb ;
d = dot( a , b ) ;
la = length( a ) ;
lb = length( b ) ;
return acos( d / ( la * lb ) ) ;
}
d3d cross( d3d a , d3d b )
{
return d3d( a.y * b.z - a.z * b.y ,
a.z * b.x - a.x * b.z ,
a.x * b.y - a.y * b.x ) ;
}
const d3d BLACK = d3d( 0.0 , 0.0 , 0.0 ) ;
const d3d RED = d3d( 1.0 , 0.0 , 0.0 ) ;
const d3d GREEN = d3d( 0.0 , 1.0 , 0.0 ) ;
const d3d YELLOW = d3d( 1.0 , 1.0 , 0.0 ) ;
const d3d BLUE = d3d( 0.0 , 0.0 , 1.0 ) ;
const d3d MAGENTA = d3d( 1.0 , 0.0 , 1.0 ) ;
const d3d CYAN = d3d( 0.0 , 1.0 , 1.0 ) ;
const d3d WHITE = d3d( 1.0 , 1.0 , 1.0 ) ;
const d3d GRAY = WHITE / 2.0 ;
const d3d ORANGE = ( YELLOW + RED ) / 2.0 ;
const d3d PINK = ( WHITE + RED ) / 2.0 ;
class m44
{
public :
double m[ 4 ][ 4 ] ;
m44()
{
int i , j ;
for ( i = 0 ; i < 4 ; i++ )
{
for ( j = 0 ; j < 4 ; j++ )
m[ i ][ j ] = 0.0 ;
m[ i ][ i ] = 1.0 ;
}
}
~m44()
{
}
void translate( double x , double y , double z )
{
m[ 3 ][ 0 ] = x ;
m[ 3 ][ 1 ] = y ;
m[ 3 ][ 2 ] = z ;
}
void rotate( double deg , int ax )
{
int a = 1 , b = 2 ;
if ( ax == 1 )
{
a = 0 ;
b = 2 ;
}
if ( ax == 2 )
{
a = 0 ;
b = 1 ;
}
m[ a ][ a ] = cos( deg * PI / 180 ) ;
m[ a ][ b ] = -sin( deg * PI / 180 ) ;
m[ b ][ a ] = sin( deg * PI / 180 ) ;
m[ b ][ b ] = cos( deg * PI / 180 ) ;
}
} ;
m44 operator * ( m44 a , m44 b )
{
int i , j , k ;
m44 uit ;
for ( i = 0 ; i < 4 ; i++ )
{
for ( j = 0 ; j < 4 ; j++ )
{
uit.m[ i ][ j ] = 0.0 ;
for ( k = 0 ; k < 4 ; k++ )
uit.m[ i ][ j ] += a.m[ i ][ k ] * b.m[ k ][ j ] ;
}
}
return uit ;
}
d3d operator * ( m44 m , d3d v )
{
return d3d( m.m[0][0]*v.x+m.m[1][0]*v.y+m.m[2][0]+m.m[3][0]
, m.m[0][1]*v.x+m.m[1][1]*v.y+m.m[2][1]+m.m[3][1]
, m.m[0][2]*v.x+m.m[1][2]*v.y+m.m[2][2]+m.m[3][2]);
}
m44 inverse( m44 q )
{
double d ;
m44 uit ;
d = q.m[0][0]*q.m[1][1]*q.m[2][2]
- q.m[0][0]*q.m[2][1]*q.m[1][2]
+ q.m[1][0]*q.m[2][1]*q.m[0][2]
- q.m[1][0]*q.m[0][1]*q.m[2][2]
+ q.m[2][0]*q.m[0][1]*q.m[1][2]
- q.m[2][0]*q.m[1][1]*q.m[0][2] ;
uit.m[0][0]=(q.m[1][1]*q.m[2][2]-q.m[1][2]*q.m[2][1])/d;
uit.m[1][0]=(q.m[0][1]*q.m[2][2]-q.m[0][2]*q.m[2][1])/d;
uit.m[2][0]=(q.m[0][1]*q.m[1][2]-q.m[0][2]*q.m[1][1])/d;
uit.m[0][1]=(q.m[1][0]*q.m[2][2]-q.m[1][2]*q.m[2][0])/d;
uit.m[1][1]=(q.m[0][0]*q.m[2][2]-q.m[0][2]*q.m[2][0])/d;
uit.m[2][1]=(q.m[0][0]*q.m[1][2]-q.m[0][2]*q.m[1][0])/d;
uit.m[0][2]=(q.m[1][0]*q.m[2][1]-q.m[1][1]*q.m[2][0])/d;
uit.m[1][2]=(q.m[0][0]*q.m[2][1]-q.m[0][1]*q.m[2][0])/d;
uit.m[2][2]=(q.m[0][0]*q.m[1][1]-q.m[0][1]*q.m[1][2])/d;
return uit ;
}
d3d SK[ 64 ] ;
m44 V[ 20 ] ;
int number ;
const int xyz = 0 ;
const int xzy = 1 ;
const int yxz = 2 ;
const int yzx = 3 ;
const int zxy = 4 ;
const int zyx = 5 ;
void link( int no , double x , double y , double z
, double pan , double tilt , double rol , int ax , int p )
{
if ( no < 1 ) return ;
if ( no >= 20 ) return ;
if ( p < 0 ) return ;
if ( p >= 20 ) return ;
if ( p == no ) return ;
m44 trans , rotx , roty , rotz ;
trans.translate( x , y , z ) ;
rotx.rotate( tilt , 0 ) ;
roty.rotate( pan , 1 ) ;
rotz.rotate( rol , 2 ) ;
switch( ax )
{
case xyz :
V[ no ] = rotx * roty * rotz * trans * V[ p ] ;
break ;
case xzy :
V[ no ] = rotx * rotz * roty * trans * V[ p ] ;
break ;
case yxz :
V[ no ] = roty * rotx * rotz * trans * V[ p ] ;
break ;
case yzx :
V[ no ] = roty * rotz * rotx * trans * V[ p ] ;
break ;
case zxy :
V[ no ] = rotz * rotx * roty * trans * V[ p ] ;
break ;
case zyx :
V[ no ] = rotz * roty * rotx * trans * V[ p ] ;
break ;
default :
V[ no ] = rotx * roty * rotz * trans * V[ p ] ;
}
number = no ;
}
void child( int no , double x , double y , double z
, int lim , int ax , int p )
{
if ( lim < 0 ) return ;
if ( lim >= 64 ) return ;
link( no , x , y , z
, SK[ lim ].y , SK[ lim ].x , SK[ lim ].z
, ax , p ) ;
}
void skelet( int lim , double x , double y , double z )
{
if ( lim < 0 ) return ;
if ( lim >= 64 ) return ;
SK[ lim ].fill( x , y , z ) ;
}
double pend( double fase , double amp )
{
return sin( fase * PI / 180 ) * amp ;
}
d3d spot( d3d q )
{
return V[ number ] * q ;
}
struct Matrial
{
d3d diffuse ;
double reflection ;
} ;
Matrial material ;
class Sphere
{
public :
d3d center ;
double radius , radius2 ;
Matrial mat ;
void fill( d3d c , double r )
{
center = spot( c ) ;
radius = r ;
radius2 = r * r ;
mat = material ;
}
double hit( d3d o , d3d d )
{
double t , a , b , c , disc ;
d3d temp = o - center ;
a = dot( d , d ) ;
b = 2 * dot( temp , d ) ;
c = dot( temp , temp ) - radius2 ;
disc = b * b - 4 * a * c ;
if ( disc < 0 )
return INFINITY ;
else
{
double e = sqrt( disc ) ;
double demon = 2 * a ;
t = ( -b - e ) / demon ;
if ( t > SMALL ) return t ;
t = ( -b + e ) / demon ;
if ( t > SMALL ) return t ;
}
return INFINITY ;
}
} ;
Sphere spheres[ 100 ] ;
int spheretel ;
void sphere( double x , double y , double z
, double r , d3d color )
{
d3d pt ;
pt.fill( x , y , z ) ;
material.diffuse = color ;
spheres[ spheretel ].fill( pt , r ) ;
spheretel++ ;
}
d3d light;
d3d render( d3d o , d3d d , int depth )
{
double dist , sphdist = INFINITY ;
int i , isph = -1 ;
for ( i = 0 ; i < spheretel ; i++ )
{
dist = spheres[ i ].hit( o , d ) ;
if ( dist < sphdist )
{
sphdist = dist ;
isph = i ;
}
}
if (isph == -1) return BLACK ;
d3d p , n ;
p = o + d * sphdist ;
n = p - spheres[ isph ].center ;
double a = getAngle( n , light ) ;
d3d color = spheres[ isph ].mat.diffuse ;
color = color * ( 0.5 + cos( a * 2 ) / 2 ) ;
if ( a > PI / 2 ) color = BLACK ;
for ( i = 0 ; i < spheretel ; i++ )
{
if ( i != isph )
{
a = spheres[ i ].hit( p , light ) ;
if ( a == INFINITY ) color = BLACK ;
}
}
return color ;
}
const int arm = 1 ;
const int elbow = 2 ;
const int wrist = 3 ;
const int leg = 4 ;
const int knee = 5 ;
const int enkle = 6 ;
const int neck = 7 ;
const int eye = 8 ;
const int wenk = 9 ;
const int tail = 10 ;
const int thumb = 11 ;
const int index = 14 ;
const int midle = 17 ;
const int ring = 20 ;
const int lr = 32 ;
void Kop( int qq , d3d kl )
{
link( 15, 0, 0, 0, 0, 0, 0, xyz, number ) ;
sphere( 0, 0, 0, 30, kl ) ;
if ( qq == 1 )
{
sphere( 25, 25, 0, 9, kl ) ;
sphere( -25, 25, 0, 9, kl ) ;
sphere( 0, 0, -40, 12, GRAY ) ;
}
else
{
sphere( 30, 0, 0, 9, kl ) ;
sphere( -30, 0, 0, 9, kl ) ;
sphere( 0, 0, -40, 12, kl ) ;
}
child( 16, 14, 14, -14, eye , xyz, 15 ) ;
sphere( 0, 0, 0, 13, WHITE ) ;
sphere( 0, 0, -10, 7, BLACK ) ;
child( 16, -14, 14, -14, eye + lr, xyz, 15 ) ;
sphere( 0, 0, 0, 13, WHITE ) ;
sphere( 0, 0, -10, 7, BLACK ) ;
}
void human( d3d trui , d3d broek )
{
link( 9 , 0,0,0 , 0,0,0 , xyz , number ) ;
sphere( 0, 50, 0, 30, trui ) ;
sphere( 0, 25, 0, 23, broek ) ;
sphere( 0, 0, 0, 15, broek ) ;
child( 11, 0, 70, 0, neck, xyz, 9 ) ;
child( 12, 0, 30, 0, neck+lr, xyz, 11 ) ;
Kop( 0, PINK ) ;
child( 11, 20, -10, 0, leg, yzx, 9 ) ;
sphere( 0, 0, 0, 16, broek ) ;
sphere( 0, -20, 0, 16, broek ) ;
child( 12, 0, -40, 0, knee, xyz, 11 ) ;
sphere( 0, 0, 0, 16, broek ) ;
sphere( 0, -20, 0, 16, broek ) ;
child( 13, 0, -40, 0, enkle, xzy, 12 ) ;
sphere( 0, 0, 0, 12, GRAY ) ;
sphere( 0, 0, -20, 12, GRAY ) ;
child( 11, -20, -10, 0, leg+lr , yzx, 9 ) ;
sphere( 0, 0, 0, 16, broek ) ;
sphere( 0, -20, 0, 16, broek ) ;
child( 12, 0, -40, 0, knee+lr, xyz, 11 ) ;
sphere( 0, 0, 0, 16, broek ) ;
sphere( 0, -20, 0,16, broek ) ;
child( 13, 0, -40, 0,enkle+lr, xzy, 12 ) ;
sphere( 0, 0, 0, 12, GRAY ) ;
sphere( 0, 0, -20, 12, GRAY ) ;
child( 11, 40, 60, 0, arm, xzy, 9 ) ;
sphere( 0, 0, 0, 16, trui ) ;
sphere( 6, -20, 0, 12, trui ) ;
child( 12, 6, -40, 0, elbow, xyz, 11 ) ;
sphere( 0, 0, 0, 12, trui ) ;
sphere( 0, -20, 0, 12, trui ) ;
sphere( 0, -42, 0, 8, PINK ) ;
child( 11, -40, 60, 0, arm+lr, xzy, 9 ) ;
sphere( 0, 0, 0, 16, trui ) ;
sphere( -6, -20, 0, 12, trui ) ;
child( 12, -6, -40, 0, elbow+lr, xyz, 11 ) ;
sphere( 0, 0, 0, 12, trui ) ;
sphere( 0, -20, 0, 12, trui ) ;
sphere( 0, -42, 0, 8, PINK ) ;
}
void human_walk( double f , double a )
{
skelet( arm , pend( f , a ) , 0 , 0 ) ;
skelet( elbow , -abs( a ) , 0 , 0 ) ;
skelet( arm + lr , pend( f + 180, a ) , 0 , 0 ) ;
skelet( elbow + lr , -abs( a ) , 0 , 0 ) ;
skelet( leg , pend( f + 180 , a ) , 0 , 0 ) ;
skelet( knee , pend( f + 90 , a ) + a , 0 , 0 ) ;
skelet( leg + lr , pend( f , a ) , 0 , 0 ) ;
skelet( knee + lr , pend( f - 90 , a ) + a , 0 , 0 ) ;
}
void frameName ( TCHAR* buffer ,
int bufsize ,
const TCHAR* nameStart ,
const TCHAR* ext ,
int no , int len )
{
}
int CaptureAnImage( HWND hWnd , char* filename )
{
HDC hdcScreen;
HDC hdcWindow;
HDC hdcMemDC = NULL;
HBITMAP hbmScreen = NULL;
BITMAP bmpScreen;
hdcScreen = GetDC(NULL);
hdcWindow = GetDC(hWnd);
hdcMemDC = CreateCompatibleDC(hdcWindow);
if (!hdcMemDC)
{
MessageBox(hWnd, _T("CreateCompatibleDC has failed"),
_T("Failed"), MB_OK) ;
}
else
{
RECT rcClient;
GetClientRect(hWnd, &rcClient);
SetStretchBltMode(hdcWindow, HALFTONE);
if (!StretchBlt(hdcWindow,
0, 0,
rcClient.right, rcClient.bottom,
hdcScreen,
0, 0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
SRCCOPY))
{
MessageBox(hWnd, _T("StretchBlt has failed"),
_T("Failed"), MB_OK) ;
}
else
{
hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top);
if (!hbmScreen)
{
MessageBox(hWnd, _T("CreateCompatibleBitmap Failed"),
_T("Failed"), MB_OK) ;
}
else
{
SelectObject(hdcMemDC, hbmScreen);
if (!BitBlt(hdcMemDC,
0, 0,
rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
hdcWindow,
0, 0,
SRCCOPY))
{
MessageBox(hWnd,
_T("BitBlt has failed"),
_T("Failed"), MB_OK) ;
}
else
{
GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen);
BITMAPFILEHEADER bmfHeader;
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bmpScreen.bmWidth;
bi.biHeight = bmpScreen.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;
HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);
char *lpbitmap = (char *)GlobalLock(hDIB);
GetDIBits(hdcWindow, hbmScreen, 0,
(UINT)bmpScreen.bmHeight,
lpbitmap,
(BITMAPINFO *)&bi, DIB_RGB_COLORS);
HANDLE hFile = CreateFile(filename,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
bmfHeader.bfSize = dwSizeofDIB;
bmfHeader.bfType = 0x4D42;
DWORD dwBytesWritten = 0;
WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);
GlobalUnlock(hDIB);
GlobalFree(hDIB);
CloseHandle(hFile);
}
}
}
}
DeleteObject(hbmScreen);
DeleteObject(hdcMemDC);
ReleaseDC(NULL, hdcScreen);
ReleaseDC(hWnd, hdcWindow);
return 0;
}
LRESULT CALLBACK WndProc( HWND hwnd ,
UINT Message ,
WPARAM wParam ,
LPARAM lParam )
{
HDC hdc ;
PAINTSTRUCT ps ;
switch (Message)
{
case WM_PAINT :
{
int x , y , picno ;
d3d o , d ;
unsigned long color ;
hdc = BeginPaint( hwnd , &ps ) ;
spheretel = 0 ;
light.fill( -1.0 , 1.0 , -1.0 ) ;
link( 1 , 0.0 , 100 - winy / 2 , 0.0 ,
30.0 , 0.0 , 0.0 , xyz , 0 ) ;
human( YELLOW , BLUE ) ;
sphere( 0.0 , -INFINITY - winy / 2 , 0.0
, INFINITY , ( WHITE + GREEN ) / 2 ) ;
for ( x = 0 ; x < winx ; x++ )
{
for ( y = 0 ; y < winy ; y++ )
{
o.fill( 0.0 , 0.0 , -1000.0 ) ;
d.fill( (double)x , (double)y , 1000.0 ) ;
color = render( o , d , 7 ).toColor() ;
SetPixel( hdc , x , y , color ) ;
}
}
int dummy = CaptureAnImage( hwnd , _T( "black.bmp" ) ;
EndPaint( hwnd , &ps ) ;
break ;
}
case WM_DESTROY :
{
PostQuitMessage( 0 ) ;
break ;
}
default :
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0 ;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = "WindowClass";
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, _T("Window Registration Failed!"), _T("Error!"), MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("WindowClass"), _T("Caption"), WS_VISIBLE | WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
winx,
winy,
NULL, NULL, hInstance, NULL);
if (hwnd == NULL) {
MessageBox(NULL, _T("Window Creation Failed!"), _T("Error!"), MB_ICONEXCLAMATION | MB_OK);
return 0;
}
while (GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
|