www.pudn.com > RayTrace.rar > LightTrack.cpp, change:2006-07-21,size:9376b
//LightTrack.cpp
#include "LightTrack.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h> /* var arg stuff */
#include "Track.h"
#include "Colour.h"
#include "Graphics.h"
#include "data.h"
#include "Vector.h"
#include <string.h>
//extern int main(int n,char **o); /* real main (well...) */
int Depth = 3 ; // 跟踪深度
int Position_Y = -300 ;
int Position_X = 0 ;
int Position_Z = 700 ;
int HW_cmd_show;
HINSTANCE HW_instance;
char HW_class_name[] = "LightTrack windows";
HWND HW_wnd; /* window */
HPALETTE HW_palette; /* the palette headers */
HDC HW_mem;
HBITMAP HW_bmp;
RECT HW_rect;
#if defined(_RGB_) /* paths to data sets */
#if defined(_32BPP_)
char path[128]="";
#endif
#endif
struct TR_world *w;
void HWI_null_function(void) {}
void (*HW_application_main)(void) = HWI_null_function;
void (*HW_application_key_handler)(int key_code);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
/**********************************************************\
* Quiting with a message. *
\**********************************************************/
#define HW_MAX_ERROR_MESSAGE 256
void HW_error(char *s,...)
{
char str[HW_MAX_ERROR_MESSAGE];
va_list lst;
va_start(lst,s);
vsprintf(str,s,lst); /* forming the message */
va_end(lst);
MessageBox(NULL,str,"LightTrack",MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
HW_close_event_loop();
exit(0); /* above might not be enough */
}
/**********************************************************\
* Quitting the event loop. *
\**********************************************************/
void HW_close_event_loop(void)
{
PostMessage(HW_wnd,WM_CLOSE,0,0L); /* telling ourselves to quit */
}
/**********************************************************\
* Implementations for fast memory fill. *
\**********************************************************/
void HW_set_int(int *d,long l,int v)
{
long i;
for(i=0;i<l;i++) *d++=v;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#define HW_MAX_CLINE_OPTIONS 20
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd )
{
WNDCLASS w;
int n;
char *start,*end;
char *o[HW_MAX_CLINE_OPTIONS];
HW_cmd_show = nShowCmd;
if ((HW_instance = hPrevInstance) == NULL)
{
w.style = CS_HREDRAW|CS_VREDRAW;
w.lpfnWndProc = WndProc;
w.cbClsExtra = 0;
w.cbWndExtra = 0;
w.hInstance = hInstance;
w.hIcon = NULL;
w.hCursor = NULL;
w.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
w.lpszMenuName = NULL;
w.lpszClassName = HW_class_name;
if (!RegisterClass(&w))
{
return FALSE;
}
}
n = 0;
o[n++] = "";
start = lpCmdLine;
while ((end = strchr(start, ' ')) != NULL)
{
if (n >= HW_MAX_CLINE_OPTIONS)
{
HW_error("(LightTrack windows) Way too many command line options.\n");
}
if (end != start)
{
o[n++] = start;
}
*end = 0;
start = end + 1;
}
if (strlen(start) > 0)
{
o[n++] = start;
}
return(main(n,0));
}
extern int Depth ; // 跟踪深度
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_PAINT:
HW_application_main();
break;
case WM_ERASEBKGND:
return(1L);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
if (wParam==VK_ESCAPE)
{
PostMessage(HW_wnd,WM_CLOSE,0,0L); //HW_application_key_handler(wParam);
}
if (wParam==VK_F1)
{
Depth--;
if (Depth =0)
{
Depth = 0 ;
}
}
if (wParam==VK_F2)
{
if (Depth >=5)
{
Depth = 5 ;
}
else Depth++;
}
if (wParam==VK_UP )
{
Position_Y -= 10 ;
}
if (wParam==VK_DOWN )
{
Position_Y += 10 ;
}
if (wParam==VK_LEFT )
{
Position_X -= 10 ;
}
if (wParam==VK_RIGHT )
{
Position_X +=10 ;
}
if (wParam=='A' )
{
Position_Z -=100 ;
}
if (wParam=='Z' )
{
Position_Z +=100 ;
}
break;
default:
return(DefWindowProc(hWnd,message,wParam,lParam));
}
return(0L);
}
/**********************************************************\
* Creating a window. *
\**********************************************************/
#if defined(_RGB_)
void HW_init_screen(char *display_name,
char *screen_name
)
#endif
{
PAINTSTRUCT ps;
HW_wnd = CreateWindow(HW_class_name,
screen_name,
WS_SYSMENU,
CW_USEDEFAULT,
CW_USEDEFAULT,
HW_SCREEN_X_SIZE,
HW_SCREEN_Y_SIZE+GetSystemMetrics(SM_CYCAPTION),
NULL,
NULL,
HW_instance,
NULL);
HW_mem=CreateCompatibleDC(BeginPaint(HW_wnd,&ps));
if(((GetDeviceCaps(ps.hdc,PLANES))!=1)||
((GetDeviceCaps(ps.hdc,BITSPIXEL))!=sizeof(HW_pixel)*8)
)
//HW_error("%d",(GetDeviceCaps(ps.hdc,BITSPIXEL)));
HW_error("(Hardware) I'd rather have %d bit screen.",
sizeof(HW_pixel)*8
);
HW_bmp=CreateCompatibleBitmap(ps.hdc,HW_SCREEN_X_SIZE,HW_SCREEN_Y_SIZE);
SelectObject(HW_mem,HW_bmp);
EndPaint(HW_wnd,&ps);
HW_rect.left=HW_rect.top=0;
//窗口的大小
HW_rect.right=HW_SCREEN_X_SIZE;
HW_rect.bottom=HW_SCREEN_Y_SIZE;
ShowWindow(HW_wnd,HW_cmd_show); /* generate messages */
UpdateWindow(HW_wnd);
}
//////////////////////////////////////////////////////////////////////////////////
/**********************************************************\
* Rendering the bitmap into the window. *
\**********************************************************/
//复制图像位图到物理设备存储器
void HW_blit(void)
{
PAINTSTRUCT ps;
//
BeginPaint(HW_wnd,&ps);
SelectPalette(ps.hdc,HW_palette,FALSE);
RealizePalette(ps.hdc);
SetMapMode(ps.hdc,MM_TEXT);
SetBitmapBits(HW_bmp,G_c_buffer_size*sizeof(HW_pixel),G_c_buffer);
BitBlt(ps.hdc,0,0,HW_SCREEN_X_SIZE,HW_SCREEN_Y_SIZE,HW_mem,0,0,SRCCOPY);
EndPaint(HW_wnd,&ps);
}
void app_main(void) /* rendering loop */
{
//光线跟踪场景中设置摄像机
//TR_set_camera(0,0,500, 0,0,0, 1,0,0, 0,1,0);Position_X
TR_set_camera(Position_X,Position_Y,-1.0*Position_Z, 0,0,0, 1,0,0, 0,1,0);
//关键中的关键,光线跟踪窗口中的pixel
TR_trace_world(w,Depth);
{
char str[100]="Now depth = ";
char * p = str; char strDepth[10];
itoa(Depth,strDepth,10);
p=strcat(str,strDepth);
G_text(270,10,p,
CL_colour(CL_COLOUR_LEVELS-1,CL_COLOUR_LEVELS-1,CL_COLOUR_LEVELS-1),
CL_LIGHT_LEVELS-1,CL_LIGHT_LEVELS-1,CL_LIGHT_LEVELS-1);
}
{
char str[100]="F1 - Sub Depth ; f2 - add depth ";
char * p = str;
G_text(270,30,p,
CL_colour(CL_COLOUR_LEVELS-1,CL_COLOUR_LEVELS-1,CL_COLOUR_LEVELS-1),
CL_LIGHT_LEVELS-1,CL_LIGHT_LEVELS-1,CL_LIGHT_LEVELS-1);
}
G_text(270,50,"Esc - exit program ",
CL_colour(CL_COLOUR_LEVELS-1,CL_COLOUR_LEVELS-1,CL_COLOUR_LEVELS-1),
CL_LIGHT_LEVELS-1,CL_LIGHT_LEVELS-1,CL_LIGHT_LEVELS-1);
G_text(270,70,"arrow(left,right,up,down) - change view",
CL_colour(CL_COLOUR_LEVELS-1,CL_COLOUR_LEVELS-1,CL_COLOUR_LEVELS-1),
CL_LIGHT_LEVELS-1,CL_LIGHT_LEVELS-1,CL_LIGHT_LEVELS-1);
G_text(270,90,"\'a\' or \'z\' -> - change distance ",
CL_colour(CL_COLOUR_LEVELS-1,CL_COLOUR_LEVELS-1,CL_COLOUR_LEVELS-1),
CL_LIGHT_LEVELS-1,CL_LIGHT_LEVELS-1,CL_LIGHT_LEVELS-1);
HW_blit();
}
void app_handler(int kk) /* event handler */
{
HW_close_event_loop();
}
void HW_close_screen(void)
{
DeleteDC(HW_mem);
DeleteObject(HW_bmp);
}
int main(int n, char **o)
{
char *display;
if (n == 2)
display = o[1];
else
display = NULL;
strcat(path,"tracer.dat");
w = (struct TR_world *)D_data(path);
CL_init_colour();
TR_init_rendering(TR_SPECULAR|TR_SHADOW|TR_REFLECT);
TR_init_world(w);
G_init_graphics();
HW_init_screen(display,"LightTrack");
HW_init_event_loop(app_main,app_handler);
HW_close_screen();
return(1);
}
/**********************************************************\
* Running the event loop. *
\**********************************************************/
//事件循环函数,第一个函数指针被不停执行,第二个响应外部时间
void HW_init_event_loop(void (*application_main)(void),
void (*application_key_handler)(int key_code)
)
{
MSG msg;
HW_application_main=application_main;
HW_application_key_handler=application_key_handler;
while(1)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) /* this IS sensitive part! */
{
if(msg.message == WM_QUIT) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
InvalidateRect(HW_wnd,&HW_rect,TRUE);
UpdateWindow(HW_wnd);
}
}
}