Game client codebase including: - CharacterActionControl: Character and creature management - GlobalScript: Network, items, skills, quests, utilities - RYLClient: Main client application with GUI and event handlers - Engine: 3D rendering engine (RYLGL) - MemoryManager: Custom memory allocation - Library: Third-party dependencies (DirectX, boost, etc.) - Tools: Development utilities 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1512 lines
43 KiB
C++
1512 lines
43 KiB
C++
// dxtexDoc.cpp : implementation of the CDxtexDoc class
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "dxtex.h"
|
|
#include "dxtexDoc.h"
|
|
#include "dialogs.h"
|
|
#include "dds.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDxtexDoc
|
|
|
|
IMPLEMENT_DYNCREATE(CDxtexDoc, CDocument)
|
|
|
|
BEGIN_MESSAGE_MAP(CDxtexDoc, CDocument)
|
|
//{{AFX_MSG_MAP(CDxtexDoc)
|
|
ON_COMMAND(ID_FILE_OPENALPHA, OnFileOpenAlpha)
|
|
ON_COMMAND(ID_FORMAT_GENERATEMIPMAPS, OnGenerateMipMaps)
|
|
ON_COMMAND(ID_FORMAT_CHANGESURFACEFMT, OnFormatChangeSurfaceFmt)
|
|
ON_COMMAND(ID_FORMAT_CHANGECUBEMAPFACES, OnFormatChangeCubeMapFaces)
|
|
ON_COMMAND(ID_FORMAT_MAKEINTOVOLUMEMAP, OnFormatMakeIntoVolumeMap)
|
|
ON_UPDATE_COMMAND_UI(ID_FILE_OPENALPHA, OnUpdateFileOpenAlpha)
|
|
ON_UPDATE_COMMAND_UI(ID_FORMAT_GENERATEMIPMAPS, OnUpdateFormatGenerateMipmaps)
|
|
ON_UPDATE_COMMAND_UI(ID_FORMAT_CHANGECUBEMAPFACES, OnUpdateFormatChangeCubeMapFaces)
|
|
ON_UPDATE_COMMAND_UI(ID_FORMAT_MAKEINTOVOLUMEMAP, OnUpdateFormatMakeIntoVolumeMap)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDxtexDoc diagnostics
|
|
|
|
#ifdef _DEBUG
|
|
void CDxtexDoc::AssertValid() const
|
|
{
|
|
CDocument::AssertValid();
|
|
}
|
|
|
|
void CDxtexDoc::Dump(CDumpContext& dc) const
|
|
{
|
|
CDocument::Dump(dc);
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDxtexDoc construction/destruction
|
|
|
|
CDxtexDoc::CDxtexDoc()
|
|
{
|
|
m_ptexOrig = NULL;
|
|
m_ptexNew = NULL;
|
|
m_dwWidth = 0;
|
|
m_dwHeight = 0;
|
|
m_dwDepth = 0;
|
|
m_numMips = 0;
|
|
m_dwCubeMapFlags = 0;
|
|
m_bTitleModsChanged = FALSE;
|
|
}
|
|
|
|
|
|
CDxtexDoc::~CDxtexDoc()
|
|
{
|
|
ReleasePpo(&m_ptexOrig);
|
|
ReleasePpo(&m_ptexNew);
|
|
}
|
|
|
|
|
|
BOOL CDxtexDoc::OnNewDocument()
|
|
{
|
|
HRESULT hr;
|
|
LPDIRECT3DDEVICE8 pd3ddev = PDxtexApp()->Pd3ddev();
|
|
|
|
if (!CDocument::OnNewDocument())
|
|
return FALSE;
|
|
|
|
CNewTextureDlg dlg;
|
|
|
|
if (IDCANCEL == dlg.DoModal())
|
|
return FALSE;
|
|
|
|
m_dwWidth = dlg.m_dwWidth;
|
|
m_dwHeight = dlg.m_dwHeight;
|
|
m_numMips = dlg.m_numMips;
|
|
|
|
if (dlg.m_iTexType == 0)
|
|
{
|
|
LPDIRECT3DTEXTURE8 pmiptex;
|
|
hr = pd3ddev->CreateTexture(m_dwWidth, m_dwHeight, m_numMips,
|
|
0, dlg.m_fmt, D3DPOOL_MANAGED, &pmiptex);
|
|
if (FAILED(hr))
|
|
{
|
|
AfxMessageBox(ID_ERROR_CANTCREATETEXTURE);
|
|
return FALSE;
|
|
}
|
|
m_ptexOrig = pmiptex;
|
|
|
|
}
|
|
else if (dlg.m_iTexType == 1)
|
|
{
|
|
// Cube Map
|
|
LPDIRECT3DCUBETEXTURE8 pcubetex;
|
|
m_dwCubeMapFlags = DDS_CUBEMAP_ALLFACES;
|
|
hr = pd3ddev->CreateCubeTexture(m_dwWidth, m_numMips,
|
|
0, dlg.m_fmt, D3DPOOL_MANAGED, &pcubetex);
|
|
if (FAILED(hr))
|
|
{
|
|
AfxMessageBox(ID_ERROR_CANTCREATETEXTURE);
|
|
return FALSE;
|
|
}
|
|
m_ptexOrig = pcubetex;
|
|
}
|
|
else
|
|
{
|
|
LPDIRECT3DVOLUMETEXTURE8 pvoltex;
|
|
m_dwDepth = dlg.m_dwDepth;
|
|
hr = pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, m_dwDepth, m_numMips,
|
|
0, dlg.m_fmt, D3DPOOL_SYSTEMMEM, &pvoltex);
|
|
if (FAILED(hr))
|
|
{
|
|
AfxMessageBox(ID_ERROR_CANTCREATETEXTURE);
|
|
return FALSE;
|
|
}
|
|
m_ptexOrig = pvoltex;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL CDxtexDoc::OnOpenDocument(LPCTSTR lpszPathName)
|
|
{
|
|
LPDIRECT3DDEVICE8 pd3ddev = PDxtexApp()->Pd3ddev();
|
|
D3DXIMAGE_INFO imageinfo;
|
|
D3DXIMAGE_INFO imageinfo2;
|
|
|
|
if( FAILED( D3DXGetImageInfoFromFile( lpszPathName, &imageinfo ) ) )
|
|
{
|
|
AfxMessageBox(ID_ERROR_COULDNTLOADFILE);
|
|
return FALSE;
|
|
}
|
|
|
|
switch( imageinfo.ResourceType )
|
|
{
|
|
case D3DRTYPE_TEXTURE:
|
|
if( FAILED( D3DXCreateTextureFromFileEx( pd3ddev, lpszPathName,
|
|
imageinfo.Width, imageinfo.Height, imageinfo.MipLevels, 0,
|
|
imageinfo.Format, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 0,
|
|
&imageinfo2, NULL, (LPDIRECT3DTEXTURE8*)&m_ptexOrig ) ) )
|
|
{
|
|
AfxMessageBox(ID_ERROR_COULDNTLOADFILE);
|
|
return FALSE;
|
|
}
|
|
m_dwWidth = imageinfo2.Width;
|
|
m_dwHeight = imageinfo2.Height;
|
|
m_dwDepth = 0;
|
|
m_numMips = imageinfo2.MipLevels;
|
|
|
|
if( imageinfo.ImageFileFormat == D3DXIFF_BMP )
|
|
{
|
|
// Look for "foo_a.bmp" for alpha channel
|
|
CString strPath = lpszPathName;
|
|
int i = strPath.ReverseFind('.');
|
|
HRESULT hr;
|
|
strPath = strPath.Left(i) + "_a.bmp";
|
|
CFileStatus status;
|
|
if (CFile::GetStatus(strPath, status))
|
|
{
|
|
// Make sure there's an alpha channel to load alpha image into
|
|
if (FAILED(EnsureAlpha(&m_ptexOrig)))
|
|
return FALSE;
|
|
|
|
LPDIRECT3DSURFACE8 psurf;
|
|
|
|
hr = ((LPDIRECT3DTEXTURE8)m_ptexOrig)->GetSurfaceLevel(0, &psurf);
|
|
if (FAILED(hr))
|
|
return FALSE;
|
|
|
|
hr = LoadAlphaIntoSurface(strPath, psurf);
|
|
ReleasePpo(&psurf);
|
|
if (FAILED(hr))
|
|
return FALSE;
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
case D3DRTYPE_VOLUMETEXTURE:
|
|
if( FAILED( D3DXCreateVolumeTextureFromFileEx( pd3ddev, lpszPathName,
|
|
imageinfo.Width, imageinfo.Height, imageinfo.Depth, imageinfo.MipLevels,
|
|
0, imageinfo.Format, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE,
|
|
0, &imageinfo2, NULL, (LPDIRECT3DVOLUMETEXTURE8*)&m_ptexOrig ) ) )
|
|
{
|
|
AfxMessageBox(ID_ERROR_COULDNTLOADFILE);
|
|
return FALSE;
|
|
}
|
|
m_dwWidth = imageinfo2.Width;
|
|
m_dwHeight = imageinfo2.Height;
|
|
m_dwDepth = imageinfo2.Depth;
|
|
m_numMips = imageinfo2.MipLevels;
|
|
break;
|
|
|
|
case D3DRTYPE_CUBETEXTURE:
|
|
if( FAILED( D3DXCreateCubeTextureFromFileEx( pd3ddev, lpszPathName,
|
|
imageinfo.Width, imageinfo.MipLevels, 0, imageinfo.Format,
|
|
D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE,
|
|
0, &imageinfo2, NULL, (LPDIRECT3DCUBETEXTURE8*)&m_ptexOrig ) ) )
|
|
{
|
|
AfxMessageBox(ID_ERROR_COULDNTLOADFILE);
|
|
return FALSE;
|
|
}
|
|
m_dwWidth = imageinfo2.Width;
|
|
m_dwHeight = imageinfo2.Height;
|
|
m_dwDepth = 0;
|
|
m_numMips = imageinfo2.MipLevels;
|
|
m_dwCubeMapFlags = DDS_CUBEMAP_ALLFACES;
|
|
break;
|
|
|
|
default:
|
|
AfxMessageBox(ID_ERROR_COULDNTLOADFILE);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL CDxtexDoc::OnSaveDocument(LPCTSTR lpszPathName)
|
|
{
|
|
LPDIRECT3DBASETEXTURE8 ptex;
|
|
ptex = (m_ptexNew == NULL ? m_ptexOrig : m_ptexNew);
|
|
|
|
if( FAILED( D3DXSaveTextureToFile( lpszPathName, D3DXIFF_DDS, ptex, NULL ) ) )
|
|
{
|
|
AfxMessageBox(ID_ERROR_COULDNTSAVEFILE);
|
|
return FALSE;
|
|
}
|
|
|
|
SetModifiedFlag(FALSE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
D3DFORMAT CDxtexDoc::GetFormat(LPDIRECT3DBASETEXTURE8 ptex)
|
|
{
|
|
LPDIRECT3DTEXTURE8 pmiptex = NULL;
|
|
LPDIRECT3DCUBETEXTURE8 pcubetex = NULL;
|
|
LPDIRECT3DVOLUMETEXTURE8 pvoltex = NULL;
|
|
D3DFORMAT fmt;
|
|
|
|
if (IsVolumeMap())
|
|
pvoltex = (LPDIRECT3DVOLUMETEXTURE8)ptex;
|
|
else if (IsCubeMap())
|
|
pcubetex = (LPDIRECT3DCUBETEXTURE8)ptex;
|
|
else
|
|
pmiptex = (LPDIRECT3DTEXTURE8)ptex;
|
|
|
|
if (pvoltex != NULL)
|
|
{
|
|
D3DVOLUME_DESC vd;
|
|
pvoltex->GetLevelDesc(0, &vd);
|
|
fmt = vd.Format;
|
|
}
|
|
else if (pcubetex != NULL)
|
|
{
|
|
D3DSURFACE_DESC sd;
|
|
pcubetex->GetLevelDesc(0, &sd);
|
|
fmt = sd.Format;
|
|
}
|
|
else
|
|
{
|
|
D3DSURFACE_DESC sd;
|
|
pmiptex->GetLevelDesc(0, &sd);
|
|
fmt = sd.Format;
|
|
}
|
|
return fmt;
|
|
}
|
|
|
|
|
|
|
|
// If *pptex's current format has less than 4 bits of alpha, change
|
|
// it to a similar format that has at least 4 bits of alpha.
|
|
HRESULT CDxtexDoc::EnsureAlpha(LPDIRECT3DBASETEXTURE8* pptex)
|
|
{
|
|
HRESULT hr;
|
|
D3DFORMAT fmtCur = GetFormat(*pptex);
|
|
D3DFORMAT fmtNew = D3DFMT_UNKNOWN;
|
|
LPDIRECT3DBASETEXTURE8 ptex;
|
|
|
|
switch (fmtCur)
|
|
{
|
|
case D3DFMT_R8G8B8:
|
|
fmtNew = D3DFMT_A8R8G8B8;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if( fmtNew != D3DFMT_UNKNOWN )
|
|
{
|
|
if (FAILED(hr = ChangeFormat(m_ptexOrig, fmtNew, &ptex)))
|
|
return hr;
|
|
ReleasePpo(&m_ptexOrig);
|
|
m_ptexOrig = ptex;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDxtexDoc commands
|
|
|
|
HRESULT CDxtexDoc::LoadAlphaBmp(CString& strPath)
|
|
{
|
|
HRESULT hr;
|
|
LPDIRECT3DTEXTURE8 pmiptex;
|
|
LPDIRECT3DSURFACE8 psurf;
|
|
|
|
if (IsCubeMap())
|
|
return E_FAIL;
|
|
|
|
pmiptex = (LPDIRECT3DTEXTURE8)m_ptexOrig;
|
|
hr = pmiptex->GetSurfaceLevel(0, &psurf);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
hr = LoadAlphaIntoSurface(strPath, psurf);
|
|
ReleasePpo(&psurf);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
UpdateAllViews(NULL, 1); // tell CView to pick up new surface pointers
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT CDxtexDoc::ChangeFormat(LPDIRECT3DBASETEXTURE8 ptexCur, D3DFORMAT fmtTo,
|
|
LPDIRECT3DBASETEXTURE8* pptexNew)
|
|
{
|
|
HRESULT hr;
|
|
LPDIRECT3DDEVICE8 pd3ddev = PDxtexApp()->Pd3ddev();
|
|
LPDIRECT3DTEXTURE8 pmiptex;
|
|
LPDIRECT3DCUBETEXTURE8 pcubetex;
|
|
LPDIRECT3DVOLUMETEXTURE8 pvoltex;
|
|
D3DFORMAT fmtFrom;
|
|
LPDIRECT3DTEXTURE8 pmiptexNew;
|
|
LPDIRECT3DCUBETEXTURE8 pcubetexNew;
|
|
LPDIRECT3DVOLUMETEXTURE8 pvoltexNew;
|
|
|
|
if (IsVolumeMap())
|
|
{
|
|
pvoltex = (LPDIRECT3DVOLUMETEXTURE8)ptexCur;
|
|
D3DVOLUME_DESC vd;
|
|
pvoltex->GetLevelDesc(0, &vd);
|
|
fmtFrom = vd.Format;
|
|
}
|
|
else if (IsCubeMap())
|
|
{
|
|
pcubetex = (LPDIRECT3DCUBETEXTURE8)ptexCur;
|
|
D3DSURFACE_DESC sd;
|
|
pcubetex->GetLevelDesc(0, &sd);
|
|
fmtFrom = sd.Format;
|
|
}
|
|
else
|
|
{
|
|
pmiptex = (LPDIRECT3DTEXTURE8)ptexCur;
|
|
D3DSURFACE_DESC sd;
|
|
pmiptex->GetLevelDesc(0, &sd);
|
|
fmtFrom = sd.Format;
|
|
}
|
|
|
|
if (fmtFrom == D3DFMT_DXT2 || fmtFrom == D3DFMT_DXT4)
|
|
{
|
|
if (fmtTo == D3DFMT_DXT1)
|
|
{
|
|
AfxMessageBox(ID_ERROR_PREMULTTODXT1);
|
|
}
|
|
else if (fmtTo != D3DFMT_DXT2 && fmtTo != D3DFMT_DXT4)
|
|
{
|
|
AfxMessageBox(ID_ERROR_PREMULTALPHA);
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
if (IsVolumeMap())
|
|
{
|
|
hr = pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, m_dwDepth, m_numMips,
|
|
0, fmtTo, D3DPOOL_SYSTEMMEM, &pvoltexNew);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
*pptexNew = pvoltexNew;
|
|
if (FAILED(BltAllLevels(D3DCUBEMAP_FACE_FORCE_DWORD, ptexCur, *pptexNew)))
|
|
return hr;
|
|
}
|
|
else if (IsCubeMap())
|
|
{
|
|
hr = pd3ddev->CreateCubeTexture(m_dwWidth, m_numMips,
|
|
0, fmtTo, D3DPOOL_MANAGED, &pcubetexNew);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
*pptexNew = pcubetexNew;
|
|
if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_NEGATIVE_X, ptexCur, *pptexNew)))
|
|
return hr;
|
|
if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_POSITIVE_X, ptexCur, *pptexNew)))
|
|
return hr;
|
|
if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_NEGATIVE_Y, ptexCur, *pptexNew)))
|
|
return hr;
|
|
if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_POSITIVE_Y, ptexCur, *pptexNew)))
|
|
return hr;
|
|
if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_NEGATIVE_Z, ptexCur, *pptexNew)))
|
|
return hr;
|
|
if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_POSITIVE_Z, ptexCur, *pptexNew)))
|
|
return hr;
|
|
}
|
|
else
|
|
{
|
|
hr = pd3ddev->CreateTexture(m_dwWidth, m_dwHeight, m_numMips,
|
|
0, fmtTo, D3DPOOL_MANAGED, &pmiptexNew);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
*pptexNew = pmiptexNew;
|
|
if (FAILED(BltAllLevels(D3DCUBEMAP_FACE_FORCE_DWORD, ptexCur, *pptexNew)))
|
|
return hr;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT CDxtexDoc::Compress(D3DFORMAT fmtTo, BOOL bSwitchView)
|
|
{
|
|
HRESULT hr;
|
|
LPDIRECT3DBASETEXTURE8 ptexNew;
|
|
|
|
if (FAILED(hr = ChangeFormat(m_ptexOrig, fmtTo, &ptexNew)))
|
|
return hr;
|
|
|
|
ReleasePpo(&m_ptexNew);
|
|
m_ptexNew = ptexNew;
|
|
|
|
SetModifiedFlag();
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
if (bSwitchView)
|
|
AfxGetMainWnd()->PostMessage(WM_COMMAND, ID_VIEW_COMPRESSED, 0);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDxtexDoc::OnGenerateMipMaps()
|
|
{
|
|
GenerateMipMaps();
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDxtexDoc::GenerateMipMaps()
|
|
{
|
|
LONG lwTempH;
|
|
LONG lwTempW;
|
|
LONG lwPowsW;
|
|
LONG lwPowsH;
|
|
LPDIRECT3DTEXTURE8 pddsNew = NULL;
|
|
D3DFORMAT fmt;
|
|
HRESULT hr;
|
|
LPDIRECT3DDEVICE8 pd3ddev = PDxtexApp()->Pd3ddev();
|
|
LPDIRECT3DTEXTURE8 pmiptex = NULL;
|
|
LPDIRECT3DCUBETEXTURE8 pcubetex = NULL;
|
|
LPDIRECT3DVOLUMETEXTURE8 pvoltex = NULL;
|
|
LPDIRECT3DTEXTURE8 pmiptexNew = NULL;
|
|
LPDIRECT3DCUBETEXTURE8 pcubetexNew = NULL;
|
|
LPDIRECT3DVOLUMETEXTURE8 pvoltexNew = NULL;
|
|
LPDIRECT3DSURFACE8 psurfSrc;
|
|
LPDIRECT3DSURFACE8 psurfDest;
|
|
LPDIRECT3DVOLUME8 pvolSrc;
|
|
LPDIRECT3DVOLUME8 pvolDest;
|
|
|
|
if (IsVolumeMap())
|
|
pvoltex = (LPDIRECT3DVOLUMETEXTURE8)m_ptexOrig;
|
|
else if (IsCubeMap())
|
|
pcubetex = (LPDIRECT3DCUBETEXTURE8)m_ptexOrig;
|
|
else
|
|
pmiptex = (LPDIRECT3DTEXTURE8)m_ptexOrig;
|
|
|
|
if (pvoltex != NULL)
|
|
{
|
|
D3DVOLUME_DESC vd;
|
|
pvoltex->GetLevelDesc(0, &vd);
|
|
fmt = vd.Format;
|
|
}
|
|
else if (pcubetex != NULL)
|
|
{
|
|
D3DSURFACE_DESC sd;
|
|
pcubetex->GetLevelDesc(0, &sd);
|
|
fmt = sd.Format;
|
|
}
|
|
else
|
|
{
|
|
D3DSURFACE_DESC sd;
|
|
pmiptex->GetLevelDesc(0, &sd);
|
|
fmt = sd.Format;
|
|
}
|
|
|
|
lwTempW = m_dwWidth;
|
|
lwTempH = m_dwHeight;
|
|
lwPowsW = 0;
|
|
lwPowsH = 0;
|
|
while (lwTempW > 0)
|
|
{
|
|
lwPowsW++;
|
|
lwTempW = lwTempW / 2;
|
|
}
|
|
while (lwTempH > 0)
|
|
{
|
|
lwPowsH++;
|
|
lwTempH = lwTempH / 2;
|
|
}
|
|
m_numMips = lwPowsW > lwPowsH ? lwPowsW : lwPowsH;
|
|
|
|
// Create destination mipmap surface - same format as source
|
|
if (pvoltex != NULL)
|
|
{
|
|
if (FAILED(hr = pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, m_dwDepth,
|
|
m_numMips, 0, fmt, D3DPOOL_SYSTEMMEM, &pvoltexNew)))
|
|
{
|
|
goto LFail;
|
|
}
|
|
hr = pvoltex->GetVolumeLevel(0, &pvolSrc);
|
|
hr = pvoltexNew->GetVolumeLevel(0, &pvolDest);
|
|
hr = D3DXLoadVolumeFromVolume(pvolDest, NULL, NULL, pvolSrc, NULL, NULL,
|
|
D3DX_FILTER_TRIANGLE, 0);
|
|
ReleasePpo(&pvolSrc);
|
|
ReleasePpo(&pvolDest);
|
|
hr = D3DXFilterVolumeTexture(pvoltexNew, NULL, 0, D3DX_FILTER_TRIANGLE);
|
|
}
|
|
else if (pmiptex != NULL)
|
|
{
|
|
if (FAILED(hr = pd3ddev->CreateTexture(m_dwWidth, m_dwHeight, m_numMips,
|
|
0, fmt, D3DPOOL_MANAGED, &pmiptexNew)))
|
|
{
|
|
goto LFail;
|
|
}
|
|
hr = pmiptex->GetSurfaceLevel(0, &psurfSrc);
|
|
hr = pmiptexNew->GetSurfaceLevel(0, &psurfDest);
|
|
hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL,
|
|
D3DX_FILTER_TRIANGLE, 0);
|
|
ReleasePpo(&psurfSrc);
|
|
ReleasePpo(&psurfDest);
|
|
hr = D3DXFilterTexture(pmiptexNew, NULL, 0, D3DX_FILTER_TRIANGLE);
|
|
}
|
|
else
|
|
{
|
|
if (FAILED(hr = pd3ddev->CreateCubeTexture(m_dwWidth, m_numMips,
|
|
0, fmt, D3DPOOL_MANAGED, &pcubetexNew)))
|
|
{
|
|
goto LFail;
|
|
}
|
|
hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_X, 0, &psurfSrc);
|
|
hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_X, 0, &psurfDest);
|
|
hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL,
|
|
D3DX_FILTER_TRIANGLE, 0);
|
|
ReleasePpo(&psurfSrc);
|
|
ReleasePpo(&psurfDest);
|
|
hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_X, 0, &psurfSrc);
|
|
hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_X, 0, &psurfDest);
|
|
hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL,
|
|
D3DX_FILTER_TRIANGLE, 0);
|
|
ReleasePpo(&psurfSrc);
|
|
ReleasePpo(&psurfDest);
|
|
hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &psurfSrc);
|
|
hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &psurfDest);
|
|
hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL,
|
|
D3DX_FILTER_TRIANGLE, 0);
|
|
ReleasePpo(&psurfSrc);
|
|
ReleasePpo(&psurfDest);
|
|
hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Y, 0, &psurfSrc);
|
|
hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Y, 0, &psurfDest);
|
|
hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL,
|
|
D3DX_FILTER_TRIANGLE, 0);
|
|
ReleasePpo(&psurfSrc);
|
|
ReleasePpo(&psurfDest);
|
|
hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Z, 0, &psurfSrc);
|
|
hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Z, 0, &psurfDest);
|
|
hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL,
|
|
D3DX_FILTER_TRIANGLE, 0);
|
|
ReleasePpo(&psurfSrc);
|
|
ReleasePpo(&psurfDest);
|
|
hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Z, 0, &psurfSrc);
|
|
hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Z, 0, &psurfDest);
|
|
hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL,
|
|
D3DX_FILTER_TRIANGLE, 0);
|
|
ReleasePpo(&psurfSrc);
|
|
ReleasePpo(&psurfDest);
|
|
hr = D3DXFilterCubeTexture(pcubetexNew, NULL, 0, D3DX_FILTER_TRIANGLE);
|
|
}
|
|
|
|
ReleasePpo(&m_ptexOrig);
|
|
if (pvoltexNew != NULL)
|
|
m_ptexOrig = pvoltexNew;
|
|
else if (pcubetexNew != NULL)
|
|
m_ptexOrig = pcubetexNew;
|
|
else
|
|
m_ptexOrig = pmiptexNew;
|
|
|
|
if (m_ptexNew != NULL)
|
|
{
|
|
// Rather than filtering down the (probably-compressed) m_ptexNew
|
|
// top level, compress each mip level from the (probably-uncompressed)
|
|
// m_ptexOrig levels.
|
|
if (pvoltexNew != NULL)
|
|
{
|
|
D3DVOLUME_DESC vd;
|
|
((LPDIRECT3DVOLUMETEXTURE8)m_ptexNew)->GetLevelDesc(0, &vd);
|
|
fmt = vd.Format;
|
|
}
|
|
else if (pcubetexNew != NULL)
|
|
{
|
|
D3DSURFACE_DESC sd;
|
|
((LPDIRECT3DTEXTURE8)m_ptexNew)->GetLevelDesc(0, &sd);
|
|
fmt = sd.Format;
|
|
}
|
|
else
|
|
{
|
|
D3DSURFACE_DESC sd;
|
|
((LPDIRECT3DCUBETEXTURE8)m_ptexNew)->GetLevelDesc(0, &sd);
|
|
fmt = sd.Format;
|
|
}
|
|
Compress(fmt, FALSE);
|
|
}
|
|
|
|
m_bTitleModsChanged = TRUE; // Generate title bar update
|
|
UpdateAllViews(NULL, 1); // tell CView to pick up new surface pointers
|
|
SetModifiedFlag();
|
|
return;
|
|
|
|
LFail:
|
|
ReleasePpo(&pddsNew);
|
|
}
|
|
|
|
|
|
void CDxtexDoc::SetPathName(LPCTSTR lpszPathName, BOOL bAddToMRU)
|
|
{
|
|
CDocument::SetPathName(lpszPathName, bAddToMRU);
|
|
|
|
TCHAR* pszLeaf = strrchr(lpszPathName, '\\') + 1;
|
|
TCHAR* pszExtension = strrchr(lpszPathName, '.');
|
|
if (lstrcmpi(pszExtension, ".dds") != 0)
|
|
{
|
|
lstrcpy(pszExtension, "");
|
|
SetModifiedFlag(TRUE);
|
|
SetTitle(pszLeaf);
|
|
m_strPathName.Empty();
|
|
}
|
|
}
|
|
|
|
DWORD CDxtexDoc::NumMips(VOID)
|
|
{
|
|
return m_numMips;
|
|
}
|
|
|
|
|
|
void CDxtexDoc::OnFileOpenAlpha()
|
|
{
|
|
HRESULT hr;
|
|
CString fileName;
|
|
LPDIRECT3DTEXTURE8 pmiptex;
|
|
|
|
if (IsCubeMap() || IsVolumeMap())
|
|
return;
|
|
|
|
// Premultiplied-alpha files don't support this feature:
|
|
D3DSURFACE_DESC sd;
|
|
((LPDIRECT3DTEXTURE8)m_ptexOrig)->GetLevelDesc(0, &sd);
|
|
if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
|
|
{
|
|
AfxMessageBox(ID_ERROR_PREMULTALPHA);
|
|
return;
|
|
}
|
|
|
|
// Check if the original has alpha
|
|
if( sd.Format != D3DFMT_A8R8G8B8 &&
|
|
sd.Format != D3DFMT_A1R5G5B5 &&
|
|
sd.Format != D3DFMT_A4R4G4B4 &&
|
|
sd.Format != D3DFMT_A8R3G3B2 &&
|
|
sd.Format != D3DFMT_DXT1 &&
|
|
sd.Format != D3DFMT_DXT3 &&
|
|
sd.Format != D3DFMT_DXT5 )
|
|
{
|
|
// If it doesn't then see if the new does
|
|
if (m_ptexNew != NULL)
|
|
{
|
|
((LPDIRECT3DTEXTURE8)m_ptexNew)->GetLevelDesc(0, &sd);
|
|
if(sd.Format != D3DFMT_A8R8G8B8 &&
|
|
sd.Format != D3DFMT_A1R5G5B5 &&
|
|
sd.Format != D3DFMT_A4R4G4B4 &&
|
|
sd.Format != D3DFMT_A8R3G3B2 &&
|
|
sd.Format != D3DFMT_DXT1 &&
|
|
sd.Format != D3DFMT_DXT3 &&
|
|
sd.Format != D3DFMT_DXT5 )
|
|
{
|
|
AfxMessageBox(ID_ERROR_NEEDALPHA);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
ReleasePpo(&m_ptexOrig);
|
|
m_ptexOrig = m_ptexNew;
|
|
m_ptexNew = NULL;
|
|
AfxGetMainWnd()->PostMessage(WM_COMMAND, ID_VIEW_ORIGINAL, 0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AfxMessageBox(ID_ERROR_NEEDALPHA);
|
|
return;
|
|
}
|
|
}
|
|
|
|
pmiptex = (LPDIRECT3DTEXTURE8)m_ptexOrig;
|
|
|
|
if (!PromptForBmp(&fileName))
|
|
return;
|
|
|
|
LPDIRECT3DSURFACE8 psurf;
|
|
if (FAILED(hr = pmiptex->GetSurfaceLevel(0, &psurf)))
|
|
return;
|
|
|
|
if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurf)))
|
|
return;
|
|
if (m_numMips > 1)
|
|
OnGenerateMipMaps();
|
|
else if (m_ptexNew != NULL)
|
|
{
|
|
((LPDIRECT3DTEXTURE8)m_ptexNew)->GetLevelDesc(0, &sd);
|
|
Compress(sd.Format, FALSE);
|
|
}
|
|
UpdateAllViews(NULL, 1);
|
|
}
|
|
|
|
|
|
HRESULT CDxtexDoc::LoadAlphaIntoSurface(CString& strPath, LPDIRECT3DSURFACE8 psurf)
|
|
{
|
|
HRESULT hr;
|
|
D3DSURFACE_DESC sd;
|
|
LPDIRECT3DDEVICE8 pd3ddev = PDxtexApp()->Pd3ddev();
|
|
LPDIRECT3DTEXTURE8 ptexAlpha;
|
|
LPDIRECT3DSURFACE8 psurfAlpha;
|
|
LPDIRECT3DSURFACE8 psurfTarget;
|
|
|
|
psurf->GetDesc(&sd);
|
|
|
|
// Load the alpha BMP into psurfAlpha, a new A8R8G8B8 surface
|
|
hr = D3DXCreateTextureFromFileEx(pd3ddev, strPath, sd.Width, sd.Height, 1, 0,
|
|
D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_TRIANGLE,
|
|
D3DX_FILTER_TRIANGLE, 0, NULL, NULL, &ptexAlpha);
|
|
hr = ptexAlpha->GetSurfaceLevel(0, &psurfAlpha);
|
|
|
|
// Copy the target surface into an A8R8G8B8 surface
|
|
hr = pd3ddev->CreateImageSurface(sd.Width, sd.Height, D3DFMT_A8R8G8B8, &psurfTarget);
|
|
hr = D3DXLoadSurfaceFromSurface(psurfTarget, NULL, NULL, psurf, NULL, NULL,
|
|
D3DX_FILTER_TRIANGLE, 0);
|
|
|
|
// Fill in the alpha channels of psurfTarget based on the blue channel of psurfAlpha
|
|
D3DLOCKED_RECT lrSrc;
|
|
D3DLOCKED_RECT lrDest;
|
|
|
|
hr = psurfAlpha->LockRect(&lrSrc, NULL, D3DLOCK_READONLY);
|
|
hr = psurfTarget->LockRect(&lrDest, NULL, 0);
|
|
|
|
DWORD xp;
|
|
DWORD yp;
|
|
DWORD* pdwRowSrc = (DWORD*)lrSrc.pBits;
|
|
DWORD* pdwRowDest = (DWORD*)lrDest.pBits;
|
|
DWORD* pdwSrc;
|
|
DWORD* pdwDest;
|
|
DWORD dwAlpha;
|
|
LONG dataBytesPerRow = 4 * sd.Width;
|
|
|
|
for (yp = 0; yp < sd.Height; yp++)
|
|
{
|
|
pdwSrc = pdwRowSrc;
|
|
pdwDest = pdwRowDest;
|
|
for (xp = 0; xp < sd.Width; xp++)
|
|
{
|
|
dwAlpha = *pdwSrc << 24;
|
|
*pdwDest &= 0x00ffffff;
|
|
*pdwDest |= dwAlpha;
|
|
|
|
pdwSrc++;
|
|
pdwDest++;
|
|
}
|
|
pdwRowSrc += lrSrc.Pitch / 4;
|
|
pdwRowDest += lrDest.Pitch / 4;
|
|
}
|
|
|
|
psurfAlpha->UnlockRect();
|
|
psurfTarget->UnlockRect();
|
|
|
|
// Copy psurfTarget back into real surface
|
|
hr = D3DXLoadSurfaceFromSurface(psurf, NULL, NULL, psurfTarget, NULL, NULL,
|
|
D3DX_FILTER_TRIANGLE, 0);
|
|
|
|
// Release allocated interfaces
|
|
ReleasePpo(&psurfTarget);
|
|
ReleasePpo(&psurfAlpha);
|
|
ReleasePpo(&ptexAlpha);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
BOOL CDxtexDoc::PromptForBmp(CString* pstrPath)
|
|
{
|
|
CFileDialog dlgFile(TRUE);
|
|
|
|
CString title;
|
|
VERIFY(title.LoadString(AFX_IDS_OPENFILE));
|
|
|
|
CString strFilter;
|
|
CString strDefault;
|
|
|
|
strFilter += "Image Files (*.dds, *.bmp, *.tga, *.jpg, *.png, *.dib)";
|
|
strFilter += (TCHAR)'\0'; // next string please
|
|
strFilter += _T("*.dds;*.bmp;*.tga;*.jpg;*.png;*.dib");
|
|
strFilter += (TCHAR)'\0'; // last string
|
|
dlgFile.m_ofn.nMaxCustFilter++;
|
|
|
|
// append the "*.*" all files filter
|
|
CString allFilter;
|
|
VERIFY(allFilter.LoadString(AFX_IDS_ALLFILTER));
|
|
strFilter += allFilter;
|
|
strFilter += (TCHAR)'\0'; // next string please
|
|
strFilter += _T("*.*");
|
|
strFilter += (TCHAR)'\0'; // last string
|
|
dlgFile.m_ofn.nMaxCustFilter++;
|
|
|
|
dlgFile.m_ofn.lpstrFilter = strFilter;
|
|
dlgFile.m_ofn.lpstrTitle = title;
|
|
dlgFile.m_ofn.lpstrFile = pstrPath->GetBuffer(_MAX_PATH);
|
|
|
|
INT_PTR nResult = dlgFile.DoModal();
|
|
pstrPath->ReleaseBuffer();
|
|
if (nResult != IDOK)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void CDxtexDoc::OpenSubsurface(D3DCUBEMAP_FACES FaceType, LONG lwMip, LONG lwSlice)
|
|
{
|
|
HRESULT hr;
|
|
CString fileName;
|
|
LPDIRECT3DDEVICE8 pd3ddev = PDxtexApp()->Pd3ddev();
|
|
LPDIRECT3DTEXTURE8 ptex = NULL;
|
|
LPDIRECT3DSURFACE8 psurfOrig = NULL;
|
|
LPDIRECT3DSURFACE8 psurfNew = NULL;
|
|
|
|
if (!PromptForBmp(&fileName))
|
|
return;
|
|
|
|
if (IsVolumeMap())
|
|
{
|
|
hr = D3DXCreateTextureFromFile(pd3ddev, fileName, &ptex);
|
|
hr = ptex->GetSurfaceLevel(0, &psurfOrig);
|
|
}
|
|
else if (IsCubeMap())
|
|
{
|
|
hr = ((LPDIRECT3DCUBETEXTURE8)m_ptexOrig)->GetCubeMapSurface(FaceType, lwMip, &psurfOrig);
|
|
if (m_ptexNew != NULL)
|
|
hr = ((LPDIRECT3DCUBETEXTURE8)m_ptexNew)->GetCubeMapSurface(FaceType, lwMip, &psurfNew);
|
|
hr = D3DXLoadSurfaceFromFile(psurfOrig, NULL, NULL, fileName, NULL, D3DX_FILTER_TRIANGLE, 0, NULL);
|
|
}
|
|
else
|
|
{
|
|
hr = ((LPDIRECT3DTEXTURE8)m_ptexOrig)->GetSurfaceLevel(lwMip, &psurfOrig);
|
|
if (m_ptexNew != NULL)
|
|
hr = ((LPDIRECT3DTEXTURE8)m_ptexNew)->GetSurfaceLevel(lwMip, &psurfNew);
|
|
hr = D3DXLoadSurfaceFromFile(psurfOrig, NULL, NULL, fileName, NULL, D3DX_FILTER_TRIANGLE, 0, NULL);
|
|
}
|
|
|
|
// Look for "foo_a.bmp" for alpha channel
|
|
int i = fileName.ReverseFind('.');
|
|
fileName = fileName.Left(i) + "_a.bmp";
|
|
CFileStatus status;
|
|
if (CFile::GetStatus(fileName, status))
|
|
{
|
|
if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfOrig)))
|
|
return;
|
|
}
|
|
|
|
if (IsVolumeMap())
|
|
{
|
|
LPDIRECT3DVOLUME8 pvol;
|
|
hr = ((LPDIRECT3DVOLUMETEXTURE8)m_ptexOrig)->GetVolumeLevel(lwMip, &pvol);
|
|
hr = LoadVolumeSliceFromSurface(pvol, lwSlice, psurfOrig);
|
|
ReleasePpo(&pvol);
|
|
if (m_ptexNew)
|
|
{
|
|
hr = ((LPDIRECT3DVOLUMETEXTURE8)m_ptexNew)->GetVolumeLevel(lwMip, &pvol);
|
|
hr = LoadVolumeSliceFromSurface(pvol, lwSlice, psurfOrig);
|
|
ReleasePpo(&pvol);
|
|
}
|
|
}
|
|
else if (psurfNew != NULL)
|
|
{
|
|
hr = D3DXLoadSurfaceFromSurface(psurfNew, NULL, NULL, psurfOrig, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
|
|
}
|
|
|
|
ReleasePpo(&psurfOrig);
|
|
ReleasePpo(&psurfNew);
|
|
ReleasePpo(&ptex);
|
|
|
|
SetModifiedFlag(TRUE);
|
|
UpdateAllViews(NULL, 1);
|
|
}
|
|
|
|
|
|
void CDxtexDoc::OpenAlphaSubsurface(D3DCUBEMAP_FACES FaceType, LONG lwMip, LONG lwSlice)
|
|
{
|
|
HRESULT hr;
|
|
CString fileName;
|
|
LPDIRECT3DDEVICE8 pd3ddev = PDxtexApp()->Pd3ddev();
|
|
LPDIRECT3DTEXTURE8 ptexOrig = NULL;
|
|
LPDIRECT3DTEXTURE8 ptexNew = NULL;
|
|
LPDIRECT3DSURFACE8 psurfOrig = NULL;
|
|
LPDIRECT3DSURFACE8 psurfNew = NULL;
|
|
LPDIRECT3DVOLUME8 pvolOrig = NULL;
|
|
LPDIRECT3DVOLUME8 pvolNew = NULL;
|
|
D3DSURFACE_DESC sd;
|
|
DWORD dwWidth = m_dwWidth;
|
|
DWORD dwHeight = m_dwHeight;
|
|
|
|
if (IsVolumeMap())
|
|
{
|
|
for (int i = 0; i < lwMip; i++)
|
|
{
|
|
dwWidth /= 2;
|
|
dwHeight /= 2;
|
|
}
|
|
hr = pd3ddev->CreateTexture(dwWidth, dwHeight, 1,
|
|
0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &ptexOrig);
|
|
hr = ptexOrig->GetSurfaceLevel(0, &psurfOrig);
|
|
hr = ((LPDIRECT3DVOLUMETEXTURE8)m_ptexOrig)->GetVolumeLevel(lwMip, &pvolOrig);
|
|
hr = LoadSurfaceFromVolumeSlice(pvolOrig, lwSlice, psurfOrig);
|
|
if (m_ptexNew != NULL)
|
|
{
|
|
hr = pd3ddev->CreateTexture(dwWidth, dwHeight, 1,
|
|
0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &ptexNew);
|
|
hr = ptexNew->GetSurfaceLevel(0, &psurfOrig);
|
|
hr = ((LPDIRECT3DVOLUMETEXTURE8)m_ptexOrig)->GetVolumeLevel(lwMip, &pvolNew);
|
|
hr = LoadSurfaceFromVolumeSlice(pvolNew, lwSlice, psurfOrig);
|
|
}
|
|
}
|
|
else if (IsCubeMap())
|
|
{
|
|
hr = ((LPDIRECT3DCUBETEXTURE8)m_ptexOrig)->GetCubeMapSurface(FaceType, lwMip, &psurfOrig);
|
|
((LPDIRECT3DCUBETEXTURE8)m_ptexOrig)->GetLevelDesc(lwMip, &sd);
|
|
if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
|
|
{
|
|
AfxMessageBox(ID_ERROR_PREMULTALPHA);
|
|
return;
|
|
}
|
|
if (m_ptexNew != NULL)
|
|
{
|
|
hr = ((LPDIRECT3DCUBETEXTURE8)m_ptexNew)->GetCubeMapSurface(FaceType, lwMip, &psurfNew);
|
|
((LPDIRECT3DCUBETEXTURE8)m_ptexNew)->GetLevelDesc(lwMip, &sd);
|
|
if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
|
|
{
|
|
AfxMessageBox(ID_ERROR_PREMULTALPHA);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
BOOL bAlphaFound = FALSE;
|
|
hr = ((LPDIRECT3DTEXTURE8)m_ptexOrig)->GetSurfaceLevel(lwMip, &psurfOrig);
|
|
((LPDIRECT3DTEXTURE8)m_ptexOrig)->GetLevelDesc(lwMip, &sd);
|
|
if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
|
|
{
|
|
AfxMessageBox(ID_ERROR_PREMULTALPHA);
|
|
return;
|
|
}
|
|
|
|
// Check if the original has alpha
|
|
if( sd.Format == D3DFMT_A8R8G8B8 ||
|
|
sd.Format == D3DFMT_A1R5G5B5 ||
|
|
sd.Format == D3DFMT_A4R4G4B4 ||
|
|
sd.Format == D3DFMT_A8R3G3B2 ||
|
|
sd.Format == D3DFMT_DXT1 ||
|
|
sd.Format == D3DFMT_DXT3 ||
|
|
sd.Format == D3DFMT_DXT5 )
|
|
{
|
|
bAlphaFound = TRUE;
|
|
}
|
|
|
|
if (m_ptexNew != NULL)
|
|
{
|
|
hr = ((LPDIRECT3DTEXTURE8)m_ptexNew)->GetSurfaceLevel(lwMip, &psurfNew);
|
|
((LPDIRECT3DTEXTURE8)m_ptexNew)->GetLevelDesc(lwMip, &sd);
|
|
if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
|
|
{
|
|
AfxMessageBox(ID_ERROR_PREMULTALPHA);
|
|
return;
|
|
}
|
|
// Check if the new has alpha
|
|
if( sd.Format == D3DFMT_A8R8G8B8 ||
|
|
sd.Format == D3DFMT_A1R5G5B5 ||
|
|
sd.Format == D3DFMT_A4R4G4B4 ||
|
|
sd.Format == D3DFMT_A8R3G3B2 ||
|
|
sd.Format == D3DFMT_DXT1 ||
|
|
sd.Format == D3DFMT_DXT3 ||
|
|
sd.Format == D3DFMT_DXT5 )
|
|
{
|
|
bAlphaFound = TRUE;
|
|
}
|
|
}
|
|
|
|
if( bAlphaFound == FALSE )
|
|
{
|
|
AfxMessageBox(ID_ERROR_NEEDALPHA);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!PromptForBmp(&fileName))
|
|
return;
|
|
|
|
if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfOrig)))
|
|
return;
|
|
|
|
if (psurfNew != NULL)
|
|
{
|
|
if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfNew)))
|
|
return;
|
|
}
|
|
|
|
if (pvolOrig != NULL)
|
|
{
|
|
hr = LoadVolumeSliceFromSurface(pvolOrig, lwSlice, psurfOrig);
|
|
}
|
|
if (pvolNew != NULL)
|
|
{
|
|
hr = LoadVolumeSliceFromSurface(pvolNew, lwSlice, psurfNew);
|
|
}
|
|
|
|
ReleasePpo(&psurfOrig);
|
|
ReleasePpo(&psurfNew);
|
|
ReleasePpo(&ptexOrig);
|
|
ReleasePpo(&ptexNew);
|
|
ReleasePpo(&pvolOrig);
|
|
ReleasePpo(&pvolNew);
|
|
|
|
SetModifiedFlag(TRUE);
|
|
UpdateAllViews(NULL, 1);
|
|
}
|
|
|
|
|
|
void CDxtexDoc::OnFormatChangeCubeMapFaces()
|
|
{
|
|
HRESULT hr;
|
|
LPDIRECT3DDEVICE8 pd3ddev = PDxtexApp()->Pd3ddev();
|
|
D3DSURFACE_DESC sd;
|
|
LPDIRECT3DCUBETEXTURE8 ptexCube;
|
|
DWORD iLevel;
|
|
LPDIRECT3DSURFACE8 psurfSrc;
|
|
LPDIRECT3DSURFACE8 psurfDest;
|
|
|
|
CCubeMapDlg cubeMapDlg;
|
|
if (IDCANCEL == cubeMapDlg.DoModal())
|
|
return;
|
|
|
|
// Change m_ptexOrig into a cubemap
|
|
((LPDIRECT3DTEXTURE8)m_ptexOrig)->GetLevelDesc(0, &sd);
|
|
hr = D3DXCreateCubeTexture(pd3ddev, m_dwWidth, m_numMips, 0, sd.Format, D3DPOOL_MANAGED, &ptexCube);
|
|
for (iLevel = 0; iLevel < m_numMips; iLevel++)
|
|
{
|
|
hr = ((LPDIRECT3DTEXTURE8)m_ptexOrig)->GetSurfaceLevel(iLevel, &psurfSrc);
|
|
hr = ptexCube->GetCubeMapSurface((D3DCUBEMAP_FACES)cubeMapDlg.m_iFace, iLevel, &psurfDest);
|
|
hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL,
|
|
psurfSrc, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
|
|
ReleasePpo(&psurfSrc);
|
|
ReleasePpo(&psurfDest);
|
|
}
|
|
ReleasePpo(&m_ptexOrig);
|
|
m_ptexOrig = ptexCube;
|
|
|
|
// Change m_ptexNew into a cubemap too
|
|
if (m_ptexNew != NULL)
|
|
{
|
|
((LPDIRECT3DTEXTURE8)m_ptexNew)->GetLevelDesc(0, &sd);
|
|
hr = D3DXCreateCubeTexture(pd3ddev, m_dwWidth, m_numMips, 0, sd.Format, D3DPOOL_MANAGED, &ptexCube);
|
|
for (iLevel = 0; iLevel < m_numMips; iLevel++)
|
|
{
|
|
hr = ((LPDIRECT3DTEXTURE8)m_ptexNew)->GetSurfaceLevel(iLevel, &psurfSrc);
|
|
hr = ptexCube->GetCubeMapSurface((D3DCUBEMAP_FACES)cubeMapDlg.m_iFace, iLevel, &psurfDest);
|
|
hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL,
|
|
psurfSrc, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
|
|
ReleasePpo(&psurfSrc);
|
|
ReleasePpo(&psurfDest);
|
|
}
|
|
ReleasePpo(&m_ptexNew);
|
|
m_ptexNew = ptexCube;
|
|
}
|
|
m_dwCubeMapFlags = DDS_CUBEMAP_ALLFACES;
|
|
SetModifiedFlag();
|
|
UpdateAllViews(NULL, 1); // tell CView to pick up new surface pointers
|
|
}
|
|
|
|
|
|
void CDxtexDoc::OnFormatMakeIntoVolumeMap()
|
|
{
|
|
HRESULT hr;
|
|
LPDIRECT3DDEVICE8 pd3ddev = PDxtexApp()->Pd3ddev();
|
|
D3DSURFACE_DESC sd;
|
|
LPDIRECT3DVOLUMETEXTURE8 ptexVolume;
|
|
DWORD iLevel;
|
|
LPDIRECT3DSURFACE8 psurfSrc;
|
|
LPDIRECT3DVOLUME8 pvolumeDest;
|
|
UINT numLayers;
|
|
|
|
CVolumeMapDlg volumeMapDlg;
|
|
if (IDCANCEL == volumeMapDlg.DoModal())
|
|
return;
|
|
|
|
numLayers = (1 << volumeMapDlg.m_powLayers) * 2;
|
|
|
|
// Change m_ptexOrig into a volumemap
|
|
((LPDIRECT3DTEXTURE8)m_ptexOrig)->GetLevelDesc(0, &sd);
|
|
hr = pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, numLayers,
|
|
m_numMips, 0, sd.Format, D3DPOOL_SYSTEMMEM, &ptexVolume);
|
|
if (FAILED(hr))
|
|
return;
|
|
for (iLevel = 0; iLevel < m_numMips; iLevel++)
|
|
{
|
|
hr = ((LPDIRECT3DTEXTURE8)m_ptexOrig)->GetSurfaceLevel(iLevel, &psurfSrc);
|
|
hr = ptexVolume->GetVolumeLevel(iLevel, &pvolumeDest);
|
|
hr = LoadVolumeSliceFromSurface(pvolumeDest, 0, psurfSrc);
|
|
ReleasePpo(&psurfSrc);
|
|
ReleasePpo(&pvolumeDest);
|
|
}
|
|
ReleasePpo(&m_ptexOrig);
|
|
m_ptexOrig = ptexVolume;
|
|
|
|
// Change m_ptexNew into a volumemap too
|
|
if (m_ptexNew != NULL)
|
|
{
|
|
((LPDIRECT3DTEXTURE8)m_ptexNew)->GetLevelDesc(0, &sd);
|
|
hr = pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, numLayers,
|
|
m_numMips, 0, sd.Format, D3DPOOL_SYSTEMMEM, &ptexVolume);
|
|
if (FAILED(hr))
|
|
return;
|
|
for (iLevel = 0; iLevel < m_numMips; iLevel++)
|
|
{
|
|
hr = ((LPDIRECT3DTEXTURE8)m_ptexNew)->GetSurfaceLevel(iLevel, &psurfSrc);
|
|
hr = ptexVolume->GetVolumeLevel(iLevel, &pvolumeDest);
|
|
hr = LoadVolumeSliceFromSurface(pvolumeDest, 0, psurfSrc);
|
|
ReleasePpo(&psurfSrc);
|
|
ReleasePpo(&pvolumeDest);
|
|
}
|
|
ReleasePpo(&m_ptexNew);
|
|
m_ptexNew = ptexVolume;
|
|
}
|
|
m_dwDepth = numLayers;
|
|
SetModifiedFlag();
|
|
UpdateAllViews(NULL, 1); // tell CView to pick up new surface pointers
|
|
}
|
|
|
|
|
|
HRESULT CDxtexDoc::LoadVolumeSliceFromSurface(LPDIRECT3DVOLUME8 pVolume, UINT iSlice, LPDIRECT3DSURFACE8 psurf)
|
|
{
|
|
HRESULT hr;
|
|
D3DSURFACE_DESC sd;
|
|
D3DVOLUME_DESC vd;
|
|
D3DLOCKED_RECT lr;
|
|
D3DBOX boxSrc;
|
|
D3DBOX boxDest;
|
|
|
|
psurf->GetDesc(&sd);
|
|
pVolume->GetDesc(&vd);
|
|
|
|
boxSrc.Left = 0;
|
|
boxSrc.Right = sd.Width;
|
|
boxSrc.Top = 0;
|
|
boxSrc.Bottom = sd.Height;
|
|
boxSrc.Front = 0;
|
|
boxSrc.Back = 1;
|
|
|
|
boxDest.Left = 0;
|
|
boxDest.Right = vd.Width;
|
|
boxDest.Top = 0;
|
|
boxDest.Bottom = vd.Height;
|
|
boxDest.Front = iSlice;
|
|
boxDest.Back = iSlice + 1;
|
|
|
|
hr = psurf->LockRect(&lr, NULL, 0);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
hr = D3DXLoadVolumeFromMemory(pVolume, NULL, &boxDest, lr.pBits, sd.Format, lr.Pitch,
|
|
0, NULL, &boxSrc, D3DX_FILTER_TRIANGLE, 0);
|
|
|
|
psurf->UnlockRect();
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CDxtexDoc::LoadSurfaceFromVolumeSlice(LPDIRECT3DVOLUME8 pVolume, UINT iSlice, LPDIRECT3DSURFACE8 psurf)
|
|
{
|
|
HRESULT hr;
|
|
D3DVOLUME_DESC vd;
|
|
D3DLOCKED_BOX lb;
|
|
D3DBOX box;
|
|
RECT rc;
|
|
|
|
pVolume->GetDesc(&vd);
|
|
|
|
box.Left = 0;
|
|
box.Right = vd.Width;
|
|
box.Top = 0;
|
|
box.Bottom = vd.Height;
|
|
box.Front = iSlice;
|
|
box.Back = iSlice + 1;
|
|
|
|
rc.left = 0;
|
|
rc.right = vd.Width;
|
|
rc.top = 0;
|
|
rc.bottom = vd.Height;
|
|
|
|
hr = pVolume->LockBox(&lb, &box, 0);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
hr = D3DXLoadSurfaceFromMemory(psurf, NULL, NULL, lb.pBits, vd.Format, lb.RowPitch,
|
|
NULL, &rc, D3DX_FILTER_TRIANGLE, 0);
|
|
|
|
pVolume->UnlockBox();
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CDxtexDoc::BltAllLevels(D3DCUBEMAP_FACES FaceType,
|
|
LPDIRECT3DBASETEXTURE8 ptexSrc, LPDIRECT3DBASETEXTURE8 ptexDest)
|
|
{
|
|
HRESULT hr;
|
|
LPDIRECT3DTEXTURE8 pmiptexSrc;
|
|
LPDIRECT3DTEXTURE8 pmiptexDest;
|
|
LPDIRECT3DCUBETEXTURE8 pcubetexSrc;
|
|
LPDIRECT3DCUBETEXTURE8 pcubetexDest;
|
|
LPDIRECT3DVOLUMETEXTURE8 pvoltexSrc;
|
|
LPDIRECT3DVOLUMETEXTURE8 pvoltexDest;
|
|
DWORD iLevel;
|
|
|
|
if (IsVolumeMap())
|
|
{
|
|
pvoltexSrc = (LPDIRECT3DVOLUMETEXTURE8)ptexSrc;
|
|
pvoltexDest = (LPDIRECT3DVOLUMETEXTURE8)ptexDest;
|
|
}
|
|
else if (IsCubeMap())
|
|
{
|
|
pcubetexSrc = (LPDIRECT3DCUBETEXTURE8)ptexSrc;
|
|
pcubetexDest = (LPDIRECT3DCUBETEXTURE8)ptexDest;
|
|
}
|
|
else
|
|
{
|
|
pmiptexSrc = (LPDIRECT3DTEXTURE8)ptexSrc;
|
|
pmiptexDest = (LPDIRECT3DTEXTURE8)ptexDest;
|
|
}
|
|
|
|
for (iLevel = 0; iLevel < m_numMips; iLevel++)
|
|
{
|
|
if (IsVolumeMap())
|
|
{
|
|
LPDIRECT3DVOLUME8 pvolSrc = NULL;
|
|
LPDIRECT3DVOLUME8 pvolDest = NULL;
|
|
hr = pvoltexSrc->GetVolumeLevel(iLevel, &pvolSrc);
|
|
hr = pvoltexDest->GetVolumeLevel(iLevel, &pvolDest);
|
|
hr = D3DXLoadVolumeFromVolume(pvolDest, NULL, NULL,
|
|
pvolSrc, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
|
|
ReleasePpo(&pvolSrc);
|
|
ReleasePpo(&pvolDest);
|
|
}
|
|
else if (IsCubeMap())
|
|
{
|
|
LPDIRECT3DSURFACE8 psurfSrc = NULL;
|
|
LPDIRECT3DSURFACE8 psurfDest = NULL;
|
|
hr = pcubetexSrc->GetCubeMapSurface(FaceType, iLevel, &psurfSrc);
|
|
hr = pcubetexDest->GetCubeMapSurface(FaceType, iLevel, &psurfDest);
|
|
hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL,
|
|
psurfSrc, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
|
|
ReleasePpo(&psurfSrc);
|
|
ReleasePpo(&psurfDest);
|
|
}
|
|
else
|
|
{
|
|
LPDIRECT3DSURFACE8 psurfSrc = NULL;
|
|
LPDIRECT3DSURFACE8 psurfDest = NULL;
|
|
hr = pmiptexSrc->GetSurfaceLevel(iLevel, &psurfSrc);
|
|
hr = pmiptexDest->GetSurfaceLevel(iLevel, &psurfDest);
|
|
hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL,
|
|
psurfSrc, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
|
|
ReleasePpo(&psurfSrc);
|
|
ReleasePpo(&psurfDest);
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
void CDxtexDoc::OpenCubeFace(D3DCUBEMAP_FACES FaceType)
|
|
{
|
|
HRESULT hr;
|
|
CString fileName;
|
|
LPDIRECT3DSURFACE8 psurfOrig = NULL;
|
|
LPDIRECT3DSURFACE8 psurfNew = NULL;
|
|
|
|
if (!IsCubeMap())
|
|
return;
|
|
|
|
hr = ((LPDIRECT3DCUBETEXTURE8)m_ptexOrig)->GetCubeMapSurface(FaceType, 0, &psurfOrig);
|
|
if (m_ptexNew != NULL)
|
|
hr = ((LPDIRECT3DCUBETEXTURE8)m_ptexNew)->GetCubeMapSurface(FaceType, 0, &psurfNew);
|
|
|
|
if (!PromptForBmp(&fileName))
|
|
return;
|
|
|
|
hr = D3DXLoadSurfaceFromFile(psurfOrig, NULL, NULL, fileName, NULL, D3DX_FILTER_TRIANGLE, 0, NULL);
|
|
|
|
// Look for "foo_a.bmp" for alpha channel
|
|
int i = fileName.ReverseFind('.');
|
|
fileName = fileName.Left(i) + "_a.bmp";
|
|
CFileStatus status;
|
|
if (CFile::GetStatus(fileName, status))
|
|
{
|
|
if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfOrig)))
|
|
return;
|
|
}
|
|
|
|
if (m_numMips > 1)
|
|
{
|
|
hr = D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE8)m_ptexOrig, NULL, 0, D3DX_FILTER_TRIANGLE);
|
|
}
|
|
|
|
|
|
if (psurfNew != NULL)
|
|
{
|
|
hr = D3DXLoadSurfaceFromSurface(psurfNew, NULL, NULL, psurfOrig, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
|
|
|
|
if (m_numMips > 1)
|
|
{
|
|
hr = D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE8)m_ptexNew, NULL, 0, D3DX_FILTER_TRIANGLE);
|
|
}
|
|
}
|
|
|
|
ReleasePpo(&psurfOrig);
|
|
ReleasePpo(&psurfNew);
|
|
|
|
SetModifiedFlag(TRUE);
|
|
UpdateAllViews(NULL, 1);
|
|
}
|
|
|
|
|
|
void CDxtexDoc::OpenAlphaCubeFace(D3DCUBEMAP_FACES FaceType)
|
|
{
|
|
HRESULT hr;
|
|
CString fileName;
|
|
LPDIRECT3DSURFACE8 psurfOrig = NULL;
|
|
LPDIRECT3DSURFACE8 psurfNew = NULL;
|
|
D3DSURFACE_DESC sd;
|
|
|
|
if (!IsCubeMap())
|
|
return;
|
|
|
|
hr = ((LPDIRECT3DCUBETEXTURE8)m_ptexOrig)->GetCubeMapSurface(FaceType, 0, &psurfOrig);
|
|
((LPDIRECT3DCUBETEXTURE8)m_ptexOrig)->GetLevelDesc(0, &sd);
|
|
if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
|
|
{
|
|
AfxMessageBox(ID_ERROR_PREMULTALPHA);
|
|
return;
|
|
}
|
|
if (m_ptexNew != NULL)
|
|
{
|
|
hr = ((LPDIRECT3DCUBETEXTURE8)m_ptexNew)->GetCubeMapSurface(FaceType, 0, &psurfNew);
|
|
}
|
|
|
|
if (!PromptForBmp(&fileName))
|
|
return;
|
|
|
|
if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfOrig)))
|
|
return;
|
|
|
|
if (psurfNew != NULL)
|
|
{
|
|
if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfNew)))
|
|
return;
|
|
}
|
|
|
|
if (m_numMips > 1)
|
|
{
|
|
hr = D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE8)m_ptexOrig, NULL, 0, D3DX_FILTER_TRIANGLE);
|
|
}
|
|
|
|
|
|
if (psurfNew != NULL)
|
|
{
|
|
hr = D3DXLoadSurfaceFromSurface(psurfNew, NULL, NULL, psurfOrig, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
|
|
|
|
if (m_numMips > 1)
|
|
{
|
|
hr = D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE8)m_ptexNew, NULL, 0, D3DX_FILTER_TRIANGLE);
|
|
}
|
|
}
|
|
|
|
ReleasePpo(&psurfOrig);
|
|
ReleasePpo(&psurfNew);
|
|
|
|
SetModifiedFlag(TRUE);
|
|
UpdateAllViews(NULL, 1);
|
|
}
|
|
|
|
|
|
DWORD CDxtexDoc::DwDepthAt(LONG lwMip)
|
|
{
|
|
DWORD dwDepth = m_dwDepth;
|
|
while (lwMip > 0 && dwDepth > 1)
|
|
{
|
|
dwDepth /= 2;
|
|
lwMip--;
|
|
}
|
|
return dwDepth;
|
|
}
|
|
|
|
|
|
void CDxtexDoc::OnFormatChangeSurfaceFmt()
|
|
{
|
|
CChangeFmtDlg changeFmtDlg;
|
|
LPDIRECT3DBASETEXTURE8 ptex;
|
|
|
|
ptex = (m_ptexNew == NULL ? m_ptexOrig : m_ptexNew);
|
|
|
|
if (IsVolumeMap())
|
|
{
|
|
D3DVOLUME_DESC vd;
|
|
((LPDIRECT3DVOLUMETEXTURE8)ptex)->GetLevelDesc(0, &vd);
|
|
changeFmtDlg.m_fmt = vd.Format;
|
|
}
|
|
else if (IsCubeMap())
|
|
{
|
|
D3DSURFACE_DESC sd;
|
|
((LPDIRECT3DCUBETEXTURE8)ptex)->GetLevelDesc(0, &sd);
|
|
changeFmtDlg.m_fmt = sd.Format;
|
|
}
|
|
else
|
|
{
|
|
D3DSURFACE_DESC sd;
|
|
((LPDIRECT3DTEXTURE8)ptex)->GetLevelDesc(0, &sd);
|
|
changeFmtDlg.m_fmt = sd.Format;
|
|
}
|
|
|
|
changeFmtDlg.m_bVolume = IsVolumeMap();
|
|
|
|
if (IDCANCEL == changeFmtDlg.DoModal())
|
|
return;
|
|
|
|
Compress(changeFmtDlg.m_fmt, TRUE);
|
|
}
|
|
|
|
|
|
void CDxtexDoc::OnUpdateFileOpenAlpha(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(!IsCubeMap() && !IsVolumeMap());
|
|
}
|
|
|
|
|
|
void CDxtexDoc::OnUpdateFormatGenerateMipmaps(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(m_numMips <= 1);
|
|
}
|
|
|
|
|
|
void CDxtexDoc::OnUpdateFormatChangeCubeMapFaces(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(!IsCubeMap() && !IsVolumeMap());
|
|
}
|
|
|
|
|
|
void CDxtexDoc::OnUpdateFormatMakeIntoVolumeMap(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(!IsCubeMap() && !IsVolumeMap());
|
|
}
|
|
|
|
|