0001:
0002:
0003:
0004:
0005:
0006:
0007:
0008:
0009:
0010: #define STRICT
0011: #include <stdio.h>
0012: #include <windows.h>
0013: #include <d3d8.h>
0014: #include <d3dx8.h>
0015:
0016: #include "resource.h"
0017: #include "main.h"
0018: #include "draw.h"
0019: #include "font.h"
0020: #include "load.h"
0021: #include "rigidbody.h"
0022:
0023:
0024:
0025:
0026: static LPDIRECT3D8 s_lpD3D = NULL;
0027: static LPDIRECT3DDEVICE8 s_lpD3DDEV = NULL;
0028: static D3DPRESENT_PARAMETERS s_d3dpp;
0029: static bool s_end;
0030: static HINSTANCE shInstApp;
0031: static bool sZoom = false;
0032:
0033: static CMyFont sFont;
0034: extern CMyMesh mesh;
0035: extern DWORD gVs;
0036: extern DWORD gEdge;
0037: extern D3DXVECTOR4 rot;
0038:
0039:
0040: extern D3DXVECTOR4 lrot;
0041: void SetLight(LPDIRECT3DDEVICE8 lpD3DDEV, D3DXVECTOR4 *pRot);
0042:
0043:
0044:
0045:
0046: int PASCAL WinMain(HINSTANCE hInst,HINSTANCE hPrev,char *CmdLine,int CmdShow);
0047: LRESULT CALLBACK MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
0048: LRESULT CALLBACK MyDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp);
0049: HRESULT InitD3D( HWND hWnd );
0050: static void fps_disp();
0051:
0052:
0053:
0054:
0055:
0056: int PASCAL WinMain(HINSTANCE hInst,HINSTANCE hPrev,char *CmdLine,int CmdShow)
0057: {
0058: s_end = 0;
0059: shInstApp = hInst;
0060:
0061: RECT rect;
0062: SetRect(&rect, 0, 0, WIDTH, HEIGHT);
0063: DWORD style = (FULLSCREEN) ? WS_POPUP :(WS_CAPTION|WS_SYSMENU|WS_BORDER|WS_MINIMIZEBOX);
0064: AdjustWindowRect(&rect, style, FALSE);
0065: int width = rect.right - rect.left;
0066: int height = rect.bottom - rect.top;
0067:
0068: WNDCLASS wc;
0069: ZeroMemory(&wc, sizeof(WNDCLASS));
0070: wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
0071: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
0072: wc.hInstance = hInst;
0073: wc.lpfnWndProc = MsgProc;
0074: wc.lpszMenuName = (char*)IDR_MENU;
0075: wc.lpszClassName = CAPTION;
0076: if(RegisterClass(&wc) == 0) return 0;
0077:
0078: HWND hWnd = CreateWindow(CAPTION
0079: ,CAPTION
0080: ,style
0081: ,CW_USEDEFAULT
0082: ,CW_USEDEFAULT
0083: ,width
0084: ,height
0085: ,NULL
0086: ,NULL
0087: ,hInst
0088: ,NULL
0089: );
0090: if(hWnd == NULL) return 0;
0091:
0092:
0093: if(SUCCEEDED(InitD3D(hWnd))){
0094:
0095: sFont.Init(s_lpD3DDEV, 12, 24);
0096:
0097: if(FAILED(InitRender(s_lpD3DDEV))) s_end = true;
0098:
0099: ShowWindow(hWnd, SW_SHOW);
0100: UpdateWindow(hWnd);
0101:
0102:
0103: MSG msg;
0104: while (!s_end)
0105: {
0106: if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
0107:
0108: TranslateMessage(&msg);
0109: DispatchMessage(&msg);
0110: }else{
0111:
0112:
0113: s_lpD3DDEV->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0x50,0x6e,0xbf),1.0f,0);
0114:
0115: s_lpD3DDEV->BeginScene();
0116:
0117: Render(s_lpD3DDEV);
0118: fps_disp();
0119:
0120:
0121: s_lpD3DDEV->EndScene();
0122: if (FAILED(s_lpD3DDEV->Present(NULL,NULL,NULL,NULL)))
0123: s_lpD3DDEV->Reset(&s_d3dpp);
0124: }
0125: }
0126: }
0127:
0128:
0129: CleanRender(s_lpD3DDEV);
0130: RELEASE(s_lpD3DDEV);
0131: RELEASE(s_lpD3D);
0132:
0133: return 0;
0134: }
0135:
0136:
0137:
0138:
0139: HRESULT InitD3D( HWND hWnd )
0140: {
0141:
0142: if (NULL == (s_lpD3D = Direct3DCreate8(D3D_SDK_VERSION))){
0143: MessageBox(NULL,"Direct3D の作成に失敗しました。",CAPTION,MB_OK | MB_ICONSTOP);
0144: return E_FAIL;
0145: }
0146:
0147:
0148: D3DDISPLAYMODE d3ddm;
0149: if( FAILED( s_lpD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) ) return E_FAIL;
0150:
0151:
0152: ZeroMemory(&s_d3dpp, sizeof(D3DPRESENT_PARAMETERS));
0153: s_d3dpp.BackBufferCount = 1;
0154: if (FULLSCREEN){
0155: s_d3dpp.Windowed = FALSE;
0156: s_d3dpp.BackBufferWidth = WIDTH;
0157: s_d3dpp.BackBufferHeight = HEIGHT;
0158: }else{
0159: s_d3dpp.Windowed = TRUE;
0160: s_d3dpp.BackBufferWidth = 0;
0161: s_d3dpp.BackBufferHeight = 0;
0162: }
0163:
0164: s_d3dpp.BackBufferFormat = d3ddm.Format;
0165: s_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
0166: s_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
0167: s_d3dpp.hDeviceWindow = hWnd;
0168:
0169: s_d3dpp.EnableAutoDepthStencil = TRUE;
0170: s_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
0171:
0172: D3DCAPS8 caps;
0173: s_lpD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
0174:
0175: if(caps.VertexShaderVersion < D3DVS_VERSION(1,0)){
0176:
0177: if(FAILED(s_lpD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&s_d3dpp,&s_lpD3DDEV))){
0178: if(FAILED(s_lpD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF,hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE,&s_d3dpp,&s_lpD3DDEV))){
0179: return FALSE;
0180: }
0181: }
0182: }else{
0183:
0184: if (FAILED(s_lpD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING,&s_d3dpp,&s_lpD3DDEV))){
0185:
0186: if (FAILED(s_lpD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&s_d3dpp,&s_lpD3DDEV))){
0187:
0188: if (FAILED(s_lpD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&s_d3dpp,&s_lpD3DDEV))){
0189:
0190: MessageBox(NULL,"Direct3D の初期化に失敗しました。",CAPTION,MB_OK | MB_ICONSTOP);
0191: return E_FAIL;
0192: }
0193: }
0194: }
0195: }
0196:
0197: return S_OK;
0198: }
0199:
0202: LRESULT CALLBACK MsgProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam)
0203: {
0204: static long prevX = 0;
0205: static long prevY = 0;
0206: static int sizeMoving = FALSE;
0207: static wVertexShaderOld = IDM_DIFFUSE;
0208: long x,y,dx,dy;
0209: D3DXMATRIX m;
0210: D3DXVECTOR3 v;
0211:
0212: switch(msg){
0213: break;
0214: case WM_LBUTTONDOWN:
0215: prevX = (lParam << 16) >> 16;
0216: prevY = lParam >> 16;
0217: SetCapture(hWnd);
0218: break;
0219: case WM_LBUTTONUP:
0220: ReleaseCapture();
0221: break;
0222: case WM_MOUSEMOVE:
0223: x = (lParam << 16) >> 16;
0224: y = lParam >> 16;
0225: dx = x - prevX;
0226: dy = y - prevY;
0227: if(wParam & MK_LBUTTON){
0228: if(sZoom){
0229: if(dy+dx != 0){
0230: D3DXVECTOR4 v = view.GetEye();
0231: v.z += 0.005f*v.z*dy;
0232: view.SetEye(v);
0233: }
0234: }else{
0235: bool chg = false;
0236: if(dx != 0){
0237: rot.y -= 0.01f*dx; chg = true;
0238: }
0239: if(dy != 0){
0240: rot.x -= 0.01f*dy; chg = true;
0241: }
0242: }
0243: }else if(wParam & MK_RBUTTON){
0244: if(dx != 0){
0245: lrot.y -= 0.005f*dx;
0246: }
0247: if(dy != 0){
0248: lrot.x -= 0.005f*dy;
0249: }
0250: if(dy != 0 || dx != 0) SetLight(s_lpD3DDEV, &lrot);
0251: }
0252: prevX = x;
0253: prevY = y;
0254: break;
0255: case WM_KEYUP:
0256: switch(wParam){
0257: case VK_SHIFT:
0258: sZoom = false;
0259: break;
0260: }
0261: break;
0262: case WM_KEYDOWN:
0263: switch(wParam){
0264: case VK_ESCAPE:
0265: case VK_F12:
0266:
0267: s_end = true;
0268: return 1;
0269: case VK_SHIFT:
0270: sZoom = true;
0271: break;
0272: default:
0273: MyMsgProc(wParam);
0274: break;
0275: }
0276: break;
0277: case WM_COMMAND:
0278: switch(LOWORD(wParam)){
0279: case FILE_MENU_OPEN:
0280: {
0281: char filename[1024];
0282: OPENFILENAME ofn;
0283: filename[0] = '\0';
0284:
0285: ZeroMemory(&ofn,sizeof(ofn));
0286: ofn.lStructSize = sizeof(ofn);
0287: ofn.hwndOwner = hWnd;
0288: ofn.hInstance = shInstApp;
0289: ofn.lpstrFilter = ".X Files (.x)\0*.x\0";
0290: ofn.lpstrTitle = "Load X-File";
0291: ofn.lpstrFile = filename;
0292: ofn.nMaxFile = 1024;
0293: ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
0294: if(GetOpenFileName(&ofn)){
0295: if(mesh.Load(s_lpD3DDEV, filename)){
0296: InvalidateRect(hWnd,NULL,TRUE);
0297: }
0298: }
0299: }
0300: break;
0301: case FILE_MENU_EXIT:
0302: s_end = true;
0303: return 1;
0304: break;
0305: case FILE_MENU_ABOUT:
0306: DialogBox(shInstApp, MAKEINTRESOURCE(IDD_ABOUT_DIALOG), hWnd, (DLGPROC)MyDlgProc);
0307: break;
0308: case IDM_DIFFUSE:
0309: case IDM_SPECULAR:
0310: case IDM_TEX_SPEC:
0311: case IDM_METAL:
0312: case IDM_HEMI:
0313: case IDM_HEMI_AMB:
0314: case IDM_HEMI_SPEC:
0315: case IDM_SOFT:
0316: gVs = wParam-IDM_DIFFUSE;
0317: CheckMenuItem(GetMenu(hWnd), wVertexShaderOld, MF_UNCHECKED);
0318: CheckMenuItem(GetMenu(hWnd), wParam,MF_CHECKED);
0319: wVertexShaderOld = wParam;
0320: break;
0321: case IDM_EDGE:
0322: gEdge = 1-gEdge;
0323: CheckMenuItem(GetMenu(hWnd), wParam, gEdge?MF_CHECKED:MF_UNCHECKED);
0324: break;
0325: default:
0326: break;
0327: }
0328: break;
0329: case WM_CLOSE:
0330: s_end = true;
0331: return 1;
0332: break;
0333: default:
0334: return DefWindowProc(hWnd,msg,wParam,lParam);
0335: }
0336: return 0L;
0337: }
0338:
0339:
0340:
0341:
0342: static void fps_disp()
0343: {
0344: static DWORD last = timeGetTime();
0345: static DWORD frames = 0;
0346: static char buf[256] = "";
0347: DWORD current;
0348:
0349: current = timeGetTime();
0350: frames++;
0351:
0352: if(500 <= current - last) {
0353: float dt = (float)(current - last) / 1000.0f;
0354: float fps = (float)frames / dt;
0355: last = current;
0356: frames = 0;
0357: sprintf(buf, "%.02f fps", fps);
0358: }
0359: sFont.Print(buf, 0,0);
0360: }
0361:
0362:
0363:
0364:
0365: LRESULT CALLBACK MyDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp)
0366: {
0367: switch (msg) {
0368: case WM_INITDIALOG:
0369: return FALSE;
0370: case WM_COMMAND:
0371: switch (LOWORD(wp)) {
0372: case IDOK:
0373: EndDialog(hDlgWnd, IDOK);
0374: break;
0375: default:
0376: return FALSE;
0377: }
0378: default:
0379: return FALSE;
0380: }
0381: return TRUE;
0382: }
0383: