assimp/tools/assimp_view/MessageProc.cpp

1121 lines
34 KiB
C++

//-------------------------------------------------------------------------------
/**
* This program is distributed under the terms of the GNU Lesser General
* Public License (LGPL).
*
* ASSIMP Viewer Utility
*
*/
//-------------------------------------------------------------------------------
#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()
{
/*
; .wscript
root: HKCR; Flags: deletekey; Subkey: ".uscript"; ValueType: string; ValueData: "UE_WSCRIPT_CLASS"; Components: rt
root: HKCR; Flags: deletekey; Subkey: "UE_WSCRIPT_CLASS"; ValueName:; ValueType: string; ValueData: "UtopicEngine Console Script"; Components: rt
root: HKCR; Flags: deletekey; Subkey: "UE_WSCRIPT_CLASS\shell\open\command"; ValueName:; ValueType: string; ValueData: "notepad.exe %1"; Components: rt
*/
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*)"AV3DSCLASS",(DWORD)strlen("AV3DSCLASS")+1);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AV3DSCLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AV3DSCLASS\\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);
// -------------------------------------------------
// .x
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.x",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVXCLASS",(DWORD)strlen("AVXCLASS")+1);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVXCLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVXCLASS\\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);
// -------------------------------------------------
// .obj
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.obj",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVOBJCLASS",(DWORD)strlen("AVOBJCLASS")+1);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVOBJCLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVOBJCLASS\\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);
// -------------------------------------------------
// .ms3d
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.ms3d",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVMS3DCLASS",(DWORD)strlen("AVMS3DCLASS")+1);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMS3DCLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMS3DCLASS\\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);
// -------------------------------------------------
// .md3
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md3",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVMD3CLASS",(DWORD)strlen("AVMD3CLASS")+1);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD3CLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD3CLASS\\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);
// -------------------------------------------------
// .md2
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md2",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVMD2CLASS",(DWORD)strlen("AVMD2CLASS")+1);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD3CLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD2CLASS\\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);
// -------------------------------------------------
// .md4
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md4",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVMD4CLASS",(DWORD)strlen("AVMD4CLASS")+1);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD4CLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD4CLASS\\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);
// -------------------------------------------------
// .md5
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md5",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVMD5CLASS",(DWORD)strlen("AVMD5CLASS")+1);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD5CLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVMD5CLASS\\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);
// -------------------------------------------------
// .ply
// -------------------------------------------------
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.ply",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegSetValueEx(hTemp,"",0,REG_SZ,(const BYTE*)"AVPLYCLASS",(DWORD)strlen("AVPLYCLASS")+1);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVPLYCLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &hTemp,NULL);
RegCloseKey(hTemp);
RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\AVPLYCLASS\\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));
}
//-------------------------------------------------------------------------------
// 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");
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;
}
}
// OLD version of this code. Not using a texture lookup to
// determine the exact position, but using maths and the fact
// that we have a circle f(x) = m +rx ;-)
#if 0
g_eClick = EClickPos_Circle;
if (yPos < 10 && yPos > -10)
{
if ((xPos2 > fHalfX-5 && xPos2 < fHalfX+15) ||
(xPos2 > fHalfX+(int)sDesc.Width-10 && xPos2 < fHalfX+(int)sDesc.Width+10))
{
g_eClick = EClickPos_CircleHor;
}
}
else if (xPos < 10 && xPos > -10)
{
if ((yPos2 > fHalfY-5 && yPos2 < fHalfY+15) ||
(yPos2 > fHalfY+(int)sDesc.Height-10 && yPos2 < fHalfY+(int)sDesc.Height+10))
{
g_eClick = EClickPos_CircleVert;
}
}
else if (sqrtf((float)(xPos * xPos + yPos * yPos)) > (float)(sDesc.Width/2))
{
g_eClick = EClickPos_Outside;
}
#endif
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_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;
}
OPENFILENAME sFilename1 = {
sizeof(OPENFILENAME),
g_hDlg,GetModuleHandle(NULL),
"ASSIMP assets\0*.x;*.obj;*.ms3d;*.3ds;*.md3;*.md1;*.md2;*.md4;*.md5;*.ply\0All files\0*.*", 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_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");
// 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;
}