assimp/tools/assimp_view/MessageProc.cpp

1193 lines
35 KiB
C++

/*
---------------------------------------------------------------------------
Free Asset Import Library (ASSIMP)
---------------------------------------------------------------------------
Copyright (c) 2006-2008, ASSIMP Development Team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the ASSIMP team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the ASSIMP Development Team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "stdafx.h"
#include "assimp_view.h"
namespace AssimpView {
// Static array to keep custom color values
COLORREF g_aclCustomColors[16] = {0};
//-------------------------------------------------------------------------------
// Setup file associations for all formats supported by the library
//
// File associations are registered in HKCU\Software\Classes. They might
// be overwritten by global file associations.
//-------------------------------------------------------------------------------
void MakeFileAssociations()
{
char szTemp2[MAX_PATH];
char szTemp[MAX_PATH + 10];
GetModuleFileName(NULL,szTemp2,MAX_PATH);
sprintf(szTemp,"%s %%1",szTemp2);
HKEY hTemp;
// -------------------------------------------------
// .3ds
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.3ds",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1);
RegCloseKey(hTemp);
// -------------------------------------------------
// .x
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.x",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1);
RegCloseKey(hTemp);
// -------------------------------------------------
// .obj
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.obj",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1);
RegCloseKey(hTemp);
// -------------------------------------------------
// .ms3d
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.ms3d",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1);
RegCloseKey(hTemp);
// -------------------------------------------------
// .md3
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md3",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1);
RegCloseKey(hTemp);
// -------------------------------------------------
// .md2
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md2",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1);
RegCloseKey(hTemp);
// -------------------------------------------------
// .md4/mdr
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md4",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.mdr",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1);
RegCloseKey(hTemp);
// -------------------------------------------------
// .md5
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md5",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1);
RegCloseKey(hTemp);
// -------------------------------------------------
// .mdl
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.mdl",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1);
RegCloseKey(hTemp);
// -------------------------------------------------
// .ply
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.ply",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1);
RegCloseKey(hTemp);
// -------------------------------------------------
// .ase/.ask
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.ase",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.ask",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\ASSIMPVIEW_CLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\ASSIMPVIEW_CLASS\\shell\\open\\command",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)szTemp,(DWORD)strlen(szTemp)+1);
RegCloseKey(hTemp);
CLogDisplay::Instance().AddEntry("[OK] File assocations have been registered",
D3DCOLOR_ARGB(0xFF,0,0xFF,0));
aiString sz;
aiGetExtensionList(&sz);
CLogDisplay::Instance().AddEntry(sz.data,
D3DCOLOR_ARGB(0xFF,0,0xFF,0));
}
//-------------------------------------------------------------------------------
// Recreate all specular materials depending on the current specularity settings
//
// Diffuse-only materials are ignored.
// Must be called after specular highlights have been toggled
//-------------------------------------------------------------------------------
void UpdateSpecularMaterials()
{
if (g_pcAsset && g_pcAsset->pcScene)
{
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
{
if (aiShadingMode_Phong == g_pcAsset->apcMeshes[i]->eShadingMode)
{
DeleteMaterial(g_pcAsset->apcMeshes[i]);
CreateMaterial(g_pcAsset->apcMeshes[i],g_pcAsset->pcScene->mMeshes[i]);
}
}
}
}
//-------------------------------------------------------------------------------
// Handle command line parameters
//
// The function loads an asset specified on the command line as first argument
// Other command line parameters are not handled
//-------------------------------------------------------------------------------
void HandleCommandLine(char* p_szCommand)
{
char* sz = p_szCommand;
//bool bQuak = false;
if (strlen(sz) < 2)return;
if (*sz == '\"')
{
char* sz2 = strrchr(sz,'\"');
if (sz2)*sz2 = 0;
}
strcpy( g_szFileName, sz );
LoadAsset();
}
//-------------------------------------------------------------------------------
// Main message procedure of the application
//
// The function handles all incoming messages for the main window.
// However, if does not directly process input commands.
// NOTE: Due to the impossibility to process WM_CHAR messages in dialogs
// properly the code for all hotkeys has been moved to the WndMain
//-------------------------------------------------------------------------------
INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg,
WPARAM wParam,LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
UNREFERENCED_PARAMETER(wParam);
int xPos,yPos;
int xPos2,yPos2;
int fHalfX;
int fHalfY;
TRACKMOUSEEVENT sEvent;
switch (uMsg)
{
case WM_INITDIALOG:
CheckDlgButton(hwndDlg,IDC_TOGGLEMS,BST_CHECKED);
CheckDlgButton(hwndDlg,IDC_ZOOM,BST_CHECKED);
CheckDlgButton(hwndDlg,IDC_AUTOROTATE,BST_CHECKED);
SetDlgItemText(hwndDlg,IDC_EVERT,"0");
SetDlgItemText(hwndDlg,IDC_EFACE,"0");
SetDlgItemText(hwndDlg,IDC_EMAT,"0");
SetDlgItemText(hwndDlg,IDC_ESHADER,"0");
SetDlgItemText(hwndDlg,IDC_ENODE,"0");
SetDlgItemText(hwndDlg,IDC_ETEX,"0");
// setup the default window title
SetWindowText(hwndDlg,AI_VIEW_CAPTION_BASE);
{
// read some UI properties from the registry and apply them
DWORD dwValue;
DWORD dwTemp = sizeof( DWORD );
HKEY hTemp;
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\ASSIMP\\Viewer",
NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
if(ERROR_SUCCESS != RegQueryValueEx(hTemp,"LastUIState",NULL,NULL,
(BYTE*)&dwValue,&dwTemp))
{
dwValue = 1;
}
if (0 == dwValue)
{
// collapse the viewer
// adjust the size
RECT sRect;
GetWindowRect(hwndDlg,&sRect);
sRect.right -= sRect.left;
sRect.bottom -= sRect.top;
RECT sRect2;
GetWindowRect(GetDlgItem ( hwndDlg, IDC_BLUBB ),&sRect2);
sRect2.left -= sRect.left;
sRect2.top -= sRect.top;
SetWindowPos(hwndDlg,NULL,0,0,sRect.right-188,sRect.bottom,
SWP_NOMOVE | SWP_NOZORDER);
SetWindowText(GetDlgItem(hwndDlg,IDC_BLUBB),">>");
}
else
{
CheckDlgButton(hwndDlg,IDC_BLUBB,BST_CHECKED);
}
RegCloseKey(hTemp);}
return TRUE;
case WM_MOUSEWHEEL:
if (!g_bFPSView)
{
g_sCamera.vPos.z += GET_WHEEL_DELTA_WPARAM(wParam) / 50.0f;
}
else
{
g_sCamera.vPos += (GET_WHEEL_DELTA_WPARAM(wParam) / 50.0f) *
g_sCamera.vLookAt.Normalize();
}
return TRUE;
case WM_MOUSELEAVE:
g_bMousePressed = false;
g_bMousePressedR = false;
g_bMousePressedM = false;
g_bMousePressedBoth = false;
return TRUE;
case WM_LBUTTONDBLCLK:
CheckDlgButton(hwndDlg,IDC_AUTOROTATE,
IsDlgButtonChecked(hwndDlg,IDC_AUTOROTATE) == BST_CHECKED
? BST_UNCHECKED : BST_CHECKED);
g_sOptions.bRotate = !g_sOptions.bRotate;
return TRUE;
case WM_CLOSE:
PostQuitMessage(0);
DestroyWindow(hwndDlg);
return TRUE;
case WM_LBUTTONDOWN:
g_bMousePressed = true;
// register a mouse track handler to be sure we'll know
// when the mouse leaves the display view again
sEvent.cbSize = sizeof(TRACKMOUSEEVENT);
sEvent.dwFlags = TME_LEAVE;
sEvent.hwndTrack = g_hDlg;
sEvent.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&sEvent);
if (g_bMousePressedR)
{
g_bMousePressed = false;
g_bMousePressedR = false;
g_bMousePressedBoth = true;
return TRUE;
}
// need to determine the position of the mouse and the
// distance from the center
xPos = (int)(short)LOWORD(lParam);
yPos = (int)(short)HIWORD(lParam);
xPos -= 10;
yPos -= 10;
xPos2 = xPos-3;
yPos2 = yPos-5;
RECT sRect;
GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect);
sRect.right -= sRect.left;
sRect.bottom -= sRect.top;
// if the mouse klick was inside the viewer panel
// give the focus to it
if (xPos > 0 && xPos < sRect.right && yPos > 0 && yPos < sRect.bottom)
{
SetFocus(GetDlgItem(g_hDlg,IDC_RT));
}
// g_bInvert stores whether the mouse has started on the negative
// x or on the positive x axis of the imaginary coordinate system
// with origin p at the center of the HUD texture
xPos -= sRect.right/2;
yPos -= sRect.bottom/2;
if (xPos > 0)g_bInvert = true;
else g_bInvert = false;
D3DSURFACE_DESC sDesc;
g_pcTexture->GetLevelDesc(0,&sDesc);
fHalfX = (int)(((float)sRect.right-(float)sDesc.Width) / 2.0f);
fHalfY = (int)(((float)sRect.bottom-(float)sDesc.Height) / 2.0f);
// Determine the input operation to perform for this position
g_eClick = EClickPos_Outside;
if (xPos2 >= fHalfX && xPos2 < fHalfX + (int)sDesc.Width &&
yPos2 >= fHalfY && yPos2 < fHalfY + (int)sDesc.Height &&
NULL != g_szImageMask)
{
// inside the texture. Lookup the grayscale value from it
xPos2 -= fHalfX;
yPos2 -= fHalfY;
unsigned char chValue = g_szImageMask[xPos2 + yPos2 * sDesc.Width];
if (chValue > 0xFF-20)
{
g_eClick = EClickPos_Circle;
}
else if (chValue < 0xFF-20 && chValue > 185)
{
g_eClick = EClickPos_CircleHor;
}
else if (chValue > 0x10 && chValue < 185)
{
g_eClick = EClickPos_CircleVert;
}
}
return TRUE;
case WM_RBUTTONDOWN:
g_bMousePressedR = true;
sEvent.cbSize = sizeof(TRACKMOUSEEVENT);
sEvent.dwFlags = TME_LEAVE;
sEvent.hwndTrack = g_hDlg;
sEvent.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&sEvent);
if (g_bMousePressed)
{
g_bMousePressedR = false;
g_bMousePressed = false;
g_bMousePressedBoth = true;
}
return TRUE;
case WM_MBUTTONDOWN:
g_bMousePressedM = true;
sEvent.cbSize = sizeof(TRACKMOUSEEVENT);
sEvent.dwFlags = TME_LEAVE;
sEvent.hwndTrack = g_hDlg;
sEvent.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&sEvent);
return TRUE;
case WM_LBUTTONUP:
g_bMousePressed = false;
g_bMousePressedBoth = false;
return TRUE;
case WM_RBUTTONUP:
g_bMousePressedR = false;
g_bMousePressedBoth = false;
return TRUE;
case WM_MBUTTONUP:
g_bMousePressedM = false;
return TRUE;
case WM_COMMAND:
if (ID_VIEWER_QUIT == LOWORD(wParam))
{
PostQuitMessage(0);
DestroyWindow(hwndDlg);
}
else if (ID_VIEWER_RESETVIEW == LOWORD(wParam))
{
g_sCamera.vPos = aiVector3D(0.0f,0.0f,-10.0f);
g_sCamera.vLookAt = aiVector3D(0.0f,0.0f,1.0f);
g_sCamera.vUp = aiVector3D(0.0f,1.0f,0.0f);
g_sCamera.vRight = aiVector3D(0.0f,1.0f,0.0f);
g_mWorldRotate = aiMatrix4x4();
g_mWorld = aiMatrix4x4();
// don't forget to reset the st
CBackgroundPainter::Instance().ResetSB();
}
else if (ID__HELP == LOWORD(wParam))
{
DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_AVHELP),
hwndDlg,&HelpDialogProc);
}
else if (ID__ABOUT == LOWORD(wParam))
{
DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_ABOUTBOX),
hwndDlg,&AboutMessageProc);
}
else if (ID_TOOLS_LOGWINDOW == LOWORD(wParam))
{
CLogWindow::Instance().Show();
}
else if (ID_VIEWER_H == LOWORD(wParam))
{
MakeFileAssociations();
}
else if (ID_BACKGROUND_CLEAR == LOWORD(wParam))
{
D3DCOLOR clrColor = D3DCOLOR_ARGB(0xFF,100,100,100);
CBackgroundPainter::Instance().SetColor(clrColor);
HKEY hTemp;
RegCreateKeyEx(HKEY_CURRENT_USER,
"Software\\ASSIMP\\Viewer",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueExA(hTemp,"LastSkyBoxSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
RegSetValueExA(hTemp,"LastTextureSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
RegSetValueExA(hTemp,"Color",0,REG_DWORD,(const BYTE*)&clrColor,4);
RegCloseKey(hTemp);
}
else if (ID_BACKGROUND_SETCOLOR == LOWORD(wParam))
{
HKEY hTemp;
RegCreateKeyEx(HKEY_CURRENT_USER,
"Software\\ASSIMP\\Viewer",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueExA(hTemp,"LastSkyBoxSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
RegSetValueExA(hTemp,"LastTextureSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
CHOOSECOLOR clr;
clr.lStructSize = sizeof(CHOOSECOLOR);
clr.hwndOwner = hwndDlg;
clr.Flags = CC_RGBINIT | CC_FULLOPEN;
clr.rgbResult = RGB(100,100,100);
clr.lpCustColors = g_aclCustomColors;
clr.lpfnHook = NULL;
clr.lpTemplateName = NULL;
clr.lCustData = NULL;
ChooseColor(&clr);
D3DCOLOR clrColor = D3DCOLOR_ARGB(0xFF,
GetRValue(clr.rgbResult),
GetGValue(clr.rgbResult),
GetBValue(clr.rgbResult));
CBackgroundPainter::Instance().SetColor(clrColor);
RegSetValueExA(hTemp,"Color",0,REG_DWORD,(const BYTE*)&clrColor,4);
RegCloseKey(hTemp);
}
else if (ID_BACKGROUND_LOADTEXTURE == LOWORD(wParam))
{
char szFileName[MAX_PATH];
DWORD dwTemp = MAX_PATH;
HKEY hTemp;
RegCreateKeyEx(HKEY_CURRENT_USER,
"Software\\ASSIMP\\Viewer",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
if(ERROR_SUCCESS != RegQueryValueEx(hTemp,"TextureSrc",NULL,NULL,
(BYTE*)szFileName,&dwTemp))
{
// Key was not found. Use C:
strcpy(szFileName,"");
}
else
{
// need to remove the file name
char* sz = strrchr(szFileName,'\\');
if (!sz)sz = strrchr(szFileName,'/');
if (!sz)*sz = 0;
}
OPENFILENAME sFilename1 = {
sizeof(OPENFILENAME),
g_hDlg,GetModuleHandle(NULL),
"Textures\0*.png;*.dds;*.tga;*.bmp;*.tif;*.ppm;*.ppx;*.jpg;*.jpeg;*.exr\0*.*\0", NULL, 0, 1,
szFileName, MAX_PATH, NULL, 0, NULL,
"Open texture as background",
OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
0, 1, ".jpg", 0, NULL, NULL
};
if(GetOpenFileName(&sFilename1) == 0) return TRUE;
// Now store the file in the registry
RegSetValueExA(hTemp,"TextureSrc",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
RegSetValueExA(hTemp,"LastTextureSrc",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
RegSetValueExA(hTemp,"LastSkyBoxSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
RegCloseKey(hTemp);
CBackgroundPainter::Instance().SetTextureBG(szFileName);
}
else if (ID_BACKGROUND_LOADSKYBOX == LOWORD(wParam))
{
char szFileName[MAX_PATH];
DWORD dwTemp = MAX_PATH;
HKEY hTemp;
RegCreateKeyEx(HKEY_CURRENT_USER,
"Software\\ASSIMP\\Viewer",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
if(ERROR_SUCCESS != RegQueryValueEx(hTemp,"SkyBoxSrc",NULL,NULL,
(BYTE*)szFileName,&dwTemp))
{
// Key was not found. Use C:
strcpy(szFileName,"");
}
else
{
// need to remove the file name
char* sz = strrchr(szFileName,'\\');
if (!sz)sz = strrchr(szFileName,'/');
if (!sz)*sz = 0;
}
OPENFILENAME sFilename1 = {
sizeof(OPENFILENAME),
g_hDlg,GetModuleHandle(NULL),
"Skyboxes\0*.dds\0*.*\0", NULL, 0, 1,
szFileName, MAX_PATH, NULL, 0, NULL,
"Open skybox as background",
OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
0, 1, ".dds", 0, NULL, NULL
};
if(GetOpenFileName(&sFilename1) == 0) return TRUE;
// Now store the file in the registry
RegSetValueExA(hTemp,"SkyBoxSrc",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
RegSetValueExA(hTemp,"LastSkyBoxSrc",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
RegSetValueExA(hTemp,"LastTextureSrc",0,REG_SZ,(const BYTE*)"",MAX_PATH);
RegCloseKey(hTemp);
CBackgroundPainter::Instance().SetCubeMapBG(szFileName);
}
else if (ID_VIEWER_SAVESCREENSHOTTOFILE == LOWORD(wParam))
{
char szFileName[MAX_PATH];
DWORD dwTemp = MAX_PATH;
HKEY hTemp;
RegCreateKeyEx(HKEY_CURRENT_USER,
"Software\\ASSIMP\\Viewer",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
if(ERROR_SUCCESS != RegQueryValueEx(hTemp,"ScreenShot",NULL,NULL,
(BYTE*)szFileName,&dwTemp))
{
// Key was not found. Use C:
strcpy(szFileName,"");
}
else
{
// need to remove the file name
char* sz = strrchr(szFileName,'\\');
if (!sz)sz = strrchr(szFileName,'/');
if (!sz)*sz = 0;
}
OPENFILENAME sFilename1 = {
sizeof(OPENFILENAME),
g_hDlg,GetModuleHandle(NULL),
"PNG Images\0*.png", NULL, 0, 1,
szFileName, MAX_PATH, NULL, 0, NULL,
"Save Screenshot to file",
OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
0, 1, ".png", 0, NULL, NULL
};
if(GetSaveFileName(&sFilename1) == 0) return TRUE;
// Now store the file in the registry
RegSetValueExA(hTemp,"ScreenShot",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
RegCloseKey(hTemp);
IDirect3DSurface9* pi;
g_piDevice->GetRenderTarget(0,&pi);
D3DXSaveSurfaceToFile(szFileName,D3DXIFF_PNG,
pi,NULL,NULL);
pi->Release();
}
else if (ID_VIEWER_OPEN == LOWORD(wParam))
{
char szFileName[MAX_PATH];
DWORD dwTemp = MAX_PATH;
HKEY hTemp;
RegCreateKeyEx(HKEY_CURRENT_USER,
"Software\\ASSIMP\\Viewer",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
if(ERROR_SUCCESS != RegQueryValueEx(hTemp,"CurrentApp",NULL,NULL,
(BYTE*)szFileName,&dwTemp))
{
// Key was not found. Use C:
strcpy(szFileName,"");
}
else
{
// need to remove the file name
char* sz = strrchr(szFileName,'\\');
if (!sz)sz = strrchr(szFileName,'/');
if (!sz)*sz = 0;
}
// get a list of all file extensions supported by ASSIMP
aiString sz;
aiGetExtensionList(&sz);
char szList[MAXLEN + 100];
strcpy(szList,"ASSIMP assets");
char* szCur = szList + 14;
strcpy(szCur,sz.data);
szCur += sz.length+1;
strcpy(szCur,"All files");
szCur += 10;
strcpy(szCur,"*.*");
szCur[4] = 0;
OPENFILENAME sFilename1 = {
sizeof(OPENFILENAME),
g_hDlg,GetModuleHandle(NULL), szList, NULL, 0, 1,
szFileName, MAX_PATH, NULL, 0, NULL,
"Import Asset into ASSIMP",
OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
0, 1, ".x", 0, NULL, NULL
};
if(GetOpenFileName(&sFilename1) == 0) return TRUE;
// Now store the file in the registry
RegSetValueExA(hTemp,"CurrentApp",0,REG_SZ,(const BYTE*)szFileName,MAX_PATH);
RegCloseKey(hTemp);
if (0 != strcmp(g_szFileName,szFileName))
{
strcpy(g_szFileName, szFileName);
DeleteAssetData();
DeleteAsset();
LoadAsset();
}
}
else if (ID_VIEWER_CLOSEASSET == LOWORD(wParam))
{
DeleteAssetData();
DeleteAsset();
}
else if (BN_CLICKED == HIWORD(wParam))
{
if (IDC_TOGGLEMS == LOWORD(wParam))
{
g_sOptions.bMultiSample = !g_sOptions.bMultiSample;
DeleteAssetData();
ShutdownDevice();
if (0 == CreateDevice())
{
CLogDisplay::Instance().AddEntry(
"[ERROR] Failed to toggle MultiSampling mode");
g_sOptions.bMultiSample = !g_sOptions.bMultiSample;
CreateDevice();
}
CreateAssetData();
if (g_sOptions.bMultiSample)
{
CLogDisplay::Instance().AddEntry(
"[OK] Changed MultiSampling mode to the maximum value for this device");
}
else
{
CLogDisplay::Instance().AddEntry(
"[OK] MultiSampling has been disabled");
}
}
else if (IDC_TOGGLEMAT == LOWORD(wParam))
{
g_sOptions.bRenderMats = !g_sOptions.bRenderMats;
}
else if (IDC_NOSPECULAR == LOWORD(wParam))
{
g_sOptions.bNoSpecular = !g_sOptions.bNoSpecular;
UpdateSpecularMaterials();
}
else if (IDC_ZOOM == LOWORD(wParam))
{
g_bFPSView = !g_bFPSView;
SetupFPSView();
}
else if (IDC_BLUBB == LOWORD(wParam))
{
// adjust the size
RECT sRect;
GetWindowRect(hwndDlg,&sRect);
sRect.right -= sRect.left;
sRect.bottom -= sRect.top;
RECT sRect2;
GetWindowRect(GetDlgItem ( hwndDlg, IDC_BLUBB ),&sRect2);
sRect2.left -= sRect.left;
sRect2.top -= sRect.top;
HKEY hTemp;
DWORD dwValue;
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\ASSIMP\\Viewer",
NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
if (BST_UNCHECKED == IsDlgButtonChecked(hwndDlg,IDC_BLUBB))
{
SetWindowPos(hwndDlg,NULL,0,0,sRect.right-188,sRect.bottom,
SWP_NOMOVE | SWP_NOZORDER);
dwValue = 0;
SetWindowText(GetDlgItem(hwndDlg,IDC_BLUBB),">>");
RegSetValueExA(hTemp,"LastUIState",0,REG_DWORD,(const BYTE*)&dwValue,4);
}
else
{
SetWindowPos(hwndDlg,NULL,0,0,sRect.right+188,sRect.bottom,
SWP_NOMOVE | SWP_NOZORDER);
dwValue = 1;
SetWindowText(GetDlgItem(hwndDlg,IDC_BLUBB),"<<");
RegSetValueExA(hTemp,"LastUIState",0,REG_DWORD,(const BYTE*)&dwValue,4);
}
RegCloseKey(hTemp);
}
else if (IDC_TOGGLENORMALS == LOWORD(wParam))
{
g_sOptions.bRenderNormals = !g_sOptions.bRenderNormals;
}
else if (IDC_LOWQUALITY == LOWORD(wParam))
{
g_sOptions.bLowQuality = !g_sOptions.bLowQuality;
}
else if (IDC_3LIGHTS == LOWORD(wParam))
{
g_sOptions.b3Lights = !g_sOptions.b3Lights;
}
else if (IDC_LIGHTROTATE == LOWORD(wParam))
{
g_sOptions.bLightRotate = !g_sOptions.bLightRotate;
}
else if (IDC_AUTOROTATE == LOWORD(wParam))
{
g_sOptions.bRotate = !g_sOptions.bRotate;
}
else if (IDC_TOGGLEWIRE == LOWORD(wParam))
{
if (g_sOptions.eDrawMode == RenderOptions::WIREFRAME)
g_sOptions.eDrawMode = RenderOptions::NORMAL;
else g_sOptions.eDrawMode = RenderOptions::WIREFRAME;
}
}
return TRUE;
};
return FALSE;
}
//-------------------------------------------------------------------------------
// Message prcoedure for the progress dialog
//-------------------------------------------------------------------------------
INT_PTR CALLBACK ProgressMessageProc(HWND hwndDlg,UINT uMsg,
WPARAM wParam,LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (uMsg)
{
case WM_INITDIALOG:
SendDlgItemMessage(hwndDlg,IDC_PROGRESS,PBM_SETRANGE,0,
MAKELPARAM(0,500));
SetTimer(hwndDlg,0,40,NULL);
return TRUE;
case WM_CLOSE:
EndDialog(hwndDlg,0);
return TRUE;
case WM_COMMAND:
if (IDOK == LOWORD(wParam))
{
#if 0
g_bLoadingCanceled = true;
TerminateThread(g_hThreadHandle,5);
g_pcAsset = NULL;
EndDialog(hwndDlg,0);
#endif
// PROBLEM: If we terminate the loader thread, ASSIMP's state
// is undefined. Any further attempts to load assets will
// fail.
exit(5);
// return TRUE;
}
case WM_TIMER:
UINT iPos = (UINT)SendDlgItemMessage(hwndDlg,IDC_PROGRESS,PBM_GETPOS,0,0);
iPos += 10;
if (iPos > 490)iPos = 0;
SendDlgItemMessage(hwndDlg,IDC_PROGRESS,PBM_SETPOS,iPos,0);
if (g_bLoadingFinished)
{
EndDialog(hwndDlg,0);
return TRUE;
}
return TRUE;
}
return FALSE;
}
//-------------------------------------------------------------------------------
// Message procedure for the about dialog
//-------------------------------------------------------------------------------
INT_PTR CALLBACK AboutMessageProc(HWND hwndDlg,UINT uMsg,
WPARAM wParam,LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (uMsg)
{
case WM_CLOSE:
EndDialog(hwndDlg,0);
return TRUE;
case WM_COMMAND:
if (IDOK == LOWORD(wParam))
{
EndDialog(hwndDlg,0);
return TRUE;
}
}
return FALSE;
}
};
using namespace AssimpView;
//-------------------------------------------------------------------------------
// Entry point to the application
//-------------------------------------------------------------------------------
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// needed for the RichEdit control in the about/help dialog
LoadLibrary( "riched20.dll" );
InitCommonControls();
g_hInstance = hInstance;
if (0 == InitD3D())
{
MessageBox(NULL,"Failed to initialize Direct3D 9",
"ASSIMP ModelViewer",MB_OK);
return -6;
}
HWND hDlg = CreateDialog(hInstance,MAKEINTRESOURCE(IDD_DIALOGMAIN),
NULL,&MessageProc);
if (NULL == hDlg)
{
MessageBox(NULL,"Failed to create dialog from resource",
"ASSIMP ModelViewer",MB_OK);
return -5;
}
g_hDlg = hDlg;
MSG uMsg;
memset(&uMsg,0,sizeof( MSG));
ShowWindow( hDlg, nCmdShow );
UpdateWindow( hDlg );
if (0 == CreateDevice(true,false,true))
{
MessageBox(NULL,"Failed to initialize Direct3D 9 (2)",
"ASSIMP ModelViewer",MB_OK);
return -4;
}
CLogDisplay::Instance().AddEntry("[OK] The viewer has been initialized successfully");
// create the log window
CLogWindow::Instance().Init();
// set the focus to the main window
SetFocus(g_hDlg);
// recover background skyboxes/textures from the last session
HKEY hTemp;
union
{
char szFileName[MAX_PATH];
D3DCOLOR clrColor;
};
DWORD dwTemp = MAX_PATH;
RegCreateKeyEx(HKEY_CURRENT_USER,
"Software\\ASSIMP\\Viewer",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
if(ERROR_SUCCESS == RegQueryValueEx(hTemp,"LastSkyBoxSrc",NULL,NULL,
(BYTE*)szFileName,&dwTemp) && '\0' != szFileName[0])
{
CBackgroundPainter::Instance().SetCubeMapBG(szFileName);
}
else if(ERROR_SUCCESS == RegQueryValueEx(hTemp,"LastTextureSrc",NULL,NULL,
(BYTE*)szFileName,&dwTemp) && '\0' != szFileName[0])
{
CBackgroundPainter::Instance().SetTextureBG(szFileName);
}
else if(ERROR_SUCCESS == RegQueryValueEx(hTemp,"Color",NULL,NULL,
(BYTE*)&clrColor,&dwTemp))
{
CBackgroundPainter::Instance().SetColor(clrColor);
}
RegCloseKey(hTemp);
// now handle command line arguments
HandleCommandLine(lpCmdLine);
double adLast[30];
for (int i = 0; i < 30;++i)adLast[i] = 0.0f;
int iCurrent = 0;
double g_dCurTime = 0;
double g_dLastTime = 0;
while( uMsg.message != WM_QUIT )
{
if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &uMsg );
DispatchMessage( &uMsg );
if (WM_CHAR == uMsg.message)
{
switch ((char)uMsg.wParam)
{
case 'M':
case 'm':
CheckDlgButton(g_hDlg,IDC_TOGGLEMS,
IsDlgButtonChecked(g_hDlg,IDC_TOGGLEMS) == BST_CHECKED
? BST_UNCHECKED : BST_CHECKED);
g_sOptions.bMultiSample = !g_sOptions.bMultiSample;
DeleteAssetData();
ShutdownDevice();
if (0 == CreateDevice())
{
CLogDisplay::Instance().AddEntry(
"[ERROR] Failed to toggle MultiSampling mode");
g_sOptions.bMultiSample = !g_sOptions.bMultiSample;
CreateDevice();
}
CreateAssetData();
if (g_sOptions.bMultiSample)
{
CLogDisplay::Instance().AddEntry(
"[OK] Changed MultiSampling mode to the maximum value for this device");
}
else
{
CLogDisplay::Instance().AddEntry(
"[OK] MultiSampling has been disabled");
}
break;
case 'L':
case 'l':
CheckDlgButton(g_hDlg,IDC_3LIGHTS,
IsDlgButtonChecked(g_hDlg,IDC_3LIGHTS) == BST_CHECKED
? BST_UNCHECKED : BST_CHECKED);
g_sOptions.b3Lights = !g_sOptions.b3Lights;
break;
case 'P':
case 'p':
CheckDlgButton(g_hDlg,IDC_LOWQUALITY,
IsDlgButtonChecked(g_hDlg,IDC_LOWQUALITY) == BST_CHECKED
? BST_UNCHECKED : BST_CHECKED);
g_sOptions.bLowQuality = !g_sOptions.bLowQuality;
break;
case 'D':
case 'd':
CheckDlgButton(g_hDlg,IDC_TOGGLEMAT,
IsDlgButtonChecked(g_hDlg,IDC_TOGGLEMAT) == BST_CHECKED
? BST_UNCHECKED : BST_CHECKED);
g_sOptions.bRenderMats = !g_sOptions.bRenderMats;
break;
case 'N':
case 'n':
CheckDlgButton(g_hDlg,IDC_TOGGLENORMALS,
IsDlgButtonChecked(g_hDlg,IDC_TOGGLENORMALS) == BST_CHECKED
? BST_UNCHECKED : BST_CHECKED);
g_sOptions.bRenderNormals = !g_sOptions.bRenderNormals;
break;
case 'S':
case 's':
CheckDlgButton(g_hDlg,IDC_NOSPECULAR,
IsDlgButtonChecked(g_hDlg,IDC_NOSPECULAR) == BST_CHECKED
? BST_UNCHECKED : BST_CHECKED);
g_sOptions.bNoSpecular = !g_sOptions.bNoSpecular;
UpdateSpecularMaterials();
break;
case 'A':
case 'a':
CheckDlgButton(g_hDlg,IDC_AUTOROTATE,
IsDlgButtonChecked(g_hDlg,IDC_AUTOROTATE) == BST_CHECKED
? BST_UNCHECKED : BST_CHECKED);
g_sOptions.bRotate = !g_sOptions.bRotate;
break;
case 'R':
case 'r':
CheckDlgButton(g_hDlg,IDC_LIGHTROTATE,
IsDlgButtonChecked(g_hDlg,IDC_LIGHTROTATE) == BST_CHECKED
? BST_UNCHECKED : BST_CHECKED);
g_sOptions.bLightRotate = !g_sOptions.bLightRotate;
break;
case 'Z':
case 'z':
CheckDlgButton(g_hDlg,IDC_ZOOM,
IsDlgButtonChecked(g_hDlg,IDC_ZOOM) == BST_CHECKED
? BST_UNCHECKED : BST_CHECKED);
g_bFPSView = !g_bFPSView;
SetupFPSView();
break;
case 'W':
case 'w':
CheckDlgButton(g_hDlg,IDC_TOGGLEWIRE,
IsDlgButtonChecked(g_hDlg,IDC_TOGGLEWIRE) == BST_CHECKED
? BST_UNCHECKED : BST_CHECKED);
if (g_sOptions.eDrawMode == RenderOptions::NORMAL)
g_sOptions.eDrawMode = RenderOptions::WIREFRAME;
else g_sOptions.eDrawMode = RenderOptions::NORMAL;
break;
}
}
}
// render the scene
Render();
g_dCurTime = timeGetTime();
g_fElpasedTime = (float)((g_dCurTime - g_dLastTime) * 0.001);
g_dLastTime = g_dCurTime;
adLast[iCurrent++] = 1.0f / g_fElpasedTime;
double dFPS = 0.0;
for (int i = 0;i < 30;++i)
dFPS += adLast[i];
dFPS /= 30.0;
if (30 == iCurrent)
{
iCurrent = 0;
if (dFPS != g_fFPS)
{
g_fFPS = dFPS;
char szOut[256];
sprintf(szOut,"%i",(int)floorf((float)dFPS+0.5f));
SetDlgItemText(g_hDlg,IDC_EFPS,szOut);
}
}
}
DeleteAsset();
ShutdownDevice();
ShutdownD3D();
return 0;
}