2015-06-30 02:54:59 +00:00
|
|
|
/*
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
Open Asset Import Library (assimp)
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
2020-01-20 13:53:12 +00:00
|
|
|
Copyright (c) 2006-2020, assimp team
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
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 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 "AnimEvaluator.h"
|
|
|
|
#include "SceneAnimator.h"
|
2020-11-11 18:38:42 +00:00
|
|
|
#include "assimp_view.h"
|
2018-01-07 05:00:11 +00:00
|
|
|
#include <assimp/StringUtils.h>
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2017-06-01 14:21:23 +00:00
|
|
|
#include <commdlg.h>
|
|
|
|
|
2015-06-30 02:54:59 +00:00
|
|
|
namespace AssimpView {
|
|
|
|
|
|
|
|
using namespace Assimp;
|
|
|
|
|
|
|
|
extern std::string g_szCheckerBackgroundShader;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
struct SVertex {
|
|
|
|
float x, y, z, w, u, v;
|
2015-06-30 02:54:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
CDisplay CDisplay::s_cInstance;
|
|
|
|
|
|
|
|
extern COLORREF g_aclCustomColors[16] /*= {0}*/;
|
|
|
|
extern HKEY g_hRegistry;
|
|
|
|
extern float g_fLoadTime;
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Table of colors used for normal vectors.
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DXVECTOR4 g_aclNormalColors[14] = {
|
|
|
|
D3DXVECTOR4(0xFF / 255.0f, 0xFF / 255.0f, 0xFF / 255.0f, 1.0f), // white
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DXVECTOR4(0xFF / 255.0f, 0x00 / 255.0f, 0x00 / 255.0f, 1.0f), // red
|
|
|
|
D3DXVECTOR4(0x00 / 255.0f, 0xFF / 255.0f, 0x00 / 255.0f, 1.0f), // green
|
|
|
|
D3DXVECTOR4(0x00 / 255.0f, 0x00 / 255.0f, 0xFF / 255.0f, 1.0f), // blue
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DXVECTOR4(0xFF / 255.0f, 0xFF / 255.0f, 0x00 / 255.0f, 1.0f), // yellow
|
|
|
|
D3DXVECTOR4(0xFF / 255.0f, 0x00 / 255.0f, 0xFF / 255.0f, 1.0f), // magenta
|
|
|
|
D3DXVECTOR4(0x00 / 255.0f, 0xFF / 255.0f, 0xFF / 255.0f, 1.0f), // wtf
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DXVECTOR4(0xFF / 255.0f, 0x60 / 255.0f, 0x60 / 255.0f, 1.0f), // light red
|
|
|
|
D3DXVECTOR4(0x60 / 255.0f, 0xFF / 255.0f, 0x60 / 255.0f, 1.0f), // light green
|
|
|
|
D3DXVECTOR4(0x60 / 255.0f, 0x60 / 255.0f, 0xFF / 255.0f, 1.0f), // light blue
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DXVECTOR4(0xA0 / 255.0f, 0x00 / 255.0f, 0x00 / 255.0f, 1.0f), // dark red
|
|
|
|
D3DXVECTOR4(0x00 / 255.0f, 0xA0 / 255.0f, 0x00 / 255.0f, 1.0f), // dark green
|
|
|
|
D3DXVECTOR4(0x00 / 255.0f, 0x00 / 255.0f, 0xA0 / 255.0f, 1.0f), // dark blue
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DXVECTOR4(0x88 / 255.0f, 0x88 / 255.0f, 0x88 / 255.0f, 1.0f) // gray
|
2015-06-30 02:54:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
// Recursively count the number of nodes in an asset's node graph
|
2015-06-30 02:54:59 +00:00
|
|
|
// Used by LoadAsset()
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
void GetNodeCount(aiNode *pcNode, unsigned int *piCnt) {
|
|
|
|
*piCnt = *piCnt + 1;
|
2018-05-09 07:51:05 +00:00
|
|
|
for (unsigned int i = 0; i < pcNode->mNumChildren; ++i) {
|
|
|
|
GetNodeCount(pcNode->mChildren[i], piCnt);
|
|
|
|
}
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------------
|
2019-02-04 21:15:15 +00:00
|
|
|
int CDisplay::EnableAnimTools(BOOL hm) {
|
2020-11-11 18:38:42 +00:00
|
|
|
EnableWindow(GetDlgItem(g_hDlg, IDC_PLAY), hm);
|
|
|
|
EnableWindow(GetDlgItem(g_hDlg, IDC_SLIDERANIM), hm);
|
|
|
|
|
2015-06-30 02:54:59 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Fill animation combo box
|
2019-02-04 21:15:15 +00:00
|
|
|
int CDisplay::FillAnimList(void) {
|
2020-11-11 18:38:42 +00:00
|
|
|
if (0 != g_pcAsset->pcScene->mNumAnimations) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// now fill in all animation names
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumAnimations; ++i) {
|
|
|
|
SendDlgItemMessage(g_hDlg, IDC_COMBO1, CB_ADDSTRING, 0,
|
|
|
|
(LPARAM)g_pcAsset->pcScene->mAnimations[i]->mName.data);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// also add a dummy - 'none'
|
2020-11-11 18:38:42 +00:00
|
|
|
SendDlgItemMessage(g_hDlg, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM) "none");
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// select first
|
2020-11-11 18:38:42 +00:00
|
|
|
SendDlgItemMessage(g_hDlg, IDC_COMBO1, CB_SETCURSEL, 0, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
EnableAnimTools(TRUE);
|
2020-11-11 18:38:42 +00:00
|
|
|
} else {
|
|
|
|
// tools remain disabled
|
2015-06-30 02:54:59 +00:00
|
|
|
EnableAnimTools(FALSE);
|
2020-11-11 18:38:42 +00:00
|
|
|
}
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Clear the list of animations
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::ClearAnimList(void) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// clear the combo box
|
2020-11-11 18:38:42 +00:00
|
|
|
SendDlgItemMessage(g_hDlg, IDC_COMBO1, CB_RESETCONTENT, 0, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Clear the tree view
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::ClearDisplayList(void) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// clear the combo box
|
2020-11-11 18:38:42 +00:00
|
|
|
TreeView_DeleteAllItems(GetDlgItem(g_hDlg, IDC_TREE1));
|
2015-06-30 02:54:59 +00:00
|
|
|
this->Reset();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Add a specific node to the display list
|
|
|
|
int CDisplay::AddNodeToDisplayList(
|
2020-11-11 18:38:42 +00:00
|
|
|
unsigned int iIndex,
|
|
|
|
unsigned int iDepth,
|
|
|
|
aiNode *pcNode,
|
|
|
|
HTREEITEM hRoot) {
|
2020-04-07 14:56:22 +00:00
|
|
|
ai_assert(nullptr != pcNode);
|
|
|
|
ai_assert(nullptr != hRoot);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
char chTemp[MAXLEN];
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (0 == pcNode->mName.length) {
|
|
|
|
if (iIndex >= 100) {
|
|
|
|
iIndex += iDepth * 1000;
|
|
|
|
} else if (iIndex >= 10) {
|
|
|
|
iIndex += iDepth * 100;
|
|
|
|
} else
|
|
|
|
iIndex += iDepth * 10;
|
|
|
|
ai_snprintf(chTemp, MAXLEN, "Node %u", iIndex);
|
|
|
|
} else {
|
|
|
|
ai_snprintf(chTemp, MAXLEN, "%s", pcNode->mName.data);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
ai_snprintf(chTemp + strlen(chTemp), MAXLEN - strlen(chTemp), iIndex ? " (%i)" : " (%i meshes)", pcNode->mNumMeshes);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
TVITEMEXW tvi;
|
|
|
|
TVINSERTSTRUCTW sNew;
|
|
|
|
|
|
|
|
wchar_t tmp[512];
|
2020-11-11 18:38:42 +00:00
|
|
|
int t = MultiByteToWideChar(CP_UTF8, 0, chTemp, -1, tmp, 512);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
tvi.pszText = tmp;
|
|
|
|
tvi.cchTextMax = (int)t;
|
|
|
|
|
|
|
|
tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_HANDLE | TVIF_PARAM;
|
|
|
|
tvi.iImage = this->m_aiImageList[AI_VIEW_IMGLIST_NODE];
|
|
|
|
tvi.iSelectedImage = this->m_aiImageList[AI_VIEW_IMGLIST_NODE];
|
|
|
|
tvi.lParam = (LPARAM)5;
|
|
|
|
|
|
|
|
sNew.itemex = tvi;
|
|
|
|
sNew.hInsertAfter = TVI_LAST;
|
|
|
|
sNew.hParent = hRoot;
|
|
|
|
|
|
|
|
// add the item to the list
|
2020-11-11 18:38:42 +00:00
|
|
|
HTREEITEM hTexture = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg, IDC_TREE1),
|
|
|
|
TVM_INSERTITEMW,
|
|
|
|
0,
|
|
|
|
(LPARAM)(LPTVINSERTSTRUCT)&sNew);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// recursively add all child nodes
|
|
|
|
++iDepth;
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i < pcNode->mNumChildren; ++i) {
|
|
|
|
AddNodeToDisplayList(i, iDepth, pcNode->mChildren[i], hTexture);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// add the node to the list
|
|
|
|
NodeInfo info;
|
|
|
|
info.hTreeItem = hTexture;
|
|
|
|
info.psNode = pcNode;
|
|
|
|
this->AddNode(info);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::AddMeshToDisplayList(unsigned int iIndex, HTREEITEM hRoot) {
|
|
|
|
aiMesh *pcMesh = g_pcAsset->pcScene->mMeshes[iIndex];
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
char chTemp[MAXLEN];
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (0 == pcMesh->mName.length) {
|
|
|
|
ai_snprintf(chTemp, MAXLEN, "Mesh %u", iIndex);
|
|
|
|
} else {
|
|
|
|
ai_snprintf(chTemp, MAXLEN, "%s", pcMesh->mName.data);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
ai_snprintf(chTemp + strlen(chTemp), MAXLEN - strlen(chTemp), iIndex ? " (%i)" : " (%i faces)", pcMesh->mNumFaces);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
TVITEMEXW tvi;
|
|
|
|
TVINSERTSTRUCTW sNew;
|
|
|
|
|
|
|
|
wchar_t tmp[512];
|
2020-11-11 18:38:42 +00:00
|
|
|
int t = MultiByteToWideChar(CP_UTF8, 0, chTemp, -1, tmp, 512);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
tvi.pszText = tmp;
|
|
|
|
tvi.cchTextMax = (int)t;
|
|
|
|
|
|
|
|
tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_HANDLE | TVIF_PARAM;
|
|
|
|
tvi.iImage = this->m_aiImageList[AI_VIEW_IMGLIST_NODE];
|
|
|
|
tvi.iSelectedImage = this->m_aiImageList[AI_VIEW_IMGLIST_NODE];
|
|
|
|
tvi.lParam = (LPARAM)5;
|
|
|
|
|
|
|
|
sNew.itemex = tvi;
|
|
|
|
sNew.hInsertAfter = TVI_LAST;
|
|
|
|
sNew.hParent = hRoot;
|
|
|
|
|
|
|
|
// add the item to the list
|
2020-11-11 18:38:42 +00:00
|
|
|
HTREEITEM hTexture = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg, IDC_TREE1),
|
|
|
|
TVM_INSERTITEMW,
|
|
|
|
0,
|
|
|
|
(LPARAM)(LPTVINSERTSTRUCT)&sNew);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// add the mesh to the list of all mesh entries in the scene browser
|
|
|
|
MeshInfo info;
|
|
|
|
info.hTreeItem = hTexture;
|
|
|
|
info.psMesh = pcMesh;
|
|
|
|
AddMesh(info);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Replace the currently selected texture by another one
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::ReplaceCurrentTexture(const char *szPath) {
|
2020-04-07 14:56:22 +00:00
|
|
|
ai_assert(nullptr != szPath);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// well ... try to load it
|
2020-11-11 18:38:42 +00:00
|
|
|
IDirect3DTexture9 *piTexture = nullptr;
|
2015-06-30 02:54:59 +00:00
|
|
|
aiString szString;
|
2020-11-11 18:38:42 +00:00
|
|
|
strcpy(szString.data, szPath);
|
2020-04-03 18:36:44 +00:00
|
|
|
szString.length = static_cast<ai_uint32>(strlen(szPath));
|
2020-11-11 18:38:42 +00:00
|
|
|
CMaterialManager::Instance().LoadTexture(&piTexture, &szString);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
if (!piTexture) {
|
|
|
|
CLogDisplay::Instance().AddEntry("[ERROR] Unable to load this texture",
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DCOLOR_ARGB(0xFF, 0xFF, 0x0, 0x0));
|
2015-06-30 02:54:59 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// we must also change the icon of the corresponding tree
|
|
|
|
// view item if the default texture was previously set
|
|
|
|
TVITEMEX tvi;
|
|
|
|
tvi.mask = TVIF_SELECTEDIMAGE | TVIF_IMAGE;
|
|
|
|
tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_MATERIAL];
|
|
|
|
tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_MATERIAL];
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
TreeView_SetItem(GetDlgItem(g_hDlg, IDC_TREE1),
|
|
|
|
m_pcCurrentTexture->hTreeItem);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// update all meshes referencing this material
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) {
|
2015-06-30 02:54:59 +00:00
|
|
|
if (this->m_pcCurrentTexture->iMatIndex != g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex)
|
|
|
|
continue;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
AssetHelper::MeshHelper *pcMesh = g_pcAsset->apcMeshes[i];
|
|
|
|
IDirect3DTexture9 **tex = nullptr;
|
|
|
|
const char *tex_string = nullptr;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
switch (this->m_pcCurrentTexture->iType) {
|
2015-06-30 02:54:59 +00:00
|
|
|
case aiTextureType_DIFFUSE:
|
|
|
|
tex = &pcMesh->piDiffuseTexture;
|
|
|
|
tex_string = "DIFFUSE_TEXTURE";
|
|
|
|
break;
|
|
|
|
case aiTextureType_AMBIENT:
|
|
|
|
tex = &pcMesh->piAmbientTexture;
|
|
|
|
tex_string = "AMBIENT_TEXTURE";
|
|
|
|
break;
|
|
|
|
case aiTextureType_SPECULAR:
|
|
|
|
tex = &pcMesh->piSpecularTexture;
|
|
|
|
tex_string = "SPECULAR_TEXTURE";
|
|
|
|
break;
|
|
|
|
case aiTextureType_EMISSIVE:
|
|
|
|
tex = &pcMesh->piEmissiveTexture;
|
|
|
|
tex_string = "EMISSIVE_TEXTURE";
|
|
|
|
break;
|
|
|
|
case aiTextureType_LIGHTMAP:
|
|
|
|
tex = &pcMesh->piLightmapTexture;
|
|
|
|
tex_string = "LIGHTMAP_TEXTURE";
|
|
|
|
break;
|
|
|
|
case aiTextureType_DISPLACEMENT:
|
|
|
|
case aiTextureType_REFLECTION:
|
|
|
|
case aiTextureType_UNKNOWN:
|
|
|
|
break;
|
|
|
|
case aiTextureType_SHININESS:
|
|
|
|
tex = &pcMesh->piShininessTexture;
|
|
|
|
tex_string = "SHININESS_TEXTURE";
|
|
|
|
break;
|
|
|
|
case aiTextureType_NORMALS:
|
|
|
|
case aiTextureType_HEIGHT:
|
|
|
|
|
|
|
|
// special handling here
|
2020-11-11 18:38:42 +00:00
|
|
|
if (pcMesh->piNormalTexture && pcMesh->piNormalTexture != piTexture) {
|
2015-06-30 02:54:59 +00:00
|
|
|
piTexture->AddRef();
|
|
|
|
pcMesh->piNormalTexture->Release();
|
|
|
|
pcMesh->piNormalTexture = piTexture;
|
2020-11-11 18:38:42 +00:00
|
|
|
CMaterialManager::Instance().HMtoNMIfNecessary(pcMesh->piNormalTexture, &pcMesh->piNormalTexture, true);
|
2015-06-30 02:54:59 +00:00
|
|
|
m_pcCurrentTexture->piTexture = &pcMesh->piNormalTexture;
|
|
|
|
|
|
|
|
if (!pcMesh->bSharedFX) {
|
2020-11-11 18:38:42 +00:00
|
|
|
pcMesh->piEffect->SetTexture("NORMAL_TEXTURE", piTexture);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default: //case aiTextureType_OPACITY && case aiTextureType_OPACITY | 0x40000000:
|
|
|
|
|
|
|
|
tex = &pcMesh->piOpacityTexture;
|
|
|
|
tex_string = "OPACITY_TEXTURE";
|
|
|
|
break;
|
|
|
|
};
|
2020-11-11 18:38:42 +00:00
|
|
|
if (tex && *tex && *tex != piTexture) {
|
2015-06-30 02:54:59 +00:00
|
|
|
(**tex).Release();
|
|
|
|
*tex = piTexture;
|
|
|
|
m_pcCurrentTexture->piTexture = tex;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
pcMesh->piEffect->SetTexture(tex_string, piTexture);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
int CDisplay::AddTextureToDisplayList(unsigned int iType,
|
2020-11-11 18:38:42 +00:00
|
|
|
unsigned int iIndex,
|
|
|
|
const aiString *szPath,
|
|
|
|
HTREEITEM hFX,
|
|
|
|
unsigned int iUVIndex /*= 0*/,
|
|
|
|
const float fBlendFactor /*= 0.0f*/,
|
|
|
|
aiTextureOp eTextureOp /*= aiTextureOp_Multiply*/,
|
|
|
|
unsigned int iMesh /*= 0*/) {
|
2020-04-07 14:56:22 +00:00
|
|
|
ai_assert(nullptr != szPath);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
char chTemp[512];
|
|
|
|
char chTempEmb[256];
|
2020-11-11 18:38:42 +00:00
|
|
|
const char *sz = strrchr(szPath->data, '\\');
|
|
|
|
if (!sz) sz = strrchr(szPath->data, '/');
|
|
|
|
if (!sz) {
|
|
|
|
if ('*' == *szPath->data) {
|
|
|
|
int iIndex2 = atoi(szPath->data + 1);
|
|
|
|
ai_snprintf(chTempEmb, 256, "Embedded #%i", iIndex2);
|
2015-06-30 02:54:59 +00:00
|
|
|
sz = chTempEmb;
|
2020-11-11 18:38:42 +00:00
|
|
|
} else {
|
2015-06-30 02:54:59 +00:00
|
|
|
sz = szPath->data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool bIsExtraOpacity = 0 != (iType & 0x40000000);
|
2020-11-11 18:38:42 +00:00
|
|
|
const char *szType;
|
|
|
|
IDirect3DTexture9 **piTexture;
|
|
|
|
switch (iType) {
|
2015-06-30 02:54:59 +00:00
|
|
|
case aiTextureType_DIFFUSE:
|
|
|
|
piTexture = &g_pcAsset->apcMeshes[iMesh]->piDiffuseTexture;
|
|
|
|
szType = "Diffuse";
|
|
|
|
break;
|
|
|
|
case aiTextureType_SPECULAR:
|
|
|
|
piTexture = &g_pcAsset->apcMeshes[iMesh]->piSpecularTexture;
|
|
|
|
szType = "Specular";
|
|
|
|
break;
|
|
|
|
case aiTextureType_AMBIENT:
|
|
|
|
piTexture = &g_pcAsset->apcMeshes[iMesh]->piAmbientTexture;
|
|
|
|
szType = "Ambient";
|
|
|
|
break;
|
|
|
|
case aiTextureType_EMISSIVE:
|
|
|
|
piTexture = &g_pcAsset->apcMeshes[iMesh]->piEmissiveTexture;
|
|
|
|
szType = "Emissive";
|
|
|
|
break;
|
|
|
|
case aiTextureType_HEIGHT:
|
|
|
|
piTexture = &g_pcAsset->apcMeshes[iMesh]->piNormalTexture;
|
|
|
|
szType = "Heightmap";
|
|
|
|
break;
|
|
|
|
case aiTextureType_NORMALS:
|
|
|
|
piTexture = &g_pcAsset->apcMeshes[iMesh]->piNormalTexture;
|
|
|
|
szType = "Normalmap";
|
|
|
|
break;
|
|
|
|
case aiTextureType_SHININESS:
|
|
|
|
piTexture = &g_pcAsset->apcMeshes[iMesh]->piShininessTexture;
|
|
|
|
szType = "Shininess";
|
|
|
|
break;
|
|
|
|
case aiTextureType_LIGHTMAP:
|
|
|
|
piTexture = &g_pcAsset->apcMeshes[iMesh]->piLightmapTexture;
|
|
|
|
szType = "Lightmap";
|
|
|
|
break;
|
|
|
|
case aiTextureType_DISPLACEMENT:
|
2020-04-07 14:56:22 +00:00
|
|
|
piTexture = nullptr;
|
2015-06-30 02:54:59 +00:00
|
|
|
szType = "Displacement";
|
|
|
|
break;
|
|
|
|
case aiTextureType_REFLECTION:
|
2020-04-07 14:56:22 +00:00
|
|
|
piTexture = nullptr;
|
2015-06-30 02:54:59 +00:00
|
|
|
szType = "Reflection";
|
|
|
|
break;
|
|
|
|
case aiTextureType_UNKNOWN:
|
2020-04-07 14:56:22 +00:00
|
|
|
piTexture = nullptr;
|
2015-06-30 02:54:59 +00:00
|
|
|
szType = "Unknown";
|
|
|
|
break;
|
|
|
|
default: // opacity + opacity | mask
|
|
|
|
piTexture = &g_pcAsset->apcMeshes[iMesh]->piOpacityTexture;
|
|
|
|
szType = "Opacity";
|
|
|
|
break;
|
|
|
|
};
|
2020-11-11 18:38:42 +00:00
|
|
|
if (bIsExtraOpacity) {
|
|
|
|
ai_snprintf(chTemp, 512, "%s %i (<copy of diffuse #1>)", szType, iIndex + 1);
|
|
|
|
} else
|
|
|
|
ai_snprintf(chTemp, 512, "%s %i (%s)", szType, iIndex + 1, sz);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
TVITEMEX tvi;
|
|
|
|
TVINSERTSTRUCT sNew;
|
|
|
|
tvi.pszText = chTemp;
|
|
|
|
tvi.cchTextMax = (int)strlen(chTemp);
|
2020-05-25 18:38:12 +00:00
|
|
|
tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_HANDLE;
|
2015-06-30 02:54:59 +00:00
|
|
|
tvi.lParam = (LPARAM)20;
|
|
|
|
|
|
|
|
// find out whether this is the default texture or not
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (piTexture && *piTexture) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// {9785DA94-1D96-426b-B3CB-BADC36347F5E}
|
2020-11-11 18:38:42 +00:00
|
|
|
static const GUID guidPrivateData = { 0x9785da94, 0x1d96, 0x426b,
|
2015-06-30 02:54:59 +00:00
|
|
|
{ 0xb3, 0xcb, 0xba, 0xdc, 0x36, 0x34, 0x7f, 0x5e } };
|
|
|
|
|
|
|
|
uint32_t iData = 0;
|
|
|
|
DWORD dwSize = 4;
|
2020-11-11 18:38:42 +00:00
|
|
|
(*piTexture)->GetPrivateData(guidPrivateData, &iData, &dwSize);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (0xFFFFFFFF == iData) {
|
2015-06-30 02:54:59 +00:00
|
|
|
tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID];
|
|
|
|
tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID];
|
2020-11-11 18:38:42 +00:00
|
|
|
} else {
|
2015-06-30 02:54:59 +00:00
|
|
|
tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE];
|
|
|
|
tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE];
|
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
} else {
|
2015-06-30 02:54:59 +00:00
|
|
|
tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID];
|
|
|
|
tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID];
|
|
|
|
}
|
|
|
|
|
|
|
|
sNew.itemex = tvi;
|
|
|
|
sNew.hInsertAfter = TVI_LAST;
|
|
|
|
sNew.hParent = hFX;
|
|
|
|
|
|
|
|
// add the item to the list
|
2020-11-11 18:38:42 +00:00
|
|
|
HTREEITEM hTexture = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg, IDC_TREE1),
|
|
|
|
TVM_INSERTITEM,
|
|
|
|
0,
|
|
|
|
(LPARAM)(LPTVINSERTSTRUCT)&sNew);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// add it to the list
|
|
|
|
CDisplay::TextureInfo sInfo;
|
|
|
|
sInfo.iUV = iUVIndex;
|
|
|
|
sInfo.fBlend = fBlendFactor;
|
|
|
|
sInfo.eOp = eTextureOp;
|
|
|
|
sInfo.szPath = szPath->data;
|
|
|
|
sInfo.hTreeItem = hTexture;
|
|
|
|
sInfo.piTexture = piTexture;
|
|
|
|
sInfo.iType = iType;
|
|
|
|
sInfo.iMatIndex = g_pcAsset->pcScene->mMeshes[iMesh]->mMaterialIndex;
|
|
|
|
AddTexture(sInfo);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
int CDisplay::AddMaterialToDisplayList(HTREEITEM hRoot,
|
2020-11-11 18:38:42 +00:00
|
|
|
unsigned int iIndex) {
|
2020-04-07 14:56:22 +00:00
|
|
|
ai_assert(nullptr != hRoot);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
aiMaterial *pcMat = g_pcAsset->pcScene->mMaterials[iIndex];
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// find the first mesh using this material index
|
|
|
|
unsigned int iMesh = 0;
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) {
|
|
|
|
if (iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) {
|
2015-06-30 02:54:59 +00:00
|
|
|
iMesh = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// use the name of the material, if possible
|
|
|
|
char chTemp[512];
|
|
|
|
aiString szOut;
|
2020-11-11 18:38:42 +00:00
|
|
|
if (AI_SUCCESS != aiGetMaterialString(pcMat, AI_MATKEY_NAME, &szOut)) {
|
|
|
|
ai_snprintf(chTemp, 512, "Material %i", iIndex + 1);
|
|
|
|
} else {
|
|
|
|
ai_snprintf(chTemp, 512, "%s (%i)", szOut.data, iIndex + 1);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
TVITEMEXW tvi;
|
|
|
|
TVINSERTSTRUCTW sNew;
|
|
|
|
|
|
|
|
wchar_t tmp[512];
|
2020-11-11 18:38:42 +00:00
|
|
|
int t = MultiByteToWideChar(CP_UTF8, 0, chTemp, -1, tmp, 512);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
tvi.pszText = tmp;
|
|
|
|
tvi.cchTextMax = (int)t;
|
2020-11-11 18:38:42 +00:00
|
|
|
tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_HANDLE | TVIF_PARAM;
|
2015-06-30 02:54:59 +00:00
|
|
|
tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_MATERIAL];
|
|
|
|
tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_MATERIAL];
|
|
|
|
tvi.lParam = (LPARAM)10;
|
|
|
|
|
|
|
|
sNew.itemex = tvi;
|
|
|
|
sNew.hInsertAfter = TVI_LAST;
|
|
|
|
sNew.hParent = hRoot;
|
|
|
|
|
|
|
|
// add the item to the list
|
2020-11-11 18:38:42 +00:00
|
|
|
HTREEITEM hTexture = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg, IDC_TREE1),
|
|
|
|
TVM_INSERTITEMW,
|
|
|
|
0,
|
|
|
|
(LPARAM)(LPTVINSERTSTRUCT)&sNew);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// for each texture in the list ... add it
|
|
|
|
unsigned int iUV;
|
|
|
|
float fBlend;
|
|
|
|
aiTextureOp eOp;
|
|
|
|
aiString szPath;
|
|
|
|
bool bNoOpacity = true;
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i <= AI_TEXTURE_TYPE_MAX; ++i) {
|
2015-06-30 02:54:59 +00:00
|
|
|
unsigned int iNum = 0;
|
2020-11-11 18:38:42 +00:00
|
|
|
while (true) {
|
|
|
|
if (AI_SUCCESS != aiGetMaterialTexture(pcMat, (aiTextureType)i, iNum,
|
|
|
|
&szPath, nullptr, &iUV, &fBlend, &eOp)) {
|
2015-06-30 02:54:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
if (aiTextureType_OPACITY == i) bNoOpacity = false;
|
|
|
|
AddTextureToDisplayList(i, iNum, &szPath, hTexture, iUV, fBlend, eOp, iMesh);
|
2015-06-30 02:54:59 +00:00
|
|
|
++iNum;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
AssetHelper::MeshHelper *pcMesh = g_pcAsset->apcMeshes[iMesh];
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (pcMesh->piDiffuseTexture && pcMesh->piDiffuseTexture == pcMesh->piOpacityTexture && bNoOpacity) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// check whether the diffuse texture is not a default texture
|
|
|
|
|
|
|
|
// {9785DA94-1D96-426b-B3CB-BADC36347F5E}
|
2020-11-11 18:38:42 +00:00
|
|
|
static const GUID guidPrivateData = { 0x9785da94, 0x1d96, 0x426b,
|
2015-06-30 02:54:59 +00:00
|
|
|
{ 0xb3, 0xcb, 0xba, 0xdc, 0x36, 0x34, 0x7f, 0x5e } };
|
|
|
|
|
|
|
|
uint32_t iData = 0;
|
|
|
|
DWORD dwSize = 4;
|
2020-11-11 18:38:42 +00:00
|
|
|
if (FAILED(pcMesh->piDiffuseTexture->GetPrivateData(guidPrivateData, &iData, &dwSize) ||
|
|
|
|
0xffffffff == iData)) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// seems the diffuse texture contains alpha, therefore it has been
|
|
|
|
// added to the opacity channel, too. Add a special value ...
|
|
|
|
AddTextureToDisplayList(aiTextureType_OPACITY | 0x40000000,
|
2020-11-11 18:38:42 +00:00
|
|
|
0, &szPath, hTexture, iUV, fBlend, eOp, iMesh);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// add the material to the list
|
|
|
|
MaterialInfo info;
|
|
|
|
info.hTreeItem = hTexture;
|
|
|
|
info.psMaterial = pcMat;
|
|
|
|
info.iIndex = iIndex;
|
|
|
|
info.piEffect = g_pcAsset->apcMeshes[iMesh]->piEffect;
|
|
|
|
this->AddMaterial(info);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
2018-05-31 18:15:13 +00:00
|
|
|
// Expand all elements in the tree-view
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::ExpandTree() {
|
2015-06-30 02:54:59 +00:00
|
|
|
// expand all materials
|
2020-11-11 18:38:42 +00:00
|
|
|
for (std::vector<MaterialInfo>::iterator
|
|
|
|
i = m_asMaterials.begin();
|
|
|
|
i != m_asMaterials.end(); ++i) {
|
|
|
|
TreeView_Expand(GetDlgItem(g_hDlg, IDC_TREE1), (*i).hTreeItem, TVE_EXPAND);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
// expand all nodes
|
2020-11-11 18:38:42 +00:00
|
|
|
for (std::vector<NodeInfo>::iterator
|
|
|
|
i = m_asNodes.begin();
|
|
|
|
i != m_asNodes.end(); ++i) {
|
|
|
|
TreeView_Expand(GetDlgItem(g_hDlg, IDC_TREE1), (*i).hTreeItem, TVE_EXPAND);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
TreeView_Expand(GetDlgItem(g_hDlg, IDC_TREE1), m_hRoot, TVE_EXPAND);
|
2015-06-30 02:54:59 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Get image list for tree view
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::LoadImageList(void) {
|
|
|
|
if (!m_hImageList) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// First, create the image list we will need.
|
|
|
|
// FIX: Need RGB888 color space to display all colors correctly
|
2020-11-11 18:38:42 +00:00
|
|
|
HIMAGELIST hIml = ImageList_Create(16, 16, ILC_COLOR24, 5, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// Load the bitmaps and add them to the image lists.
|
|
|
|
HBITMAP hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BFX));
|
2020-04-07 14:56:22 +00:00
|
|
|
m_aiImageList[AI_VIEW_IMGLIST_MATERIAL] = ImageList_Add(hIml, hBmp, nullptr);
|
2015-06-30 02:54:59 +00:00
|
|
|
DeleteObject(hBmp);
|
|
|
|
|
|
|
|
hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BNODE));
|
2020-04-07 14:56:22 +00:00
|
|
|
m_aiImageList[AI_VIEW_IMGLIST_NODE] = ImageList_Add(hIml, hBmp, nullptr);
|
2015-06-30 02:54:59 +00:00
|
|
|
DeleteObject(hBmp);
|
|
|
|
|
|
|
|
hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BTX));
|
2020-04-07 14:56:22 +00:00
|
|
|
m_aiImageList[AI_VIEW_IMGLIST_TEXTURE] = ImageList_Add(hIml, hBmp, nullptr);
|
2015-06-30 02:54:59 +00:00
|
|
|
DeleteObject(hBmp);
|
|
|
|
|
|
|
|
hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BTXI));
|
2020-04-07 14:56:22 +00:00
|
|
|
m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID] = ImageList_Add(hIml, hBmp, nullptr);
|
2015-06-30 02:54:59 +00:00
|
|
|
DeleteObject(hBmp);
|
|
|
|
|
|
|
|
hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BROOT));
|
2020-04-07 14:56:22 +00:00
|
|
|
m_aiImageList[AI_VIEW_IMGLIST_MODEL] = ImageList_Add(hIml, hBmp, nullptr);
|
2015-06-30 02:54:59 +00:00
|
|
|
DeleteObject(hBmp);
|
|
|
|
|
|
|
|
// Associate the image list with the tree.
|
2020-11-11 18:38:42 +00:00
|
|
|
TreeView_SetImageList(GetDlgItem(g_hDlg, IDC_TREE1), hIml, TVSIL_NORMAL);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
m_hImageList = hIml;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Fill tree view
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::FillDisplayList(void) {
|
2015-06-30 02:54:59 +00:00
|
|
|
LoadImageList();
|
|
|
|
|
|
|
|
// Initialize the tree view window.
|
|
|
|
// fill in the first entry
|
|
|
|
TVITEMEX tvi;
|
|
|
|
TVINSERTSTRUCT sNew;
|
2020-11-11 18:38:42 +00:00
|
|
|
tvi.pszText = (char *)"Model";
|
2015-06-30 02:54:59 +00:00
|
|
|
tvi.cchTextMax = (int)strlen(tvi.pszText);
|
|
|
|
tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_HANDLE | TVIF_STATE;
|
|
|
|
tvi.state = TVIS_EXPANDED;
|
|
|
|
tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_MODEL];
|
|
|
|
tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_MODEL];
|
|
|
|
tvi.lParam = (LPARAM)0;
|
|
|
|
|
|
|
|
sNew.itemex = tvi;
|
|
|
|
sNew.hInsertAfter = TVI_ROOT;
|
|
|
|
sNew.hParent = 0;
|
|
|
|
|
|
|
|
// add the root item to the tree
|
2020-11-11 18:38:42 +00:00
|
|
|
m_hRoot = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg, IDC_TREE1),
|
|
|
|
TVM_INSERTITEM,
|
|
|
|
0,
|
|
|
|
(LPARAM)(LPTVINSERTSTRUCT)&sNew);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// add each loaded material to the tree
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMaterials; ++i)
|
|
|
|
AddMaterialToDisplayList(m_hRoot, i);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// add each mesh to the tree
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i)
|
|
|
|
AddMeshToDisplayList(i, m_hRoot);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// now add all loaded nodes recursively
|
2020-11-11 18:38:42 +00:00
|
|
|
AddNodeToDisplayList(0, 0, g_pcAsset->pcScene->mRootNode, m_hRoot);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// now expand all parent nodes in the tree
|
|
|
|
ExpandTree();
|
|
|
|
|
|
|
|
// everything reacts a little bit slowly if D3D is rendering,
|
|
|
|
// so give GDI a small hint to leave the couch and work ;-)
|
|
|
|
UpdateWindow(g_hDlg);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Main render loop
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::OnRender() {
|
2015-06-30 02:54:59 +00:00
|
|
|
// update possible animation
|
2020-11-11 18:38:42 +00:00
|
|
|
if (g_pcAsset) {
|
2015-06-30 02:54:59 +00:00
|
|
|
static double lastPlaying = 0.;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
ai_assert(g_pcAsset->mAnimator);
|
2015-06-30 02:54:59 +00:00
|
|
|
if (g_bPlay) {
|
2020-11-11 18:38:42 +00:00
|
|
|
g_dCurrent += clock() / double(CLOCKS_PER_SEC) - lastPlaying;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
double time = g_dCurrent;
|
2020-11-11 18:38:42 +00:00
|
|
|
aiAnimation *mAnim = g_pcAsset->mAnimator->CurrentAnim();
|
|
|
|
if (mAnim && mAnim->mDuration > 0.0) {
|
2015-06-30 02:54:59 +00:00
|
|
|
double tps = mAnim->mTicksPerSecond ? mAnim->mTicksPerSecond : 25.f;
|
2020-11-11 18:38:42 +00:00
|
|
|
time = fmod(time, mAnim->mDuration / tps);
|
|
|
|
SendDlgItemMessage(g_hDlg, IDC_SLIDERANIM, TBM_SETPOS, TRUE, LPARAM(10000 * (time / (mAnim->mDuration / tps))));
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
g_pcAsset->mAnimator->Calculate(time);
|
2015-06-30 02:54:59 +00:00
|
|
|
lastPlaying = g_dCurrent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// begin the frame
|
|
|
|
g_piDevice->BeginScene();
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
switch (m_iViewMode) {
|
2015-06-30 02:54:59 +00:00
|
|
|
case VIEWMODE_FULL:
|
|
|
|
case VIEWMODE_NODE:
|
|
|
|
RenderFullScene();
|
|
|
|
break;
|
|
|
|
case VIEWMODE_MATERIAL:
|
|
|
|
RenderMaterialView();
|
|
|
|
break;
|
|
|
|
case VIEWMODE_TEXTURE:
|
|
|
|
RenderTextureView();
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Now render the log display in the upper right corner of the window
|
|
|
|
CLogDisplay::Instance().OnRender();
|
|
|
|
|
2018-05-31 18:15:13 +00:00
|
|
|
// present the back-buffer
|
2015-06-30 02:54:59 +00:00
|
|
|
g_piDevice->EndScene();
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->Present(nullptr, nullptr, nullptr, nullptr);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// don't remove this, problems on some older machines (AMD timing bug)
|
|
|
|
Sleep(10);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Update UI
|
2020-11-11 18:38:42 +00:00
|
|
|
void UpdateColorFieldsInUI() {
|
|
|
|
InvalidateRect(GetDlgItem(g_hDlg, IDC_LCOLOR1), nullptr, TRUE);
|
|
|
|
InvalidateRect(GetDlgItem(g_hDlg, IDC_LCOLOR2), nullptr, TRUE);
|
|
|
|
InvalidateRect(GetDlgItem(g_hDlg, IDC_LCOLOR3), nullptr, TRUE);
|
|
|
|
|
|
|
|
UpdateWindow(GetDlgItem(g_hDlg, IDC_LCOLOR1));
|
|
|
|
UpdateWindow(GetDlgItem(g_hDlg, IDC_LCOLOR2));
|
|
|
|
UpdateWindow(GetDlgItem(g_hDlg, IDC_LCOLOR3));
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// FIll statistics UI
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::FillDefaultStatistics(void) {
|
|
|
|
if (!g_pcAsset) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// clear all stats edit controls
|
2020-11-11 18:38:42 +00:00
|
|
|
SetDlgItemText(g_hDlg, IDC_EVERT, "0");
|
|
|
|
SetDlgItemText(g_hDlg, IDC_EFACE, "0");
|
|
|
|
SetDlgItemText(g_hDlg, IDC_EMAT, "0");
|
|
|
|
SetDlgItemText(g_hDlg, IDC_ENODE, "0");
|
|
|
|
SetDlgItemText(g_hDlg, IDC_ESHADER, "0");
|
|
|
|
SetDlgItemText(g_hDlg, IDC_ETEX, "0");
|
2015-06-30 02:54:59 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get the number of vertices/faces in the model
|
|
|
|
unsigned int iNumVert = 0;
|
|
|
|
unsigned int iNumFaces = 0;
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) {
|
2015-06-30 02:54:59 +00:00
|
|
|
iNumVert += g_pcAsset->pcScene->mMeshes[i]->mNumVertices;
|
|
|
|
iNumFaces += g_pcAsset->pcScene->mMeshes[i]->mNumFaces;
|
|
|
|
}
|
|
|
|
// and fill the statistic edit controls
|
|
|
|
char szOut[1024];
|
2020-11-11 18:38:42 +00:00
|
|
|
ai_snprintf(szOut, 1024, "%i", (int)iNumVert);
|
|
|
|
SetDlgItemText(g_hDlg, IDC_EVERT, szOut);
|
|
|
|
ai_snprintf(szOut, 1024, "%i", (int)iNumFaces);
|
|
|
|
SetDlgItemText(g_hDlg, IDC_EFACE, szOut);
|
|
|
|
ai_snprintf(szOut, 1024, "%i", (int)g_pcAsset->pcScene->mNumMaterials);
|
|
|
|
SetDlgItemText(g_hDlg, IDC_EMAT, szOut);
|
|
|
|
ai_snprintf(szOut, 1024, "%i", (int)g_pcAsset->pcScene->mNumMeshes);
|
|
|
|
SetDlgItemText(g_hDlg, IDC_EMESH, szOut);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// need to get the number of nodes
|
|
|
|
iNumVert = 0;
|
2020-11-11 18:38:42 +00:00
|
|
|
GetNodeCount(g_pcAsset->pcScene->mRootNode, &iNumVert);
|
|
|
|
ai_snprintf(szOut, 1024, "%i", (int)iNumVert);
|
|
|
|
SetDlgItemText(g_hDlg, IDC_ENODEWND, szOut);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// now get the number of unique shaders generated for the asset
|
|
|
|
// (even if the environment changes this number won't change)
|
2020-11-11 18:38:42 +00:00
|
|
|
ai_snprintf(szOut, 1024, "%i", CMaterialManager::Instance().GetShaderCount());
|
|
|
|
SetDlgItemText(g_hDlg, IDC_ESHADER, szOut);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
sprintf(szOut, "%.5f", (float)g_fLoadTime);
|
|
|
|
SetDlgItemText(g_hDlg, IDC_ELOAD, szOut);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
UpdateColorFieldsInUI();
|
|
|
|
UpdateWindow(g_hDlg);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Reset UI
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::Reset(void) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// clear all lists
|
|
|
|
m_asMaterials.clear();
|
|
|
|
m_asTextures.clear();
|
|
|
|
m_asNodes.clear();
|
|
|
|
m_asMeshes.clear();
|
|
|
|
|
2020-04-07 14:56:22 +00:00
|
|
|
m_hRoot = nullptr;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
return OnSetupNormalView();
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// reset to standard statistics view
|
2020-11-11 18:38:42 +00:00
|
|
|
void ShowNormalUIComponents() {
|
|
|
|
ShowWindow(GetDlgItem(g_hDlg, IDC_NUMNODES), SW_SHOW);
|
|
|
|
ShowWindow(GetDlgItem(g_hDlg, IDC_ENODEWND), SW_SHOW);
|
|
|
|
ShowWindow(GetDlgItem(g_hDlg, IDC_NUMSHADERS), SW_SHOW);
|
|
|
|
ShowWindow(GetDlgItem(g_hDlg, IDC_LOADTIME), SW_SHOW);
|
|
|
|
ShowWindow(GetDlgItem(g_hDlg, IDC_ESHADER), SW_SHOW);
|
|
|
|
ShowWindow(GetDlgItem(g_hDlg, IDC_ELOAD), SW_SHOW);
|
|
|
|
ShowWindow(GetDlgItem(g_hDlg, IDC_VIEWMATRIX), SW_HIDE);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::OnSetupNormalView() {
|
|
|
|
if (VIEWMODE_NODE == m_iViewMode) {
|
2015-06-30 02:54:59 +00:00
|
|
|
ShowNormalUIComponents();
|
|
|
|
}
|
|
|
|
|
|
|
|
// now ... change the meaning of the statistics fields back
|
2020-11-11 18:38:42 +00:00
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMVERTS), "Vertices:");
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMNODES), "Nodes:");
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMFACES), "Faces:");
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMSHADERS), "Shaders:");
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMMATS), "Materials:");
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMMESHES), "Meshes:");
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_LOADTIME), "Time:");
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
FillDefaultStatistics();
|
|
|
|
SetViewMode(VIEWMODE_FULL);
|
|
|
|
|
|
|
|
// for debugging
|
2020-04-07 14:56:22 +00:00
|
|
|
m_pcCurrentMaterial = nullptr;
|
|
|
|
m_pcCurrentTexture = nullptr;
|
|
|
|
m_pcCurrentNode = nullptr;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// redraw the color fields in the UI --- their purpose has possibly changed
|
|
|
|
UpdateColorFieldsInUI();
|
|
|
|
UpdateWindow(g_hDlg);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::OnSetupNodeView(NodeInfo *pcNew) {
|
2020-04-07 14:56:22 +00:00
|
|
|
ai_assert(nullptr != pcNew);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (m_pcCurrentNode == pcNew) return 2;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// now ... change the meaning of the statistics fields back
|
2020-11-11 18:38:42 +00:00
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMVERTS), "Vertices:");
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMFACES), "Faces:");
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMMATS), "Materials:");
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMMESHES), "Meshes:");
|
|
|
|
|
|
|
|
ShowWindow(GetDlgItem(g_hDlg, IDC_NUMNODES), SW_HIDE);
|
|
|
|
ShowWindow(GetDlgItem(g_hDlg, IDC_ENODEWND), SW_HIDE);
|
|
|
|
ShowWindow(GetDlgItem(g_hDlg, IDC_NUMSHADERS), SW_HIDE);
|
|
|
|
ShowWindow(GetDlgItem(g_hDlg, IDC_LOADTIME), SW_HIDE);
|
|
|
|
ShowWindow(GetDlgItem(g_hDlg, IDC_ESHADER), SW_HIDE);
|
|
|
|
ShowWindow(GetDlgItem(g_hDlg, IDC_ELOAD), SW_HIDE);
|
|
|
|
ShowWindow(GetDlgItem(g_hDlg, IDC_VIEWMATRIX), SW_SHOW);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
char szTemp[1024];
|
|
|
|
sprintf(szTemp,
|
2020-11-11 18:38:42 +00:00
|
|
|
"%.2f %.2f %.2f\r\n"
|
|
|
|
"%.2f %.2f %.2f\r\n"
|
|
|
|
"%.2f %.2f %.2f\r\n"
|
|
|
|
"%.2f %.2f %.2f\r\n",
|
|
|
|
pcNew->psNode->mTransformation.a1,
|
|
|
|
pcNew->psNode->mTransformation.b1,
|
|
|
|
pcNew->psNode->mTransformation.c1,
|
|
|
|
pcNew->psNode->mTransformation.a2,
|
|
|
|
pcNew->psNode->mTransformation.b2,
|
|
|
|
pcNew->psNode->mTransformation.c2,
|
|
|
|
pcNew->psNode->mTransformation.a3,
|
|
|
|
pcNew->psNode->mTransformation.b3,
|
|
|
|
pcNew->psNode->mTransformation.c3,
|
|
|
|
pcNew->psNode->mTransformation.a4,
|
|
|
|
pcNew->psNode->mTransformation.b4,
|
|
|
|
pcNew->psNode->mTransformation.c4);
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_VIEWMATRIX), szTemp);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
m_pcCurrentNode = pcNew;
|
|
|
|
SetViewMode(VIEWMODE_NODE);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::OnSetupMaterialView(MaterialInfo *pcNew) {
|
2020-04-07 14:56:22 +00:00
|
|
|
ai_assert(nullptr != pcNew);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (m_pcCurrentMaterial == pcNew) return 2;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
if (VIEWMODE_NODE == m_iViewMode)
|
|
|
|
ShowNormalUIComponents();
|
|
|
|
|
|
|
|
m_pcCurrentMaterial = pcNew;
|
|
|
|
SetViewMode(VIEWMODE_MATERIAL);
|
|
|
|
|
|
|
|
// redraw the color fields in the UI --- their purpose has possibly changed
|
|
|
|
UpdateColorFieldsInUI();
|
|
|
|
UpdateWindow(g_hDlg);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::OnSetupTextureView(TextureInfo *pcNew) {
|
2020-04-07 14:56:22 +00:00
|
|
|
ai_assert(nullptr != pcNew);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (this->m_pcCurrentTexture == pcNew) return 2;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (VIEWMODE_NODE == this->m_iViewMode) {
|
2015-06-30 02:54:59 +00:00
|
|
|
ShowNormalUIComponents();
|
|
|
|
}
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if ((aiTextureType_OPACITY | 0x40000000) == pcNew->iType) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// for opacity textures display a warn message
|
|
|
|
CLogDisplay::Instance().AddEntry("[INFO] This texture is not existing in the "
|
2020-11-11 18:38:42 +00:00
|
|
|
"original mesh",
|
|
|
|
D3DCOLOR_ARGB(0xFF, 0xFF, 0xFF, 0));
|
2015-06-30 02:54:59 +00:00
|
|
|
CLogDisplay::Instance().AddEntry("It is a copy of the alpha channel of the first "
|
2020-11-11 18:38:42 +00:00
|
|
|
"diffuse texture",
|
|
|
|
D3DCOLOR_ARGB(0xFF, 0xFF, 0xFF, 0));
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// check whether the pattern background effect is supported
|
2020-11-11 18:38:42 +00:00
|
|
|
if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(3, 0)) {
|
2015-06-30 02:54:59 +00:00
|
|
|
CLogDisplay::Instance().AddEntry("[WARN] The background shader won't work "
|
2020-11-11 18:38:42 +00:00
|
|
|
"on your system, it required PS 3.0 hardware. A default color is used ...",
|
|
|
|
D3DCOLOR_ARGB(0xFF, 0xFF, 0x00, 0));
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
this->m_fTextureZoom = 1000.0f;
|
|
|
|
this->m_vTextureOffset.x = this->m_vTextureOffset.y = 0.0f;
|
|
|
|
|
|
|
|
this->m_pcCurrentTexture = pcNew;
|
|
|
|
this->SetViewMode(VIEWMODE_TEXTURE);
|
|
|
|
|
|
|
|
// now ... change the meaning of the statistics fields
|
2020-11-11 18:38:42 +00:00
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMVERTS), "Width:");
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMNODES), "Height:");
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMFACES), "Format:");
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMSHADERS), "MIPs:");
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMMATS), "UV:");
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_NUMMESHES), "Blend:");
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_LOADTIME), "Op:");
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// and fill them with data
|
|
|
|
D3DSURFACE_DESC sDesc;
|
|
|
|
if (pcNew->piTexture && *pcNew->piTexture) {
|
2020-11-11 18:38:42 +00:00
|
|
|
(*pcNew->piTexture)->GetLevelDesc(0, &sDesc);
|
2015-06-30 02:54:59 +00:00
|
|
|
char szTemp[128];
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
sprintf(szTemp, "%i", sDesc.Width);
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_EVERT), szTemp);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
sprintf(szTemp, "%i", sDesc.Height);
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_ENODEWND), szTemp);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
sprintf(szTemp, "%i", (*pcNew->piTexture)->GetLevelCount());
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_ESHADER), szTemp);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
sprintf(szTemp, "%u", pcNew->iUV);
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_EMAT), szTemp);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
sprintf(szTemp, "%f", pcNew->fBlend);
|
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_EMESH), szTemp);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
const char *szOp;
|
|
|
|
switch (pcNew->eOp) {
|
2015-06-30 02:54:59 +00:00
|
|
|
case aiTextureOp_Add:
|
2018-05-09 07:51:05 +00:00
|
|
|
szOp = "add";
|
|
|
|
break;
|
2015-06-30 02:54:59 +00:00
|
|
|
case aiTextureOp_Subtract:
|
2018-05-09 07:51:05 +00:00
|
|
|
szOp = "sub";
|
|
|
|
break;
|
2015-06-30 02:54:59 +00:00
|
|
|
case aiTextureOp_Divide:
|
2018-05-09 07:51:05 +00:00
|
|
|
szOp = "div";
|
|
|
|
break;
|
2015-06-30 02:54:59 +00:00
|
|
|
case aiTextureOp_SignedAdd:
|
2018-05-09 07:51:05 +00:00
|
|
|
szOp = "addsign";
|
|
|
|
break;
|
2015-06-30 02:54:59 +00:00
|
|
|
case aiTextureOp_SmoothAdd:
|
2018-05-09 07:51:05 +00:00
|
|
|
szOp = "addsmooth";
|
|
|
|
break;
|
2020-11-11 18:38:42 +00:00
|
|
|
default:
|
2018-05-09 07:51:05 +00:00
|
|
|
szOp = "mul";
|
|
|
|
break;
|
2015-06-30 02:54:59 +00:00
|
|
|
};
|
2020-11-11 18:38:42 +00:00
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_ELOAD), szOp);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// NOTE: Format is always ARGB8888 since other formats are
|
|
|
|
// converted to this format ...
|
2020-11-11 18:38:42 +00:00
|
|
|
SetWindowText(GetDlgItem(g_hDlg, IDC_EFACE), "ARGB8");
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// check whether this is the default texture
|
2020-11-11 18:38:42 +00:00
|
|
|
if (pcNew->piTexture) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// {9785DA94-1D96-426b-B3CB-BADC36347F5E}
|
2020-11-11 18:38:42 +00:00
|
|
|
static const GUID guidPrivateData = { 0x9785da94, 0x1d96, 0x426b,
|
|
|
|
{ 0xb3, 0xcb, 0xba, 0xdc, 0x36, 0x34, 0x7f, 0x5e } };
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
uint32_t iData = 0;
|
|
|
|
DWORD dwSize = 4;
|
2020-11-11 18:38:42 +00:00
|
|
|
(*pcNew->piTexture)->GetPrivateData(guidPrivateData, &iData, &dwSize);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (0xFFFFFFFF == iData) {
|
2015-06-30 02:54:59 +00:00
|
|
|
CLogDisplay::Instance().AddEntry("[ERROR] Texture could not be loaded. "
|
2020-11-11 18:38:42 +00:00
|
|
|
"The displayed texture is a default texture",
|
|
|
|
D3DCOLOR_ARGB(0xFF, 0xFF, 0, 0));
|
2015-06-30 02:54:59 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// redraw the color fields in the UI --- their purpose has possibly changed
|
|
|
|
UpdateColorFieldsInUI();
|
|
|
|
UpdateWindow(g_hDlg);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::OnSetup(HTREEITEM p_hTreeItem) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// search in our list for the item
|
2020-11-11 18:38:42 +00:00
|
|
|
union {
|
|
|
|
TextureInfo *pcNew;
|
|
|
|
NodeInfo *pcNew2;
|
|
|
|
MaterialInfo *pcNew3;
|
2015-06-30 02:54:59 +00:00
|
|
|
};
|
|
|
|
|
2020-04-07 14:56:22 +00:00
|
|
|
pcNew = nullptr;
|
2020-11-11 18:38:42 +00:00
|
|
|
for (std::vector<TextureInfo>::iterator i = m_asTextures.begin(); i != m_asTextures.end(); ++i) {
|
|
|
|
if (p_hTreeItem == (*i).hTreeItem) {
|
2015-06-30 02:54:59 +00:00
|
|
|
pcNew = &(*i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
if (pcNew) {
|
2015-06-30 02:54:59 +00:00
|
|
|
return OnSetupTextureView(pcNew);
|
|
|
|
}
|
|
|
|
|
2016-04-03 00:38:00 +00:00
|
|
|
// search the node list
|
2020-11-11 18:38:42 +00:00
|
|
|
for (std::vector<NodeInfo>::iterator i = m_asNodes.begin(); i != m_asNodes.end(); ++i) {
|
|
|
|
if (p_hTreeItem == (*i).hTreeItem) {
|
2015-06-30 02:54:59 +00:00
|
|
|
pcNew2 = &(*i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (pcNew2) {
|
|
|
|
return OnSetupNodeView(pcNew2);
|
|
|
|
}
|
|
|
|
|
2016-04-03 00:38:00 +00:00
|
|
|
// search the material list
|
2020-11-11 18:38:42 +00:00
|
|
|
for (std::vector<MaterialInfo>::iterator i = m_asMaterials.begin(); i != m_asMaterials.end(); ++i) {
|
|
|
|
if (p_hTreeItem == (*i).hTreeItem) {
|
2015-06-30 02:54:59 +00:00
|
|
|
pcNew3 = &(*i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (pcNew3) {
|
|
|
|
return OnSetupMaterialView(pcNew3);
|
|
|
|
}
|
|
|
|
return OnSetupNormalView();
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::ShowTreeViewContextMenu(HTREEITEM hItem) {
|
2020-04-07 14:56:22 +00:00
|
|
|
ai_assert(nullptr != hItem);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-04-07 14:56:22 +00:00
|
|
|
HMENU hDisplay = nullptr;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// search in our list for the item
|
2020-11-11 18:38:42 +00:00
|
|
|
TextureInfo *pcNew = nullptr;
|
2015-06-30 02:54:59 +00:00
|
|
|
for (std::vector<TextureInfo>::iterator
|
2020-11-11 18:38:42 +00:00
|
|
|
i = m_asTextures.begin();
|
|
|
|
i != m_asTextures.end(); ++i) {
|
|
|
|
if (hItem == (*i).hTreeItem) {
|
2015-06-30 02:54:59 +00:00
|
|
|
pcNew = &(*i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
if (pcNew) {
|
|
|
|
HMENU hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_TXPOPUP));
|
|
|
|
hDisplay = GetSubMenu(hMenu, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// search in the material list for the item
|
2020-11-11 18:38:42 +00:00
|
|
|
MaterialInfo *pcNew2 = nullptr;
|
2015-06-30 02:54:59 +00:00
|
|
|
for (std::vector<MaterialInfo>::iterator
|
2020-11-11 18:38:42 +00:00
|
|
|
i = m_asMaterials.begin();
|
|
|
|
i != m_asMaterials.end(); ++i) {
|
|
|
|
if (hItem == (*i).hTreeItem) {
|
2015-06-30 02:54:59 +00:00
|
|
|
pcNew2 = &(*i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
if (pcNew2) {
|
|
|
|
HMENU hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_MATPOPUP));
|
|
|
|
hDisplay = GetSubMenu(hMenu, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
if (nullptr != hDisplay) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// select this entry (this should all OnSetup())
|
2020-11-11 18:38:42 +00:00
|
|
|
TreeView_Select(GetDlgItem(g_hDlg, IDC_TREE1), hItem, TVGN_CARET);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// FIX: Render the scene once that the correct texture/material
|
|
|
|
// is displayed while the context menu is active
|
|
|
|
OnRender();
|
|
|
|
|
|
|
|
POINT sPoint;
|
|
|
|
GetCursorPos(&sPoint);
|
|
|
|
TrackPopupMenu(hDisplay, TPM_LEFTALIGN, sPoint.x, sPoint.y, 0,
|
2020-11-11 18:38:42 +00:00
|
|
|
g_hDlg, nullptr);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::HandleTreeViewPopup(WPARAM wParam, LPARAM lParam) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// get the current selected material
|
|
|
|
std::vector<Info> apclrOut;
|
2020-11-11 18:38:42 +00:00
|
|
|
const char *szMatKey = "";
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
switch (LOWORD(wParam)) {
|
2015-06-30 02:54:59 +00:00
|
|
|
case ID_SOLONG_CLEARDIFFUSECOLOR:
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) {
|
|
|
|
if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) {
|
|
|
|
apclrOut.push_back(Info(&g_pcAsset->apcMeshes[i]->vDiffuseColor,
|
|
|
|
g_pcAsset->apcMeshes[i], "DIFFUSE_COLOR"));
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
szMatKey = "$clr.diffuse";
|
|
|
|
break;
|
|
|
|
case ID_SOLONG_CLEARSPECULARCOLOR:
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) {
|
|
|
|
if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) {
|
|
|
|
apclrOut.push_back(Info(&g_pcAsset->apcMeshes[i]->vSpecularColor,
|
|
|
|
g_pcAsset->apcMeshes[i], "SPECULAR_COLOR"));
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
szMatKey = "$clr.specular";
|
|
|
|
break;
|
|
|
|
case ID_SOLONG_CLEARAMBIENTCOLOR:
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) {
|
|
|
|
if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) {
|
|
|
|
apclrOut.push_back(Info(&g_pcAsset->apcMeshes[i]->vAmbientColor,
|
|
|
|
g_pcAsset->apcMeshes[i], "AMBIENT_COLOR"));
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
szMatKey = "$clr.ambient";
|
|
|
|
break;
|
|
|
|
case ID_SOLONG_CLEAREMISSIVECOLOR:
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) {
|
|
|
|
if (this->m_pcCurrentMaterial->iIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) {
|
|
|
|
apclrOut.push_back(Info(&g_pcAsset->apcMeshes[i]->vEmissiveColor,
|
|
|
|
g_pcAsset->apcMeshes[i], "EMISSIVE_COLOR"));
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
szMatKey = "$clr.emissive";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
|
|
|
|
// let the next function do this ... no spaghetti code ;-)
|
2020-11-11 18:38:42 +00:00
|
|
|
HandleTreeViewPopup2(wParam, lParam);
|
2015-06-30 02:54:59 +00:00
|
|
|
};
|
2020-11-11 18:38:42 +00:00
|
|
|
if (!apclrOut.empty()) {
|
|
|
|
aiColor4D clrOld = *((aiColor4D *)(apclrOut.front().pclrColor));
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
CHOOSECOLOR clr;
|
|
|
|
clr.lStructSize = sizeof(CHOOSECOLOR);
|
|
|
|
clr.hwndOwner = g_hDlg;
|
|
|
|
clr.Flags = CC_RGBINIT | CC_FULLOPEN;
|
|
|
|
clr.rgbResult = RGB(
|
2020-11-11 18:38:42 +00:00
|
|
|
clamp<unsigned char>(clrOld.r * 255.0f),
|
|
|
|
clamp<unsigned char>(clrOld.g * 255.0f),
|
|
|
|
clamp<unsigned char>(clrOld.b * 255.0f));
|
2015-06-30 02:54:59 +00:00
|
|
|
clr.lpCustColors = g_aclCustomColors;
|
2020-04-07 14:56:22 +00:00
|
|
|
clr.lpfnHook = nullptr;
|
|
|
|
clr.lpTemplateName = nullptr;
|
2015-06-30 02:54:59 +00:00
|
|
|
clr.lCustData = 0;
|
|
|
|
|
|
|
|
ChooseColor(&clr);
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
clrOld.r = (float)(((unsigned int)clr.rgbResult) & 0xFF) / 255.0f;
|
|
|
|
clrOld.g = (float)(((unsigned int)clr.rgbResult >> 8) & 0xFF) / 255.0f;
|
2015-06-30 02:54:59 +00:00
|
|
|
clrOld.b = (float)(((unsigned int)clr.rgbResult >> 16) & 0xFF) / 255.0f;
|
|
|
|
|
|
|
|
// update the color values in the mesh instances and
|
|
|
|
// update all shaders ...
|
|
|
|
for (std::vector<Info>::iterator
|
2020-11-11 18:38:42 +00:00
|
|
|
i = apclrOut.begin();
|
|
|
|
i != apclrOut.end(); ++i) {
|
|
|
|
*((*i).pclrColor) = *((D3DXVECTOR4 *)&clrOld);
|
|
|
|
if (!(*i).pMesh->bSharedFX) {
|
|
|
|
(*i).pMesh->piEffect->SetVector((*i).szShaderParam, (*i).pclrColor);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// change the material key ...
|
2020-11-11 18:38:42 +00:00
|
|
|
aiMaterial *pcMat = (aiMaterial *)g_pcAsset->pcScene->mMaterials[this->m_pcCurrentMaterial->iIndex];
|
|
|
|
pcMat->AddProperty<aiColor4D>(&clrOld, 1, szMatKey, 0, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
if (ID_SOLONG_CLEARSPECULARCOLOR == LOWORD(wParam) &&
|
2020-11-11 18:38:42 +00:00
|
|
|
aiShadingMode_Gouraud == apclrOut.front().pMesh->eShadingMode) {
|
2015-06-30 02:54:59 +00:00
|
|
|
CLogDisplay::Instance().AddEntry("[INFO] You have just changed the specular "
|
2020-11-11 18:38:42 +00:00
|
|
|
"material color",
|
|
|
|
D3DCOLOR_ARGB(0xFF, 0xFF, 0xFF, 0));
|
2015-06-30 02:54:59 +00:00
|
|
|
CLogDisplay::Instance().AddEntry(
|
2020-11-11 18:38:42 +00:00
|
|
|
"This is great, especially since there is currently no specular shading",
|
|
|
|
D3DCOLOR_ARGB(0xFF, 0xFF, 0xFF, 0));
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
int CALLBACK TreeViewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) {
|
|
|
|
if (lParamSort == lParam1) return -1;
|
|
|
|
if (lParamSort == lParam2) return 1;
|
2015-06-30 02:54:59 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::HandleTreeViewPopup2(WPARAM wParam, LPARAM /*lParam*/) {
|
2015-06-30 02:54:59 +00:00
|
|
|
char szFileName[MAX_PATH];
|
|
|
|
DWORD dwTemp = MAX_PATH;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
switch (LOWORD(wParam)) {
|
|
|
|
case ID_HEY_REPLACE: {
|
2015-06-30 02:54:59 +00:00
|
|
|
// get a path to a new texture
|
2020-11-11 18:38:42 +00:00
|
|
|
if (ERROR_SUCCESS != RegQueryValueEx(g_hRegistry, "ReplaceTextureSrc", nullptr, nullptr,
|
|
|
|
(BYTE *)szFileName, &dwTemp)) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// Key was not found. Use C:
|
2020-11-11 18:38:42 +00:00
|
|
|
strcpy(szFileName, "");
|
|
|
|
} else {
|
2015-06-30 02:54:59 +00:00
|
|
|
// need to remove the file name
|
2020-11-11 18:38:42 +00:00
|
|
|
char *sz = strrchr(szFileName, '\\');
|
2015-07-02 11:50:21 +00:00
|
|
|
if (!sz)
|
2020-11-11 18:38:42 +00:00
|
|
|
sz = strrchr(szFileName, '/');
|
2015-07-02 11:50:21 +00:00
|
|
|
if (sz)
|
|
|
|
*sz = 0;
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
OPENFILENAME sFilename1 = {
|
|
|
|
sizeof(OPENFILENAME),
|
2020-11-11 18:38:42 +00:00
|
|
|
g_hDlg, GetModuleHandle(nullptr),
|
2015-06-30 02:54:59 +00:00
|
|
|
"Textures\0*.png;*.dds;*.tga;*.bmp;*.tif;*.ppm;*.ppx;*.jpg;*.jpeg;*.exr\0*.*\0",
|
2020-04-07 14:56:22 +00:00
|
|
|
nullptr, 0, 1,
|
|
|
|
szFileName, MAX_PATH, nullptr, 0, nullptr,
|
2015-06-30 02:54:59 +00:00
|
|
|
"Replace this texture",
|
|
|
|
OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
|
2020-04-07 14:56:22 +00:00
|
|
|
0, 1, ".jpg", 0, nullptr, nullptr
|
2015-06-30 02:54:59 +00:00
|
|
|
};
|
2020-11-11 18:38:42 +00:00
|
|
|
if (GetOpenFileName(&sFilename1) == 0) return 0;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// Now store the file in the registry
|
2020-11-11 18:38:42 +00:00
|
|
|
RegSetValueExA(g_hRegistry, "ReplaceTextureSrc", 0, REG_SZ, (const BYTE *)szFileName, MAX_PATH);
|
2015-06-30 02:54:59 +00:00
|
|
|
this->ReplaceCurrentTexture(szFileName);
|
2020-11-11 18:38:42 +00:00
|
|
|
}
|
2015-06-30 02:54:59 +00:00
|
|
|
return 1;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
case ID_HEY_EXPORT: {
|
|
|
|
if (ERROR_SUCCESS != RegQueryValueEx(g_hRegistry, "TextureExportDest", nullptr, nullptr,
|
|
|
|
(BYTE *)szFileName, &dwTemp)) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// Key was not found. Use C:
|
2020-11-11 18:38:42 +00:00
|
|
|
strcpy(szFileName, "");
|
|
|
|
} else {
|
2015-06-30 02:54:59 +00:00
|
|
|
// need to remove the file name
|
2020-11-11 18:38:42 +00:00
|
|
|
char *sz = strrchr(szFileName, '\\');
|
2015-07-02 11:50:21 +00:00
|
|
|
if (!sz)
|
2020-11-11 18:38:42 +00:00
|
|
|
sz = strrchr(szFileName, '/');
|
2015-07-02 11:50:21 +00:00
|
|
|
if (sz)
|
|
|
|
*sz = 0;
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
OPENFILENAME sFilename1 = {
|
|
|
|
sizeof(OPENFILENAME),
|
2020-11-11 18:38:42 +00:00
|
|
|
g_hDlg, GetModuleHandle(nullptr),
|
2020-04-07 14:56:22 +00:00
|
|
|
"Textures\0*.png;*.dds;*.bmp;*.tif;*.pfm;*.jpg;*.jpeg;*.hdr\0*.*\0", nullptr, 0, 1,
|
|
|
|
szFileName, MAX_PATH, nullptr, 0, nullptr,
|
2015-06-30 02:54:59 +00:00
|
|
|
"Export texture to file",
|
|
|
|
OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_NOCHANGEDIR,
|
2020-04-07 14:56:22 +00:00
|
|
|
0, 1, ".png", 0, nullptr, nullptr
|
2015-06-30 02:54:59 +00:00
|
|
|
};
|
2020-11-11 18:38:42 +00:00
|
|
|
if (GetSaveFileName(&sFilename1) == 0) return 0;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// Now store the file in the registry
|
2020-11-11 18:38:42 +00:00
|
|
|
RegSetValueExA(g_hRegistry, "TextureExportDest", 0, REG_SZ, (const BYTE *)szFileName, MAX_PATH);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// determine the file format ...
|
|
|
|
D3DXIMAGE_FILEFORMAT eFormat = D3DXIFF_PNG;
|
2020-11-11 18:38:42 +00:00
|
|
|
const char *sz = strrchr(szFileName, '.');
|
|
|
|
if (sz) {
|
2015-06-30 02:54:59 +00:00
|
|
|
++sz;
|
2020-11-11 18:38:42 +00:00
|
|
|
if (0 == Assimp::ASSIMP_stricmp(sz, "pfm"))
|
|
|
|
eFormat = D3DXIFF_PFM;
|
|
|
|
else if (0 == Assimp::ASSIMP_stricmp(sz, "dds"))
|
|
|
|
eFormat = D3DXIFF_DDS;
|
|
|
|
else if (0 == Assimp::ASSIMP_stricmp(sz, "jpg"))
|
|
|
|
eFormat = D3DXIFF_JPG;
|
|
|
|
else if (0 == Assimp::ASSIMP_stricmp(sz, "jpeg"))
|
|
|
|
eFormat = D3DXIFF_JPG;
|
|
|
|
else if (0 == Assimp::ASSIMP_stricmp(sz, "hdr"))
|
|
|
|
eFormat = D3DXIFF_HDR;
|
|
|
|
else if (0 == Assimp::ASSIMP_stricmp(sz, "bmp"))
|
|
|
|
eFormat = D3DXIFF_BMP;
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// get a pointer to the first surface of the current texture
|
2020-11-11 18:38:42 +00:00
|
|
|
IDirect3DSurface9 *pi = nullptr;
|
|
|
|
(*this->m_pcCurrentTexture->piTexture)->GetSurfaceLevel(0, &pi);
|
|
|
|
if (!pi || FAILED(D3DXSaveSurfaceToFile(szFileName, eFormat, pi, nullptr, nullptr))) {
|
2015-06-30 02:54:59 +00:00
|
|
|
CLogDisplay::Instance().AddEntry("[ERROR] Unable to export texture",
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DCOLOR_ARGB(0xFF, 0xFF, 0, 0));
|
|
|
|
} else {
|
2015-06-30 02:54:59 +00:00
|
|
|
CLogDisplay::Instance().AddEntry("[INFO] The texture has been exported",
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DCOLOR_ARGB(0xFF, 0xFF, 0xFF, 0));
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
if (pi) pi->Release();
|
|
|
|
}
|
2015-06-30 02:54:59 +00:00
|
|
|
return 1;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
case ID_HEY_REMOVE: {
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (IDYES != MessageBox(g_hDlg, "To recover the texture you need to reload the model. Do you wish to continue?",
|
|
|
|
"Remove texture", MB_YESNO)) {
|
2015-06-30 02:54:59 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
aiMaterial *pcMat = (aiMaterial *)g_pcAsset->pcScene->mMaterials[m_pcCurrentTexture->iMatIndex];
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
unsigned int s;
|
2020-11-11 18:38:42 +00:00
|
|
|
if (m_pcCurrentTexture->iType == (aiTextureType_OPACITY | 0x40000000)) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// set a special property to indicate that no alpha channel is required
|
|
|
|
int iVal = 1;
|
2020-11-11 18:38:42 +00:00
|
|
|
pcMat->AddProperty<int>(&iVal, 1, "no_a_from_d", 0, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
s = aiTextureType_OPACITY;
|
2020-11-11 18:38:42 +00:00
|
|
|
} else
|
|
|
|
s = m_pcCurrentTexture->iType;
|
|
|
|
pcMat->RemoveProperty(AI_MATKEY_TEXTURE(m_pcCurrentTexture->iType, 0));
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// need to update all meshes associated with this material
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes; ++i) {
|
|
|
|
if (m_pcCurrentTexture->iMatIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) {
|
2015-06-30 02:54:59 +00:00
|
|
|
CMaterialManager::Instance().DeleteMaterial(g_pcAsset->apcMeshes[i]);
|
2020-11-11 18:38:42 +00:00
|
|
|
CMaterialManager::Instance().CreateMaterial(g_pcAsset->apcMeshes[i], g_pcAsset->pcScene->mMeshes[i]);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// find the corresponding MaterialInfo structure
|
|
|
|
const unsigned int iMatIndex = m_pcCurrentTexture->iMatIndex;
|
|
|
|
for (std::vector<MaterialInfo>::iterator
|
2020-11-11 18:38:42 +00:00
|
|
|
a = m_asMaterials.begin();
|
|
|
|
a != m_asMaterials.end(); ++a) {
|
|
|
|
if (iMatIndex == (*a).iIndex) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// good news. we will also need to find all other textures
|
|
|
|
// associated with this item ...
|
|
|
|
for (std::vector<TextureInfo>::iterator
|
2020-11-11 18:38:42 +00:00
|
|
|
n = m_asTextures.begin();
|
|
|
|
n != m_asTextures.end(); ++n) {
|
|
|
|
if ((*n).iMatIndex == iMatIndex) {
|
|
|
|
n = m_asTextures.erase(n);
|
|
|
|
if (m_asTextures.end() == n) break;
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// delete this material from all lists ...
|
2020-11-11 18:38:42 +00:00
|
|
|
TreeView_DeleteItem(GetDlgItem(g_hDlg, IDC_TREE1), (*a).hTreeItem);
|
2015-06-30 02:54:59 +00:00
|
|
|
this->m_asMaterials.erase(a);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// add the new material to the list and make sure it will be fully expanded
|
2020-11-11 18:38:42 +00:00
|
|
|
AddMaterialToDisplayList(m_hRoot, iMatIndex);
|
2015-06-30 02:54:59 +00:00
|
|
|
HTREEITEM hNewItem = m_asMaterials.back().hTreeItem;
|
2020-11-11 18:38:42 +00:00
|
|
|
TreeView_Expand(GetDlgItem(g_hDlg, IDC_TREE1), hNewItem, TVE_EXPAND);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// we need to sort the list, materials come first, then nodes
|
|
|
|
TVSORTCB sSort;
|
|
|
|
sSort.hParent = m_hRoot;
|
|
|
|
sSort.lParam = 10;
|
|
|
|
sSort.lpfnCompare = &TreeViewCompareFunc;
|
2020-11-11 18:38:42 +00:00
|
|
|
TreeView_SortChildrenCB(GetDlgItem(g_hDlg, IDC_TREE1), &sSort, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// the texture was selected, but the silly user has just deleted it
|
|
|
|
// ... go back to normal viewing mode
|
2020-11-11 18:38:42 +00:00
|
|
|
TreeView_Select(GetDlgItem(g_hDlg, IDC_TREE1), m_hRoot, TVGN_CARET);
|
2015-06-30 02:54:59 +00:00
|
|
|
return 1;
|
2020-11-11 18:38:42 +00:00
|
|
|
}
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Setup stereo view
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::SetupStereoView() {
|
|
|
|
if (nullptr != g_pcAsset && nullptr != g_pcAsset->pcScene->mRootNode) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// enable the RED, GREEN and ALPHA channels
|
|
|
|
g_piDevice->SetRenderState(D3DRS_COLORWRITEENABLE,
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DCOLORWRITEENABLE_RED |
|
|
|
|
D3DCOLORWRITEENABLE_ALPHA |
|
|
|
|
D3DCOLORWRITEENABLE_GREEN);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// move the camera a little bit to the left
|
|
|
|
g_sCamera.vPos -= g_sCamera.vRight * 0.03f;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Do the actual rendering pass for the stereo view
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::RenderStereoView(const aiMatrix4x4 &m) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// and rerender the scene
|
2020-11-11 18:38:42 +00:00
|
|
|
if (nullptr != g_pcAsset && nullptr != g_pcAsset->pcScene->mRootNode) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// enable the BLUE, GREEN and ALPHA channels
|
|
|
|
g_piDevice->SetRenderState(D3DRS_COLORWRITEENABLE,
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DCOLORWRITEENABLE_GREEN |
|
|
|
|
D3DCOLORWRITEENABLE_ALPHA |
|
|
|
|
D3DCOLORWRITEENABLE_BLUE);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// clear the z-buffer
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->Clear(0, nullptr, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// move the camera a little bit to the right
|
|
|
|
g_sCamera.vPos += g_sCamera.vRight * 0.06f;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
RenderNode(g_pcAsset->pcScene->mRootNode, m, false);
|
|
|
|
g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
|
|
|
RenderNode(g_pcAsset->pcScene->mRootNode, m, true);
|
|
|
|
g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// (move back to the original position)
|
|
|
|
g_sCamera.vPos -= g_sCamera.vRight * 0.03f;
|
|
|
|
|
|
|
|
// reenable all channels
|
|
|
|
g_piDevice->SetRenderState(D3DRS_COLORWRITEENABLE,
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DCOLORWRITEENABLE_RED |
|
|
|
|
D3DCOLORWRITEENABLE_GREEN |
|
|
|
|
D3DCOLORWRITEENABLE_ALPHA |
|
|
|
|
D3DCOLORWRITEENABLE_BLUE);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Process input for the texture view
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::HandleInputTextureView() {
|
2015-06-30 02:54:59 +00:00
|
|
|
HandleMouseInputTextureView();
|
|
|
|
HandleKeyboardInputTextureView();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Get input for the current state
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::HandleInput() {
|
|
|
|
if (CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode())
|
2015-06-30 02:54:59 +00:00
|
|
|
HandleMouseInputSkyBox();
|
|
|
|
|
|
|
|
// handle input commands
|
|
|
|
HandleMouseInputLightRotate();
|
|
|
|
HandleMouseInputLightIntensityAndColor();
|
2020-11-11 18:38:42 +00:00
|
|
|
if (g_bFPSView) {
|
2015-06-30 02:54:59 +00:00
|
|
|
HandleMouseInputFPS();
|
|
|
|
HandleKeyboardInputFPS();
|
2020-11-11 18:38:42 +00:00
|
|
|
} else
|
|
|
|
HandleMouseInputLocal();
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// compute auto rotation depending on the time which has passed
|
2020-11-11 18:38:42 +00:00
|
|
|
if (g_sOptions.bRotate) {
|
2015-06-30 02:54:59 +00:00
|
|
|
aiMatrix4x4 mMat;
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DXMatrixRotationYawPitchRoll((D3DXMATRIX *)&mMat,
|
|
|
|
g_vRotateSpeed.x * g_fElpasedTime,
|
|
|
|
g_vRotateSpeed.y * g_fElpasedTime,
|
|
|
|
g_vRotateSpeed.z * g_fElpasedTime);
|
2015-06-30 02:54:59 +00:00
|
|
|
g_mWorldRotate = g_mWorldRotate * mMat;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle rotations of light source(s)
|
2020-11-11 18:38:42 +00:00
|
|
|
if (g_sOptions.bLightRotate) {
|
2015-06-30 02:54:59 +00:00
|
|
|
aiMatrix4x4 mMat;
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DXMatrixRotationYawPitchRoll((D3DXMATRIX *)&mMat,
|
|
|
|
g_vRotateSpeed.x * g_fElpasedTime * 0.5f,
|
|
|
|
g_vRotateSpeed.y * g_fElpasedTime * 0.5f,
|
|
|
|
g_vRotateSpeed.z * g_fElpasedTime * 0.5f);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DXVec3TransformNormal((D3DXVECTOR3 *)&g_avLightDirs[0],
|
|
|
|
(D3DXVECTOR3 *)&g_avLightDirs[0], (D3DXMATRIX *)&mMat);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
g_avLightDirs[0].Normalize();
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
2018-05-31 18:15:13 +00:00
|
|
|
// Process input for an empty scene view to allow for sky-box rotations
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::HandleInputEmptyScene() {
|
|
|
|
if (CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode()) {
|
|
|
|
if (g_bFPSView) {
|
2015-06-30 02:54:59 +00:00
|
|
|
HandleMouseInputFPS();
|
|
|
|
HandleKeyboardInputFPS();
|
|
|
|
}
|
|
|
|
HandleMouseInputSkyBox();
|
|
|
|
|
|
|
|
// need to store the last mouse position in the global variable
|
|
|
|
// HandleMouseInputFPS() is doing this internally
|
2020-11-11 18:38:42 +00:00
|
|
|
if (!g_bFPSView) {
|
2015-06-30 02:54:59 +00:00
|
|
|
g_LastmousePos.x = g_mousePos.x;
|
|
|
|
g_LastmousePos.y = g_mousePos.y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Draw the HUD on top of the scene
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::DrawHUD() {
|
|
|
|
// HACK: (thom) can't get the effect to work on non-shader cards, therefore deactivated for the moment
|
|
|
|
if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(2, 0))
|
|
|
|
return 1;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// get the dimension of the back buffer
|
|
|
|
RECT sRect;
|
2020-11-11 18:38:42 +00:00
|
|
|
GetWindowRect(GetDlgItem(g_hDlg, IDC_RT), &sRect);
|
2015-06-30 02:54:59 +00:00
|
|
|
sRect.right -= sRect.left;
|
|
|
|
sRect.bottom -= sRect.top;
|
|
|
|
|
|
|
|
// commit the texture to the shader
|
|
|
|
// FIX: Necessary because the texture view is also using this shader
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piPassThroughEffect->SetTexture("TEXTURE_2D", g_pcTexture);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// NOTE: The shader might be used for other purposes, too.
|
|
|
|
// So ensure the right technique is there
|
2020-11-11 18:38:42 +00:00
|
|
|
if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(2, 0))
|
|
|
|
g_piPassThroughEffect->SetTechnique("PassThrough_FF");
|
2015-06-30 02:54:59 +00:00
|
|
|
else
|
|
|
|
g_piPassThroughEffect->SetTechnique("PassThrough");
|
|
|
|
|
|
|
|
// build vertices for drawing from system memory
|
|
|
|
UINT dw;
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piPassThroughEffect->Begin(&dw, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
g_piPassThroughEffect->BeginPass(0);
|
|
|
|
|
|
|
|
D3DSURFACE_DESC sDesc;
|
2020-11-11 18:38:42 +00:00
|
|
|
g_pcTexture->GetLevelDesc(0, &sDesc);
|
2015-06-30 02:54:59 +00:00
|
|
|
SVertex as[4];
|
2020-11-11 18:38:42 +00:00
|
|
|
float fHalfX = ((float)sRect.right - (float)sDesc.Width) / 2.0f;
|
|
|
|
float fHalfY = ((float)sRect.bottom - (float)sDesc.Height) / 2.0f;
|
2015-06-30 02:54:59 +00:00
|
|
|
as[1].x = fHalfX;
|
|
|
|
as[1].y = fHalfY;
|
|
|
|
as[1].z = 0.2f;
|
|
|
|
as[1].w = 1.0f;
|
|
|
|
as[1].u = 0.0f;
|
|
|
|
as[1].v = 0.0f;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
as[3].x = (float)sRect.right - fHalfX;
|
2015-06-30 02:54:59 +00:00
|
|
|
as[3].y = fHalfY;
|
|
|
|
as[3].z = 0.2f;
|
|
|
|
as[3].w = 1.0f;
|
|
|
|
as[3].u = 1.0f;
|
|
|
|
as[3].v = 0.0f;
|
|
|
|
|
|
|
|
as[0].x = fHalfX;
|
2020-11-11 18:38:42 +00:00
|
|
|
as[0].y = (float)sRect.bottom - fHalfY;
|
2015-06-30 02:54:59 +00:00
|
|
|
as[0].z = 0.2f;
|
|
|
|
as[0].w = 1.0f;
|
|
|
|
as[0].u = 0.0f;
|
|
|
|
as[0].v = 1.0f;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
as[2].x = (float)sRect.right - fHalfX;
|
|
|
|
as[2].y = (float)sRect.bottom - fHalfY;
|
2015-06-30 02:54:59 +00:00
|
|
|
as[2].z = 0.2f;
|
|
|
|
as[2].w = 1.0f;
|
|
|
|
as[2].u = 1.0f;
|
|
|
|
as[2].v = 1.0f;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
as[0].x -= 0.5f;
|
|
|
|
as[1].x -= 0.5f;
|
|
|
|
as[2].x -= 0.5f;
|
|
|
|
as[3].x -= 0.5f;
|
|
|
|
as[0].y -= 0.5f;
|
|
|
|
as[1].y -= 0.5f;
|
|
|
|
as[2].y -= 0.5f;
|
|
|
|
as[3].y -= 0.5f;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
|
|
|
g_piDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// draw the screen-filling squad
|
2020-11-11 18:38:42 +00:00
|
|
|
DWORD dw2;
|
|
|
|
g_piDevice->GetFVF(&dw2);
|
2015-06-30 02:54:59 +00:00
|
|
|
g_piDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2,
|
|
|
|
&as, sizeof(SVertex));
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// end the effect and recover the old vertex format
|
|
|
|
g_piPassThroughEffect->EndPass();
|
|
|
|
g_piPassThroughEffect->End();
|
|
|
|
|
|
|
|
g_piDevice->SetFVF(dw2);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Render the full scene, all nodes
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::RenderFullScene() {
|
2015-06-30 02:54:59 +00:00
|
|
|
// reset the color index used for drawing normals
|
|
|
|
g_iCurrentColor = 0;
|
|
|
|
|
|
|
|
aiMatrix4x4 pcProj;
|
|
|
|
GetProjectionMatrix(pcProj);
|
|
|
|
|
|
|
|
vPos = GetCameraMatrix(mViewProjection);
|
|
|
|
mViewProjection = mViewProjection * pcProj;
|
|
|
|
|
|
|
|
// setup wireframe/solid rendering mode
|
|
|
|
if (g_sOptions.eDrawMode == RenderOptions::WIREFRAME)
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
|
|
|
|
else
|
|
|
|
g_piDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
if (g_sOptions.bCulling)
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
|
|
|
|
else
|
|
|
|
g_piDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// for high-quality mode, enable anisotropic texture filtering
|
|
|
|
if (g_sOptions.bLowQuality) {
|
2020-11-11 18:38:42 +00:00
|
|
|
for (DWORD d = 0; d < 8; ++d) {
|
|
|
|
g_piDevice->SetSamplerState(d, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
|
|
|
g_piDevice->SetSamplerState(d, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
|
|
|
g_piDevice->SetSamplerState(d, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
} else {
|
|
|
|
for (DWORD d = 0; d < 8; ++d) {
|
|
|
|
g_piDevice->SetSamplerState(d, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC);
|
|
|
|
g_piDevice->SetSamplerState(d, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
|
|
|
|
g_piDevice->SetSamplerState(d, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->SetSamplerState(d, D3DSAMP_MAXANISOTROPY, g_sCaps.MaxAnisotropy);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// draw the scene background (clear and texture 2d)
|
|
|
|
CBackgroundPainter::Instance().OnPreRender();
|
|
|
|
|
|
|
|
// setup the stereo view if necessary
|
|
|
|
if (g_sOptions.bStereoView)
|
|
|
|
SetupStereoView();
|
|
|
|
|
|
|
|
// draw all opaque objects in the scene
|
|
|
|
aiMatrix4x4 m;
|
2020-11-11 18:38:42 +00:00
|
|
|
if (nullptr != g_pcAsset && nullptr != g_pcAsset->pcScene->mRootNode) {
|
2015-06-30 02:54:59 +00:00
|
|
|
HandleInput();
|
2020-11-11 18:38:42 +00:00
|
|
|
m = g_mWorld * g_mWorldRotate;
|
|
|
|
RenderNode(g_pcAsset->pcScene->mRootNode, m, false);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// if a cube texture is loaded as background image, the user
|
|
|
|
// should be able to rotate it even if no asset is loaded
|
|
|
|
HandleInputEmptyScene();
|
|
|
|
|
|
|
|
// draw the scene background
|
|
|
|
CBackgroundPainter::Instance().OnPostRender();
|
|
|
|
|
|
|
|
// draw all non-opaque objects in the scene
|
2020-11-11 18:38:42 +00:00
|
|
|
if (nullptr != g_pcAsset && nullptr != g_pcAsset->pcScene->mRootNode) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// disable the z-buffer
|
|
|
|
if (!g_sOptions.bNoAlphaBlending) {
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
RenderNode(g_pcAsset->pcScene->mRootNode, m, true);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
if (!g_sOptions.bNoAlphaBlending) {
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// setup the stereo view if necessary
|
|
|
|
if (g_sOptions.bStereoView)
|
|
|
|
RenderStereoView(m);
|
|
|
|
|
|
|
|
// render the skeleton if necessary
|
2020-04-07 14:56:22 +00:00
|
|
|
if (g_sOptions.bSkeleton && nullptr != g_pcAsset && nullptr != g_pcAsset->pcScene->mRootNode) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// disable the z-buffer
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
if (g_sOptions.eDrawMode != RenderOptions::WIREFRAME) {
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->SetVertexDeclaration(gDefaultVertexDecl);
|
2015-06-30 02:54:59 +00:00
|
|
|
// this is very similar to the code in SetupMaterial()
|
2020-11-11 18:38:42 +00:00
|
|
|
ID3DXEffect *piEnd = g_piNormalsEffect;
|
2020-04-03 18:36:44 +00:00
|
|
|
aiMatrix4x4 pcProj2 = m * mViewProjection;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DXVECTOR4 vVector(1.f, 0.f, 0.f, 1.f);
|
|
|
|
piEnd->SetVector("OUTPUT_COLOR", &vVector);
|
|
|
|
piEnd->SetMatrix("WorldViewProjection", (const D3DXMATRIX *)&pcProj2);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
UINT dwPasses = 0;
|
2020-11-11 18:38:42 +00:00
|
|
|
piEnd->Begin(&dwPasses, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
piEnd->BeginPass(0);
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
RenderSkeleton(g_pcAsset->pcScene->mRootNode, m, m);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
piEnd->EndPass();
|
|
|
|
piEnd->End();
|
|
|
|
g_piDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
|
|
|
|
g_piDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// draw the HUD texture on top of the rendered scene using
|
|
|
|
// pre-projected vertices
|
|
|
|
if (!g_bFPSView && g_pcAsset && g_pcTexture)
|
|
|
|
DrawHUD();
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::RenderMaterialView() {
|
2015-06-30 02:54:59 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Render animation skeleton
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::RenderSkeleton(aiNode *piNode, const aiMatrix4x4 &piMatrix, const aiMatrix4x4 &parent) {
|
|
|
|
aiMatrix4x4 me = g_pcAsset->mAnimator->GetGlobalTransform(piNode);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
me.Transpose();
|
|
|
|
//me *= piMatrix;
|
|
|
|
|
|
|
|
if (piNode->mParent) {
|
|
|
|
AssetHelper::LineVertex data[2];
|
2020-11-11 18:38:42 +00:00
|
|
|
data[0].dColorDiffuse = data[1].dColorDiffuse = D3DCOLOR_ARGB(0xff, 0xff, 0, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
data[0].vPosition.x = parent.d1;
|
|
|
|
data[0].vPosition.y = parent.d2;
|
|
|
|
data[0].vPosition.z = parent.d3;
|
|
|
|
|
|
|
|
data[1].vPosition.x = me.d1;
|
|
|
|
data[1].vPosition.y = me.d2;
|
|
|
|
data[1].vPosition.z = me.d3;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, &data, sizeof(AssetHelper::LineVertex));
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// render all child nodes
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i < piNode->mNumChildren; ++i)
|
|
|
|
RenderSkeleton(piNode->mChildren[i], piMatrix, me);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
// Render a single node
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::RenderNode(aiNode *piNode, const aiMatrix4x4 &piMatrix,
|
|
|
|
bool bAlpha /*= false*/) {
|
|
|
|
aiMatrix4x4 aiMe = g_pcAsset->mAnimator->GetGlobalTransform(piNode);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
aiMe.Transpose();
|
|
|
|
aiMe *= piMatrix;
|
|
|
|
|
|
|
|
bool bChangedVM = false;
|
2020-11-11 18:38:42 +00:00
|
|
|
if (VIEWMODE_NODE == m_iViewMode && m_pcCurrentNode) {
|
|
|
|
if (piNode != m_pcCurrentNode->psNode) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// directly call our children
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i < piNode->mNumChildren; ++i)
|
|
|
|
RenderNode(piNode->mChildren[i], piMatrix, bAlpha);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
m_iViewMode = VIEWMODE_FULL;
|
|
|
|
bChangedVM = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
aiMatrix4x4 pcProj = aiMe * mViewProjection;
|
|
|
|
|
|
|
|
aiMatrix4x4 pcCam = aiMe;
|
|
|
|
pcCam.Inverse().Transpose();
|
|
|
|
|
|
|
|
// VERY UNOPTIMIZED, much stuff is redundant. Who cares?
|
2020-11-11 18:38:42 +00:00
|
|
|
if (!g_sOptions.bRenderMats && !bAlpha) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// this is very similar to the code in SetupMaterial()
|
2020-11-11 18:38:42 +00:00
|
|
|
ID3DXEffect *piEnd = g_piDefaultEffect;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// commit transformation matrices to the shader
|
|
|
|
piEnd->SetMatrix("WorldViewProjection",
|
2020-11-11 18:38:42 +00:00
|
|
|
(const D3DXMATRIX *)&pcProj);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
piEnd->SetMatrix("World", (const D3DXMATRIX *)&aiMe);
|
2015-06-30 02:54:59 +00:00
|
|
|
piEnd->SetMatrix("WorldInverseTranspose",
|
2020-11-11 18:38:42 +00:00
|
|
|
(const D3DXMATRIX *)&pcCam);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode()) {
|
2015-06-30 02:54:59 +00:00
|
|
|
pcCam = pcCam * pcProj;
|
2020-11-11 18:38:42 +00:00
|
|
|
piEnd->SetMatrix("ViewProj", (const D3DXMATRIX *)&pcCam);
|
2015-06-30 02:54:59 +00:00
|
|
|
pcCam.Inverse();
|
2020-11-11 18:38:42 +00:00
|
|
|
piEnd->SetMatrix("InvViewProj", (const D3DXMATRIX *)&pcCam);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// commit light colors and direction to the shader
|
|
|
|
D3DXVECTOR4 apcVec[5];
|
|
|
|
apcVec[0].x = g_avLightDirs[0].x;
|
|
|
|
apcVec[0].y = g_avLightDirs[0].y;
|
|
|
|
apcVec[0].z = g_avLightDirs[0].z;
|
|
|
|
apcVec[0].w = 0.0f;
|
|
|
|
apcVec[1].x = g_avLightDirs[0].x * -1.0f;
|
|
|
|
apcVec[1].y = g_avLightDirs[0].y * -1.0f;
|
|
|
|
apcVec[1].z = g_avLightDirs[0].z * -1.0f;
|
|
|
|
apcVec[1].w = 0.0f;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
D3DXVec4Normalize(&apcVec[0], &apcVec[0]);
|
|
|
|
D3DXVec4Normalize(&apcVec[1], &apcVec[1]);
|
|
|
|
piEnd->SetVectorArray("afLightDir", apcVec, 5);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
apcVec[0].x = ((g_avLightColors[0] >> 16) & 0xFF) / 255.0f;
|
|
|
|
apcVec[0].y = ((g_avLightColors[0] >> 8) & 0xFF) / 255.0f;
|
|
|
|
apcVec[0].z = ((g_avLightColors[0]) & 0xFF) / 255.0f;
|
|
|
|
apcVec[0].w = 1.0f;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (g_sOptions.b3Lights) {
|
2015-06-30 02:54:59 +00:00
|
|
|
apcVec[1].x = ((g_avLightColors[1] >> 16) & 0xFF) / 255.0f;
|
|
|
|
apcVec[1].y = ((g_avLightColors[1] >> 8) & 0xFF) / 255.0f;
|
|
|
|
apcVec[1].z = ((g_avLightColors[1]) & 0xFF) / 255.0f;
|
|
|
|
apcVec[1].w = 0.0f;
|
2020-11-11 18:38:42 +00:00
|
|
|
} else {
|
2015-06-30 02:54:59 +00:00
|
|
|
apcVec[1].x = 0.0f;
|
|
|
|
apcVec[1].y = 0.0f;
|
|
|
|
apcVec[1].z = 0.0f;
|
|
|
|
apcVec[1].w = 0.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
apcVec[0] *= g_fLightIntensity;
|
|
|
|
apcVec[1] *= g_fLightIntensity;
|
2020-11-11 18:38:42 +00:00
|
|
|
piEnd->SetVectorArray("afLightColor", apcVec, 5);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
apcVec[0].x = vPos.x;
|
|
|
|
apcVec[0].y = vPos.y;
|
|
|
|
apcVec[0].z = vPos.z;
|
2020-11-11 18:38:42 +00:00
|
|
|
piEnd->SetVector("vCameraPos", &apcVec[0]);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// setup the best technique
|
2020-11-11 18:38:42 +00:00
|
|
|
if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(2, 0)) {
|
|
|
|
g_piDefaultEffect->SetTechnique("DefaultFXSpecular_FF");
|
|
|
|
} else if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(3, 0) || g_sOptions.bLowQuality) {
|
2015-06-30 02:54:59 +00:00
|
|
|
if (g_sOptions.b3Lights)
|
|
|
|
piEnd->SetTechnique("DefaultFXSpecular_PS20_D2");
|
2020-11-11 18:38:42 +00:00
|
|
|
else
|
|
|
|
piEnd->SetTechnique("DefaultFXSpecular_PS20_D1");
|
|
|
|
} else {
|
2015-06-30 02:54:59 +00:00
|
|
|
if (g_sOptions.b3Lights)
|
|
|
|
piEnd->SetTechnique("DefaultFXSpecular_D2");
|
2020-11-11 18:38:42 +00:00
|
|
|
else
|
|
|
|
piEnd->SetTechnique("DefaultFXSpecular_D1");
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// setup the default material
|
|
|
|
UINT dwPasses = 0;
|
2020-11-11 18:38:42 +00:00
|
|
|
piEnd->Begin(&dwPasses, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
piEnd->BeginPass(0);
|
|
|
|
}
|
|
|
|
D3DXVECTOR4 vVector = g_aclNormalColors[g_iCurrentColor];
|
2020-11-11 18:38:42 +00:00
|
|
|
if (++g_iCurrentColor == 14) {
|
2015-06-30 02:54:59 +00:00
|
|
|
g_iCurrentColor = 0;
|
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
if (!(!g_sOptions.bRenderMats && bAlpha)) {
|
|
|
|
for (unsigned int i = 0; i < piNode->mNumMeshes; ++i) {
|
|
|
|
const aiMesh *mesh = g_pcAsset->pcScene->mMeshes[piNode->mMeshes[i]];
|
|
|
|
AssetHelper::MeshHelper *helper = g_pcAsset->apcMeshes[piNode->mMeshes[i]];
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// don't render the mesh if the render pass is incorrect
|
2020-11-11 18:38:42 +00:00
|
|
|
if (g_sOptions.bRenderMats && (helper->piOpacityTexture || helper->fOpacity != 1.0f) && !mesh->HasBones()) {
|
|
|
|
if (!bAlpha) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else if (bAlpha) {
|
|
|
|
continue;
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Upload bone matrices. This maybe is the wrong place to do it, but for the heck of it I don't understand this code flow
|
2020-11-11 18:38:42 +00:00
|
|
|
if (mesh->HasBones()) {
|
|
|
|
if (helper->piEffect) {
|
|
|
|
static float matrices[4 * 4 * 60];
|
|
|
|
float *tempmat = matrices;
|
|
|
|
const std::vector<aiMatrix4x4> &boneMats = g_pcAsset->mAnimator->GetBoneMatrices(piNode, i);
|
|
|
|
ai_assert(boneMats.size() == mesh->mNumBones);
|
|
|
|
|
|
|
|
for (unsigned int a = 0; a < mesh->mNumBones; a++) {
|
|
|
|
const aiMatrix4x4 &mat = boneMats[a];
|
|
|
|
*tempmat++ = mat.a1;
|
|
|
|
*tempmat++ = mat.a2;
|
|
|
|
*tempmat++ = mat.a3;
|
|
|
|
*tempmat++ = mat.a4;
|
|
|
|
*tempmat++ = mat.b1;
|
|
|
|
*tempmat++ = mat.b2;
|
|
|
|
*tempmat++ = mat.b3;
|
|
|
|
*tempmat++ = mat.b4;
|
|
|
|
*tempmat++ = mat.c1;
|
|
|
|
*tempmat++ = mat.c2;
|
|
|
|
*tempmat++ = mat.c3;
|
|
|
|
*tempmat++ = mat.c4;
|
|
|
|
*tempmat++ = mat.d1;
|
|
|
|
*tempmat++ = mat.d2;
|
|
|
|
*tempmat++ = mat.d3;
|
|
|
|
*tempmat++ = mat.d4;
|
2015-06-30 02:54:59 +00:00
|
|
|
//tempmat += 4;
|
|
|
|
}
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (g_sOptions.bRenderMats) {
|
|
|
|
helper->piEffect->SetMatrixTransposeArray("gBoneMatrix", (D3DXMATRIX *)matrices, 60);
|
|
|
|
} else {
|
|
|
|
g_piDefaultEffect->SetMatrixTransposeArray("gBoneMatrix", (D3DXMATRIX *)matrices, 60);
|
2015-06-30 02:54:59 +00:00
|
|
|
g_piDefaultEffect->CommitChanges();
|
|
|
|
}
|
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
} else {
|
2015-06-30 02:54:59 +00:00
|
|
|
// upload identity matrices instead. Only the first is ever going to be used in meshes without bones
|
2020-11-11 18:38:42 +00:00
|
|
|
if (!g_sOptions.bRenderMats) {
|
|
|
|
D3DXMATRIX identity(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
|
|
|
|
g_piDefaultEffect->SetMatrixTransposeArray("gBoneMatrix", &identity, 1);
|
2015-06-30 02:54:59 +00:00
|
|
|
g_piDefaultEffect->CommitChanges();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// now setup the material
|
2020-11-11 18:38:42 +00:00
|
|
|
if (g_sOptions.bRenderMats) {
|
|
|
|
CMaterialManager::Instance().SetupMaterial(helper, pcProj, aiMe, pcCam, vPos);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->SetVertexDeclaration(gDefaultVertexDecl);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
if (g_sOptions.bNoAlphaBlending) {
|
2018-05-31 18:15:13 +00:00
|
|
|
// manually disable alpha-blending
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (bAlpha)
|
|
|
|
CMeshRenderer::Instance().DrawSorted(piNode->mMeshes[i], aiMe);
|
|
|
|
else
|
|
|
|
CMeshRenderer::Instance().DrawUnsorted(piNode->mMeshes[i]);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// now end the material
|
2020-11-11 18:38:42 +00:00
|
|
|
if (g_sOptions.bRenderMats) {
|
|
|
|
CMaterialManager::Instance().EndMaterial(helper);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// render normal vectors?
|
2020-11-11 18:38:42 +00:00
|
|
|
if (g_sOptions.bRenderNormals && helper->piVBNormals) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// this is very similar to the code in SetupMaterial()
|
2020-11-11 18:38:42 +00:00
|
|
|
ID3DXEffect *piEnd = g_piNormalsEffect;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
piEnd->SetVector("OUTPUT_COLOR", &vVector);
|
|
|
|
piEnd->SetMatrix("WorldViewProjection", (const D3DXMATRIX *)&pcProj);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
UINT dwPasses = 0;
|
2020-11-11 18:38:42 +00:00
|
|
|
piEnd->Begin(&dwPasses, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
piEnd->BeginPass(0);
|
|
|
|
|
|
|
|
g_piDevice->SetStreamSource(0, helper->piVBNormals, 0, sizeof(AssetHelper::LineVertex));
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->DrawPrimitive(D3DPT_LINELIST, 0, g_pcAsset->pcScene->mMeshes[piNode->mMeshes[i]]->mNumVertices);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
piEnd->EndPass();
|
|
|
|
piEnd->End();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// end the default material
|
2020-11-11 18:38:42 +00:00
|
|
|
if (!g_sOptions.bRenderMats) {
|
2015-06-30 02:54:59 +00:00
|
|
|
g_piDefaultEffect->EndPass();
|
|
|
|
g_piDefaultEffect->End();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// render all child nodes
|
2020-11-11 18:38:42 +00:00
|
|
|
for (unsigned int i = 0; i < piNode->mNumChildren; ++i)
|
|
|
|
RenderNode(piNode->mChildren[i], piMatrix, bAlpha);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// need to reset the viewmode?
|
|
|
|
if (bChangedVM)
|
|
|
|
m_iViewMode = VIEWMODE_NODE;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::RenderPatternBG() {
|
|
|
|
if (!g_piPatternEffect) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// the pattern effect won't work on ps_2_0 cards
|
2020-11-11 18:38:42 +00:00
|
|
|
if (g_sCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// seems we have not yet compiled this shader.
|
|
|
|
// and NOW is the best time to do that ...
|
2020-11-11 18:38:42 +00:00
|
|
|
ID3DXBuffer *piBuffer = nullptr;
|
|
|
|
if (FAILED(D3DXCreateEffect(g_piDevice,
|
|
|
|
g_szCheckerBackgroundShader.c_str(),
|
|
|
|
(UINT)g_szCheckerBackgroundShader.length(),
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
D3DXSHADER_USE_LEGACY_D3DX9_31_DLL,
|
|
|
|
nullptr,
|
|
|
|
&g_piPatternEffect, &piBuffer))) {
|
|
|
|
if (piBuffer) {
|
|
|
|
MessageBox(g_hDlg, (LPCSTR)piBuffer->GetBufferPointer(), "HLSL", MB_OK);
|
2015-06-30 02:54:59 +00:00
|
|
|
piBuffer->Release();
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
if (piBuffer) {
|
2015-06-30 02:54:59 +00:00
|
|
|
piBuffer->Release();
|
2020-04-07 14:56:22 +00:00
|
|
|
piBuffer = nullptr;
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
2020-11-11 18:38:42 +00:00
|
|
|
} else {
|
2015-06-30 02:54:59 +00:00
|
|
|
// clear the color buffer in magenta
|
|
|
|
// (hopefully this is ugly enough that every ps_2_0 cards owner
|
|
|
|
// runs to the next shop to buy himself a new card ...)
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
|
|
|
|
D3DCOLOR_ARGB(0xFF, 0xFF, 0, 0xFF), 1.0f, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// clear the depth buffer only
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->Clear(0, nullptr, D3DCLEAR_ZBUFFER,
|
|
|
|
D3DCOLOR_ARGB(0xFF, 0xFF, 0, 0xFF), 1.0f, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// setup the colors to be used ...
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piPatternEffect->SetVector("COLOR_ONE", &m_avCheckerColors[0]);
|
|
|
|
g_piPatternEffect->SetVector("COLOR_TWO", &m_avCheckerColors[1]);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// setup the shader
|
|
|
|
UINT dw;
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piPatternEffect->Begin(&dw, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
g_piPatternEffect->BeginPass(0);
|
|
|
|
|
|
|
|
RECT sRect;
|
2020-11-11 18:38:42 +00:00
|
|
|
GetWindowRect(GetDlgItem(g_hDlg, IDC_RT), &sRect);
|
2015-06-30 02:54:59 +00:00
|
|
|
sRect.right -= sRect.left;
|
|
|
|
sRect.bottom -= sRect.top;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
struct SVertex {
|
|
|
|
float x, y, z, w;
|
2015-06-30 02:54:59 +00:00
|
|
|
};
|
|
|
|
// build the screen-filling rectangle
|
|
|
|
SVertex as[4];
|
|
|
|
as[1].x = 0.0f;
|
|
|
|
as[1].y = 0.0f;
|
|
|
|
as[1].z = 0.2f;
|
|
|
|
as[3].x = (float)sRect.right;
|
|
|
|
as[3].y = 0.0f;
|
|
|
|
as[3].z = 0.2f;
|
|
|
|
as[0].x = 0.0f;
|
|
|
|
as[0].y = (float)sRect.bottom;
|
|
|
|
as[0].z = 0.2f;
|
|
|
|
as[2].x = (float)sRect.right;
|
|
|
|
as[2].y = (float)sRect.bottom;
|
|
|
|
as[2].z = 0.2f;
|
|
|
|
|
|
|
|
as[0].w = 1.0f;
|
|
|
|
as[1].w = 1.0f;
|
|
|
|
as[2].w = 1.0f;
|
|
|
|
as[3].w = 1.0f;
|
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
as[0].x -= 0.5f;
|
|
|
|
as[1].x -= 0.5f;
|
|
|
|
as[2].x -= 0.5f;
|
|
|
|
as[3].x -= 0.5f;
|
|
|
|
as[0].y -= 0.5f;
|
|
|
|
as[1].y -= 0.5f;
|
|
|
|
as[2].y -= 0.5f;
|
|
|
|
as[3].y -= 0.5f;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// draw the rectangle
|
2020-11-11 18:38:42 +00:00
|
|
|
DWORD dw2;
|
|
|
|
g_piDevice->GetFVF(&dw2);
|
2015-06-30 02:54:59 +00:00
|
|
|
g_piDevice->SetFVF(D3DFVF_XYZRHW);
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2,
|
|
|
|
&as, sizeof(SVertex));
|
2015-06-30 02:54:59 +00:00
|
|
|
g_piDevice->SetFVF(dw2);
|
|
|
|
|
|
|
|
// cleanup
|
|
|
|
g_piPatternEffect->EndPass();
|
|
|
|
g_piPatternEffect->End();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
2020-11-11 18:38:42 +00:00
|
|
|
int CDisplay::RenderTextureView() {
|
|
|
|
if (!g_pcAsset || !g_pcAsset->pcScene) return 0;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// handle input
|
|
|
|
this->HandleInputTextureView();
|
|
|
|
|
|
|
|
// render the background
|
|
|
|
RenderPatternBG();
|
|
|
|
|
|
|
|
// it might be that there is no texture ...
|
2020-11-11 18:38:42 +00:00
|
|
|
if (!m_pcCurrentTexture->piTexture) {
|
2015-06-30 02:54:59 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
RECT sRect;
|
2020-11-11 18:38:42 +00:00
|
|
|
GetWindowRect(GetDlgItem(g_hDlg, IDC_RT), &sRect);
|
2015-06-30 02:54:59 +00:00
|
|
|
sRect.right -= sRect.left;
|
|
|
|
sRect.bottom -= sRect.top;
|
|
|
|
|
|
|
|
// commit the texture to the shader
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piPassThroughEffect->SetTexture("TEXTURE_2D", *m_pcCurrentTexture->piTexture);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
if (aiTextureType_OPACITY == m_pcCurrentTexture->iType) {
|
2015-06-30 02:54:59 +00:00
|
|
|
g_piPassThroughEffect->SetTechnique("PassThroughAlphaFromR");
|
2020-11-11 18:38:42 +00:00
|
|
|
} else if ((aiTextureType_OPACITY | 0x40000000) == m_pcCurrentTexture->iType) {
|
2015-06-30 02:54:59 +00:00
|
|
|
g_piPassThroughEffect->SetTechnique("PassThroughAlphaFromA");
|
2020-11-11 18:38:42 +00:00
|
|
|
} else if (g_sCaps.PixelShaderVersion < D3DPS_VERSION(2, 0))
|
|
|
|
g_piPassThroughEffect->SetTechnique("PassThrough_FF");
|
2015-06-30 02:54:59 +00:00
|
|
|
else
|
|
|
|
g_piPassThroughEffect->SetTechnique("PassThrough");
|
|
|
|
|
|
|
|
UINT dw;
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piPassThroughEffect->Begin(&dw, 0);
|
2015-06-30 02:54:59 +00:00
|
|
|
g_piPassThroughEffect->BeginPass(0);
|
|
|
|
|
|
|
|
if (aiTextureType_HEIGHT == m_pcCurrentTexture->iType ||
|
2020-11-11 18:38:42 +00:00
|
|
|
aiTextureType_NORMALS == m_pcCurrentTexture->iType || g_sOptions.bNoAlphaBlending) {
|
2015-06-30 02:54:59 +00:00
|
|
|
// manually disable alpha blending
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
2015-06-30 02:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// build a rectangle which centers the texture
|
|
|
|
// scaling is OK, but no stretching
|
|
|
|
D3DSURFACE_DESC sDesc;
|
2020-11-11 18:38:42 +00:00
|
|
|
if (m_pcCurrentTexture->piTexture && *m_pcCurrentTexture->piTexture) { /* just a dirty fix */
|
|
|
|
(*m_pcCurrentTexture->piTexture)->GetLevelDesc(0, &sDesc);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
struct SVertex {
|
|
|
|
float x, y, z, w, u, v;
|
|
|
|
};
|
2015-06-30 02:54:59 +00:00
|
|
|
SVertex as[4];
|
|
|
|
|
|
|
|
const float nx = (float)sRect.right;
|
|
|
|
const float ny = (float)sRect.bottom;
|
2020-11-11 18:38:42 +00:00
|
|
|
const float x = (float)sDesc.Width;
|
|
|
|
const float y = (float)sDesc.Height;
|
|
|
|
float f = std::min((nx - 30) / x, (ny - 30) / y) * (m_fTextureZoom / 1000.0f);
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
float fHalfX = (nx - (f * x)) / 2.0f;
|
|
|
|
float fHalfY = (ny - (f * y)) / 2.0f;
|
|
|
|
as[1].x = fHalfX + m_vTextureOffset.x;
|
|
|
|
as[1].y = fHalfY + m_vTextureOffset.y;
|
|
|
|
as[1].z = 0.2f;
|
|
|
|
as[1].w = 1.0f;
|
|
|
|
as[1].u = 0.0f;
|
|
|
|
as[1].v = 0.0f;
|
2020-11-11 18:38:42 +00:00
|
|
|
as[3].x = nx - fHalfX + m_vTextureOffset.x;
|
2015-06-30 02:54:59 +00:00
|
|
|
as[3].y = fHalfY + m_vTextureOffset.y;
|
|
|
|
as[3].z = 0.2f;
|
|
|
|
as[3].w = 1.0f;
|
|
|
|
as[3].u = 1.0f;
|
|
|
|
as[3].v = 0.0f;
|
|
|
|
as[0].x = fHalfX + m_vTextureOffset.x;
|
2020-11-11 18:38:42 +00:00
|
|
|
as[0].y = ny - fHalfY + m_vTextureOffset.y;
|
2015-06-30 02:54:59 +00:00
|
|
|
as[0].z = 0.2f;
|
|
|
|
as[0].w = 1.0f;
|
|
|
|
as[0].u = 0.0f;
|
|
|
|
as[0].v = 1.0f;
|
2020-11-11 18:38:42 +00:00
|
|
|
as[2].x = nx - fHalfX + m_vTextureOffset.x;
|
|
|
|
as[2].y = ny - fHalfY + m_vTextureOffset.y;
|
2015-06-30 02:54:59 +00:00
|
|
|
as[2].z = 0.2f;
|
|
|
|
as[2].w = 1.0f;
|
|
|
|
as[2].u = 1.0f;
|
|
|
|
as[2].v = 1.0f;
|
2020-11-11 18:38:42 +00:00
|
|
|
as[0].x -= 0.5f;
|
|
|
|
as[1].x -= 0.5f;
|
|
|
|
as[2].x -= 0.5f;
|
|
|
|
as[3].x -= 0.5f;
|
|
|
|
as[0].y -= 0.5f;
|
|
|
|
as[1].y -= 0.5f;
|
|
|
|
as[2].y -= 0.5f;
|
|
|
|
as[3].y -= 0.5f;
|
2015-06-30 02:54:59 +00:00
|
|
|
|
|
|
|
// draw the rectangle
|
2020-11-11 18:38:42 +00:00
|
|
|
DWORD dw2;
|
|
|
|
g_piDevice->GetFVF(&dw2);
|
2015-06-30 02:54:59 +00:00
|
|
|
g_piDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
|
2020-11-11 18:38:42 +00:00
|
|
|
g_piDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2,
|
|
|
|
&as, sizeof(SVertex));
|
2015-06-30 02:54:59 +00:00
|
|
|
g_piDevice->SetFVF(dw2);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_piPassThroughEffect->EndPass();
|
|
|
|
g_piPassThroughEffect->End();
|
|
|
|
|
|
|
|
// do we need to draw UV coordinates?
|
|
|
|
return 1;
|
|
|
|
}
|
2018-05-31 18:15:13 +00:00
|
|
|
|
2020-11-11 18:38:42 +00:00
|
|
|
} // namespace AssimpView
|