DragonNest/Client/EtPackingShader/EtPackingShaderDlg.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

438 lines
12 KiB
C++

// EtPackingShaderDlg.cpp : 구현 파일
//
#include "stdafx.h"
#include "EtPackingShader.h"
#include "EtPackingShaderDlg.h"
#include "EtPackingShaderUtility.h"
#define REG_SUBKEY "SOFTWARE\\EyedentityGames\\EtPackingShader"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 응용 프로그램 정보에 사용되는 CAboutDlg 대화 상자입니다.
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// 대화 상자 데이터입니다.
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.
// 구현입니다.
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CEtPackingShaderDlg 대화 상자
CEtPackingShaderDlg::CEtPackingShaderDlg(CWnd* pParent /*=NULL*/)
: CDialog(CEtPackingShaderDlg::IDD, pParent)
, m_szCurrentDefine(_T(""))
, m_szProgress(_T(""))
, m_szShaderFolder(_T(""))
, m_szOutputFolder(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_nPrevComboSel = 0;
}
void CEtPackingShaderDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_szCurrentDefine);
DDX_Text(pDX, IDC_EDIT2, m_szProgress);
DDX_Control(pDX, IDC_COMBO2, m_ComboBox);
DDX_Text(pDX, IDC_EDIT3, m_szShaderFolder);
DDX_Control(pDX, IDC_EDIT2, m_progressEdit);
DDX_Text(pDX, IDC_EDIT4, m_szOutputFolder);
}
BEGIN_MESSAGE_MAP(CEtPackingShaderDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON1, &CEtPackingShaderDlg::OnBnClickedButtonCompile)
ON_CBN_SELCHANGE(IDC_COMBO2, &CEtPackingShaderDlg::OnCbnSelchangeCombo)
ON_BN_CLICKED(IDC_BUTTON2, &CEtPackingShaderDlg::OnBnClickedButtonFolder)
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_BUTTON3, &CEtPackingShaderDlg::OnBnClickedButtonOutput)
END_MESSAGE_MAP()
// CEtPackingShaderDlg 메시지 처리기
BOOL CEtPackingShaderDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 시스템 메뉴에 "정보..." 메뉴 항목을 추가합니다.
// IDM_ABOUTBOX는 시스템 명령 범위에 있어야 합니다.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 이 대화 상자의 아이콘을 설정합니다. 응용 프로그램의 주 창이 대화 상자가 아닐 경우에는
// 프레임워크가 이 작업을 자동으로 수행합니다.
SetIcon(m_hIcon, TRUE); // 큰 아이콘을 설정합니다.
SetIcon(m_hIcon, FALSE); // 작은 아이콘을 설정합니다.
// TODO: 여기에 추가 초기화 작업을 추가합니다.
char szStrFolder[2048] = { 0, };
char szStrOutput[2048] = { 0, };
char szStrDefine1[2048] = {0,};
char szStrDefine2[2048] = {0,};
char szStrDefine3[2048] = {0,};
GetRegistryString( HKEY_CURRENT_USER, REG_SUBKEY, "ShaderFolder", szStrFolder, 2048 );
if( strlen(szStrFolder) == 0 )
m_szShaderFolder = "\\\\eye-ad\\ToolData\\SharedEffect";
else m_szShaderFolder = szStrFolder;
GetRegistryString( HKEY_CURRENT_USER, REG_SUBKEY, "OutputFolder", szStrOutput, 2048 );
if( strlen(szStrOutput) == 0 )
m_szOutputFolder = "\\\\eye-ad\\ToolData\\Resource\\SharedEffect";
else m_szOutputFolder = szStrOutput;
GetModuleFileName(GetModuleHandle(0), m_szFileName, MAX_PATH );
char *ps = strrchr(m_szFileName, '\\');
if( ps ) {
strcpy(ps, "\\shader.info");
}
FILE *fp = fopen(m_szFileName, "rt");
if( fp == NULL ) {
m_szDefineList[0] = "ETERNITY_ENGINE Eternity\r\nUSE_TERRAIN_LIGHTMAP 1\r\nDEPTH_SHADOWMAP 1\r\nBAKE_DEPTHMAP 1\r\nBAKE_VELOCITY 0\r\n";
m_szDefineList[1] = "ETERNITY_ENGINE Eternity\r\nUSE_TERRAIN_LIGHTMAP 1\r\nDEPTH_SHADOWMAP 1\r\nBAKE_DEPTHMAP 1\r\nBAKE_VELOCITY 0\r\n";
m_szDefineList[2] = "ETERNITY_ENGINE Eternity\r\nUSE_TERRAIN_LIGHTMAP 1\r\nDEPTH_SHADOWMAP 1\r\nBAKE_DEPTHMAP 1\r\nBAKE_VELOCITY 0\r\n";
}
else {
char buffer[255];
int nIndex = -1;
for( ;; ) {
fgets(buffer, 255, fp);
if( feof(fp) || buffer[0] == '\0' )break;
if( buffer[0] == '[' ) {
if( strcmp(buffer, "[DefineHigh]\n") == 0 ) {
nIndex = 0;
}
if( strcmp(buffer, "[DefineNormal]\n") == 0 ) {
nIndex = 1;
}
if( strcmp(buffer, "[DefineLow]\n") == 0 ) {
nIndex = 2;
}
}
else {
m_szDefineList[nIndex] += buffer;
}
}
fclose(fp);
}
m_szCurrentDefine = m_szDefineList[0];
UpdateData( FALSE );
m_ComboBox.SetCurSel( 0 );
//OnCbnSelchangeCombo();
if( strstr(GetCommandLine(), "-autostart") != NULL ) {
OnBnClickedButtonCompile();
}
return TRUE; // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.
}
void CEtPackingShaderDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 대화 상자에 최소화 단추를 추가할 경우 아이콘을 그리려면
// 아래 코드가 필요합니다. 문서/뷰 모델을 사용하는 MFC 응용 프로그램의 경우에는
// 프레임워크에서 이 작업을 자동으로 수행합니다.
void CEtPackingShaderDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 클라이언트 사각형에서 아이콘을 가운데에 맞춥니다.
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 아이콘을 그립니다.
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// 사용자가 최소화된 창을 끄는 동안에 커서가 표시되도록 시스템에서
// 이 함수를 호출합니다.
HCURSOR CEtPackingShaderDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
struct SHADER_COMPILE_INFO
{
char szFileName[64];
int nQualityLevel;
DWORD dwBufferSize;
BYTE *pCompiledBuffer;
};
DWORD WINAPI CEtPackingShaderDlg::CompileProc( LPVOID pThisPointer )
{
CEtPackingShaderDlg *pThis = (CEtPackingShaderDlg*)pThisPointer;
std::vector< std::string > &shaderFileNameList = GetShaderFileNameList( pThis->m_szShaderFolder );
std::vector< SHADER_COMPILE_INFO > CompiledList;
CString str;
for( int nQualityLevel = 0; nQualityLevel < 3; nQualityLevel++)
{
int nErrors=0;
int nSuccess=0;
std::vector<D3DXMACRO> DefineList = GetStringToMacro( pThis->m_szDefineList[ nQualityLevel ] );
for each( std::string szFileName in shaderFileNameList )
{
char szName[255];
char *ps = strrchr((char*)szFileName.c_str(), '\\');
strcpy(szName, ps+1);
str += szName;
const char *fullName = szFileName.c_str();
LPD3DXEFFECTCOMPILER pCompiler = NULL;
LPD3DXBUFFER pParseErrors = NULL;
DWORD dwFlags = 0;
D3DXCreateEffectCompilerFromFile(fullName, &DefineList[0], NULL, dwFlags, &pCompiler, &pParseErrors);
if(!pCompiler) {
char *szErrorMsg = (char*)pParseErrors->GetBufferPointer();
// compile error
str += " . . . Compile Error - ";
str += szErrorMsg;
str += "\r\n";
pThis->m_progressEdit.SetWindowText( str );
pThis->m_progressEdit.LineScroll( INT_MAX );
nErrors++;
break;
}
LPD3DXBUFFER pCompiledEffect = NULL;
LPD3DXBUFFER pErrorMsg = NULL;
pCompiler->CompileEffect(dwFlags, &pCompiledEffect, &pErrorMsg);
if(!pCompiledEffect) {
char *szErrorMsg = (char*)pErrorMsg->GetBufferPointer();
str += " . . . Compile Error - ";
str += szErrorMsg;
str += "\r\n";
pThis->m_progressEdit.SetWindowText( str );
pThis->m_progressEdit.LineScroll( INT_MAX );
nErrors++;
break;
}
pCompiler->Release();
SHADER_COMPILE_INFO scInfo;
strcpy(scInfo.szFileName, szName);
scInfo.nQualityLevel = nQualityLevel;
scInfo.dwBufferSize = pCompiledEffect->GetBufferSize();
scInfo.pCompiledBuffer = new BYTE[ pCompiledEffect->GetBufferSize() ];
memcpy(scInfo.pCompiledBuffer, pCompiledEffect->GetBufferPointer(), pCompiledEffect->GetBufferSize());
CompiledList.push_back( scInfo );
pCompiledEffect->Release();
str += " . . . Compiling Ok.\r\n";
pThis->m_progressEdit.SetWindowText( str );
pThis->m_progressEdit.LineScroll( INT_MAX );
nSuccess++;
}
for each( D3DXMACRO e in DefineList ) {
delete [] e.Name;
delete [] e.Definition;
}
if( nErrors == 0 ) {
char szText[255];
sprintf(szText, " %d succeeded, %d failed\r\n\r\n", nSuccess, nErrors );
str += szText;
pThis->m_progressEdit.SetWindowText( str );
pThis->m_progressEdit.LineScroll( INT_MAX );
}
else {
break;
}
}
char szOutName[255];
strcpy(szOutName, pThis->m_szOutputFolder.GetBuffer());
strcat(szOutName, "\\DnShaders.dat");
FILE *fp = fopen(szOutName, "wb");
if( fp == NULL ) {
AfxMessageBox("파일을 쓸 수 없습니다.");
}
else {
DWORD dwHead = *(DWORD*)"SHD0";
int dwCount = (int)CompiledList.size();
fwrite(&dwHead, sizeof(DWORD), 1, fp);
fwrite(&dwCount, sizeof(int), 1, fp);
for( int i = 0; i < dwCount; i++) {
fwrite(CompiledList[i].szFileName, 64, 1, fp);
fwrite(&CompiledList[i].nQualityLevel, sizeof(DWORD), 1, fp);
fwrite(&CompiledList[i].dwBufferSize, sizeof(DWORD), 1, fp);
fwrite(CompiledList[i].pCompiledBuffer, CompiledList[i].dwBufferSize, 1, fp);
delete [] CompiledList[i].pCompiledBuffer;
}
fclose(fp);
char szText[255];
sprintf(szText, " %d shaders save success. \r\n\r\n", dwCount );
str += szText;
pThis->m_progressEdit.SetWindowText( str );
pThis->m_progressEdit.LineScroll( INT_MAX );
}
if( strstr(GetCommandLine(), "-autostart") != NULL ) {
pThis->EndDialog(IDOK);
}
return 0;
}
void CEtPackingShaderDlg::OnBnClickedButtonCompile()
{
OnCbnSelchangeCombo();
HANDLE packingThread = ::CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)&CEtPackingShaderDlg::CompileProc, this, 0, NULL );
}
void CEtPackingShaderDlg::OnCbnSelchangeCombo()
{
UpdateData( TRUE );
m_szDefineList[ m_nPrevComboSel ] = m_szCurrentDefine;
int nCurSel = m_ComboBox.GetCurSel();
m_szCurrentDefine = m_szDefineList[ nCurSel ];
UpdateData( FALSE );
m_nPrevComboSel = nCurSel;
}
void CEtPackingShaderDlg::OnBnClickedButtonFolder()
{
// TODO: Add your control notification handler code here
CXTBrowseDialog Dlg;
UpdateData(TRUE);
Dlg.SetTitle(_T("Select Shader Directory"));
if( !m_szShaderFolder.IsEmpty() ) {
TCHAR path[_MAX_PATH];
STRCPY_S(path, _MAX_PATH, m_szShaderFolder);
Dlg.SetSelPath(path);
}
if( Dlg.DoModal() == IDOK ) {
m_szShaderFolder = Dlg.GetSelPath();
UpdateData(FALSE);
}
}
void CEtPackingShaderDlg::OnBnClickedButtonOutput()
{
// TODO: Add your control notification handler code here
CXTBrowseDialog Dlg;
UpdateData(TRUE);
Dlg.SetTitle(_T("Select Output Directory"));
if( !m_szOutputFolder.IsEmpty() ) {
TCHAR path[_MAX_PATH];
STRCPY_S(path, _MAX_PATH, m_szOutputFolder);
Dlg.SetSelPath(path);
}
if( Dlg.DoModal() == IDOK ) {
m_szOutputFolder = Dlg.GetSelPath();
UpdateData(FALSE);
}
}
void CEtPackingShaderDlg::OnDestroy()
{
CDialog::OnDestroy();
SetRegistryString( HKEY_CURRENT_USER, REG_SUBKEY, "ShaderFolder", m_szShaderFolder.GetBuffer() );
SetRegistryString( HKEY_CURRENT_USER, REG_SUBKEY, "OutputFolder", m_szOutputFolder.GetBuffer() );
OnCbnSelchangeCombo();
/*SetRegistryString( HKEY_CURRENT_USER, REG_SUBKEY, "DefineHigh", m_szDefineList[0].GetBuffer() );
SetRegistryString( HKEY_CURRENT_USER, REG_SUBKEY, "DefineNormal", m_szDefineList[1].GetBuffer() );
SetRegistryString( HKEY_CURRENT_USER, REG_SUBKEY, "DefineLow", m_szDefineList[2].GetBuffer() ); */
FILE *fp = fopen(m_szFileName, "wt");
fputs("[DefineHigh]\n", fp);
fputs(m_szDefineList[0].GetBuffer(), fp);
fputs("[DefineNormal]\n", fp);
fputs(m_szDefineList[1].GetBuffer(), fp);
fputs("[DefineLow]\n", fp);
fputs(m_szDefineList[2].GetBuffer(), fp);
fclose(fp);
// TODO: Add your message handler code here
}