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