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>
1071 lines
28 KiB
C++
1071 lines
28 KiB
C++
// dxtexView.cpp : implementation of the CDxtexView class
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "dxtex.h"
|
|
#include "dxtexDoc.h"
|
|
#include "dxtexView.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
// Our custom vertex type
|
|
struct CUSTOMVERTEX
|
|
{
|
|
FLOAT x, y, z;
|
|
FLOAT rhw;
|
|
DWORD color;
|
|
FLOAT tu, tv; // The texture coordinates
|
|
};
|
|
|
|
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1)
|
|
|
|
|
|
IMPLEMENT_DYNCREATE(CDxtexView, CScrollView)
|
|
|
|
BEGIN_MESSAGE_MAP(CDxtexView, CScrollView)
|
|
//{{AFX_MSG_MAP(CDxtexView)
|
|
ON_WM_LBUTTONUP()
|
|
ON_COMMAND(ID_FILE_OPENSUBSURFACE, OnFileOpenSubsurface)
|
|
ON_COMMAND(ID_FILE_OPENALPHASUBSURFACE, OnFileOpenAlphaSubsurface)
|
|
ON_COMMAND(ID_FILE_OPENFACE, OnFileOpenFace)
|
|
ON_COMMAND(ID_FILE_OPENALPHAFACE, OnFileOpenAlphaFace)
|
|
ON_COMMAND(ID_VIEW_ORIGINAL, OnViewOriginal)
|
|
ON_COMMAND(ID_VIEW_COMPRESSED, OnViewCompressed)
|
|
ON_COMMAND(ID_VIEW_SMALLERMIPLEVEL, OnViewSmallerMipLevel)
|
|
ON_COMMAND(ID_VIEW_LARGERMIPLEVEL, OnViewLargerMipLevel)
|
|
ON_COMMAND(ID_VIEW_ALPHACHANNEL, OnViewAlphaChannel)
|
|
ON_COMMAND(ID_VIEW_ZOOMIN, OnViewZoomIn)
|
|
ON_COMMAND(ID_VIEW_ZOOMOUT, OnViewZoomOut)
|
|
ON_COMMAND(ID_VIEW_CHANGEBACKGROUNDCOLOR, OnViewChangeBackgroundColor)
|
|
ON_COMMAND(ID_VIEW_NEGX, OnViewNegX)
|
|
ON_COMMAND(ID_VIEW_POSX, OnViewPosX)
|
|
ON_COMMAND(ID_VIEW_NEGY, OnViewNegY)
|
|
ON_COMMAND(ID_VIEW_POSY, OnViewPosY)
|
|
ON_COMMAND(ID_VIEW_NEGZ, OnViewNegZ)
|
|
ON_COMMAND(ID_VIEW_POSZ, OnViewPosZ)
|
|
ON_COMMAND(ID_VIEW_HIGHERVOLUMESLICE, OnViewHigherVolumeSlice)
|
|
ON_COMMAND(ID_VIEW_LOWERVOLUMESLICE, OnViewLowerVolumeSlice)
|
|
ON_UPDATE_COMMAND_UI(ID_FILE_OPENSUBSURFACE, OnUpdateFileOpenSubsurface)
|
|
ON_UPDATE_COMMAND_UI(ID_FILE_OPENALPHASUBSURFACE, OnUpdateFileOpenAlphaSubsurface)
|
|
ON_UPDATE_COMMAND_UI(ID_FILE_OPENFACE, OnUpdateFileOpenFace)
|
|
ON_UPDATE_COMMAND_UI(ID_FILE_OPENALPHAFACE, OnUpdateFileOpenAlphaFace)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_ORIGINAL, OnUpdateViewOriginal)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_COMPRESSED, OnUpdateViewCompressed)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_ALPHACHANNEL, OnUpdateViewAlphaChannel)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_LARGERMIPLEVEL, OnUpdateViewLargerMipLevel)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_SMALLERMIPLEVEL, OnUpdateViewSmallerMipLevel)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_ZOOMIN, OnUpdateViewZoomIn)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_ZOOMOUT, OnUpdateViewZoomOut)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_NEGX, OnUpdateViewNegX)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_POSX, OnUpdateViewPosX)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_NEGY, OnUpdateViewNegY)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_POSY, OnUpdateViewPosY)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_NEGZ, OnUpdateViewNegZ)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_POSZ, OnUpdateViewPosZ)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_HIGHERVOLUMESLICE, OnUpdateViewHigherVolumeSlice)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_LOWERVOLUMESLICE, OnUpdateViewLowerVolumeSlice)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
CDxtexView::CDxtexView()
|
|
{
|
|
m_pVB = NULL;
|
|
m_ptexCur = NULL;
|
|
m_pSwapChain = NULL;
|
|
m_lwMipCur = 0;
|
|
m_CubeFaceCur = D3DCUBEMAP_FACE_FORCE_DWORD;
|
|
m_lwSliceCur = -1;
|
|
m_fZoom = 1.0f;
|
|
m_bViewOrig = TRUE;
|
|
m_bViewAlpha = FALSE;
|
|
}
|
|
|
|
|
|
CDxtexView::~CDxtexView()
|
|
{
|
|
ReleasePpo(&m_pVB);
|
|
ReleasePpo(&m_ptexCur);
|
|
ReleasePpo(&m_pSwapChain);
|
|
}
|
|
|
|
|
|
// Note: repaints don't require re-rendering, just recopy from back buffer to view's DC
|
|
void CDxtexView::OnDraw(CDC* pDC)
|
|
{
|
|
CDxtexDoc* pDoc = GetDocument();
|
|
ASSERT_VALID(pDoc);
|
|
|
|
HRESULT hr;
|
|
CRect rcSrc;
|
|
CRect rcDest;
|
|
|
|
rcSrc = m_rcSrc;
|
|
rcDest = m_rcDest;
|
|
|
|
rcDest.OffsetRect(pDC->GetViewportOrg());
|
|
|
|
// REVIEW: only update dirty region?
|
|
if (m_pSwapChain != NULL)
|
|
hr = m_pSwapChain->Present(&rcSrc, &rcDest, GetSafeHwnd(), NULL);
|
|
}
|
|
|
|
|
|
#ifdef _DEBUG
|
|
void CDxtexView::AssertValid() const
|
|
{
|
|
CScrollView::AssertValid();
|
|
}
|
|
|
|
|
|
void CDxtexView::Dump(CDumpContext& dc) const
|
|
{
|
|
CScrollView::Dump(dc);
|
|
}
|
|
|
|
|
|
CDxtexDoc* CDxtexView::GetDocument() // non-debug version is inline
|
|
{
|
|
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDxtexDoc)));
|
|
return (CDxtexDoc*)m_pDocument;
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
|
|
void CDxtexView::OnLButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
// Button click means toggle compressed / uncompressed view
|
|
if (m_bViewOrig)
|
|
OnViewCompressed();
|
|
else
|
|
OnViewOriginal();
|
|
|
|
CScrollView::OnLButtonUp(nFlags, point);
|
|
}
|
|
|
|
|
|
void CDxtexView::OnInitialUpdate()
|
|
{
|
|
#ifdef _WIN64
|
|
SetClassLongPtr(GetSafeHwnd(), GCLP_HBRBACKGROUND, (LONG_PTR)CreateSolidBrush(RGB(100, 100, 120)));
|
|
#else
|
|
SetClassLong(GetSafeHwnd(), GCL_HBRBACKGROUND, (LONG)CreateSolidBrush(RGB(100, 100, 120)));
|
|
#endif
|
|
|
|
if (GetDocument()->IsCubeMap())
|
|
m_CubeFaceCur = D3DCUBEMAP_FACE_POSITIVE_X;
|
|
else
|
|
m_CubeFaceCur = D3DCUBEMAP_FACE_FORCE_DWORD;
|
|
if (GetDocument()->IsVolumeMap())
|
|
m_lwSliceCur = 0;
|
|
BuildViewSurface(m_bViewOrig, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
|
|
UpdateDevice();
|
|
CreateVertexBuffer();
|
|
RenderScene();
|
|
|
|
SetScrollSizes(MM_TEXT, CSize(m_rcDest.Width(), m_rcDest.Height()));
|
|
ResizeParentToFit();
|
|
|
|
CScrollView::OnInitialUpdate();
|
|
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
}
|
|
|
|
|
|
VOID CDxtexView::GetImageInfo(CString& strInfo)
|
|
{
|
|
LPDIRECT3DBASETEXTURE8 ptex;
|
|
D3DSURFACE_DESC sd;
|
|
D3DVOLUME_DESC vd;
|
|
D3DFORMAT fmt;
|
|
DWORD dwWidth;
|
|
DWORD dwHeight;
|
|
DWORD dwDepth;
|
|
CString strFormat;
|
|
TCHAR sz[100];
|
|
DWORD dwBytes = 0;
|
|
UINT iLevel;
|
|
|
|
if (m_bViewOrig)
|
|
ptex = GetDocument()->PtexOrig();
|
|
else
|
|
ptex = GetDocument()->PtexNew();
|
|
|
|
if (GetDocument()->IsVolumeMap())
|
|
{
|
|
((LPDIRECT3DVOLUMETEXTURE8)ptex)->GetLevelDesc(0, &vd);
|
|
fmt = vd.Format;
|
|
dwWidth = vd.Width;
|
|
dwHeight = vd.Height;
|
|
dwDepth = vd.Depth;
|
|
}
|
|
else if (!GetDocument()->IsCubeMap())
|
|
{
|
|
((LPDIRECT3DTEXTURE8)ptex)->GetLevelDesc(0, &sd);
|
|
fmt = sd.Format;
|
|
dwWidth = sd.Width;
|
|
dwHeight = sd.Height;
|
|
dwDepth = 0;
|
|
}
|
|
else
|
|
{
|
|
((LPDIRECT3DCUBETEXTURE8)ptex)->GetLevelDesc(0, &sd);
|
|
fmt = sd.Format;
|
|
dwWidth = sd.Width;
|
|
dwHeight = sd.Height;
|
|
dwDepth = 0;
|
|
}
|
|
|
|
strFormat = FormatName(fmt);
|
|
|
|
// Count bytes in main surface chain
|
|
if (GetDocument()->IsVolumeMap())
|
|
{
|
|
for (iLevel = 0; iLevel < GetDocument()->NumMips(); iLevel++)
|
|
{
|
|
((LPDIRECT3DVOLUMETEXTURE8)ptex)->GetLevelDesc(iLevel, &vd);
|
|
dwBytes += vd.Size;
|
|
}
|
|
}
|
|
else if (!GetDocument()->IsCubeMap())
|
|
{
|
|
dwBytes += NumBytesInSurfaces(D3DCUBEMAP_FACE_FORCE_DWORD, ptex);
|
|
}
|
|
else
|
|
{
|
|
dwBytes += NumBytesInSurfaces(D3DCUBEMAP_FACE_POSITIVE_X, ptex);
|
|
dwBytes += NumBytesInSurfaces(D3DCUBEMAP_FACE_NEGATIVE_X, ptex);
|
|
dwBytes += NumBytesInSurfaces(D3DCUBEMAP_FACE_POSITIVE_Y, ptex);
|
|
dwBytes += NumBytesInSurfaces(D3DCUBEMAP_FACE_NEGATIVE_Y, ptex);
|
|
dwBytes += NumBytesInSurfaces(D3DCUBEMAP_FACE_POSITIVE_Z, ptex);
|
|
dwBytes += NumBytesInSurfaces(D3DCUBEMAP_FACE_NEGATIVE_Z, ptex);
|
|
}
|
|
|
|
if (dwDepth == 0)
|
|
wsprintf(sz, "%d x %d, %s, %d bytes", dwWidth, dwHeight, strFormat, dwBytes);
|
|
else
|
|
wsprintf(sz, "%d x %d x %d, %s, %d bytes", dwWidth, dwHeight, dwDepth, strFormat, dwBytes);
|
|
strInfo = sz;
|
|
}
|
|
|
|
|
|
DWORD CDxtexView::NumBytesInSurfaces(D3DCUBEMAP_FACES FaceType, LPDIRECT3DBASETEXTURE8 ptex)
|
|
{
|
|
DWORD dwBytes = 0;
|
|
LPDIRECT3DTEXTURE8 pmiptex = NULL;
|
|
LPDIRECT3DCUBETEXTURE8 pcubetex = NULL;
|
|
D3DSURFACE_DESC sd;
|
|
DWORD iLevel;
|
|
|
|
if (FaceType == D3DCUBEMAP_FACE_FORCE_DWORD)
|
|
pmiptex = (LPDIRECT3DTEXTURE8)ptex;
|
|
else
|
|
pcubetex = (LPDIRECT3DCUBETEXTURE8)ptex;
|
|
|
|
for (iLevel = 0; iLevel < GetDocument()->NumMips(); iLevel++)
|
|
{
|
|
if (pmiptex != NULL)
|
|
pmiptex->GetLevelDesc(iLevel, &sd);
|
|
else
|
|
pcubetex->GetLevelDesc(iLevel, &sd);
|
|
dwBytes += sd.Size;
|
|
}
|
|
|
|
return dwBytes;
|
|
}
|
|
|
|
|
|
HRESULT CDxtexView::UpdateDevice(VOID)
|
|
{
|
|
HRESULT hr;
|
|
LPDIRECT3D8 pd3d = PDxtexApp()->Pd3d();
|
|
LPDIRECT3DDEVICE8 pd3ddev = PDxtexApp()->Pd3ddev();
|
|
D3DDISPLAYMODE dispMode;
|
|
D3DPRESENT_PARAMETERS presentParams;
|
|
|
|
pd3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dispMode);
|
|
|
|
ReleasePpo(&m_pSwapChain);
|
|
ZeroMemory(&presentParams, sizeof(presentParams));
|
|
presentParams.Windowed = TRUE;
|
|
presentParams.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;
|
|
presentParams.BackBufferWidth = m_rcSrc.Width();
|
|
presentParams.BackBufferHeight = m_rcSrc.Height();
|
|
presentParams.BackBufferFormat = dispMode.Format;
|
|
|
|
if (FAILED(hr = pd3ddev->CreateAdditionalSwapChain(&presentParams, &m_pSwapChain)))
|
|
return hr;
|
|
|
|
COLORREF crBkgd;
|
|
crBkgd = PDxtexApp()->GetProfileInt("Settings", "Background Color", RGB(0, 255, 255));
|
|
m_dwClearColor = D3DCOLOR_RGBA(GetRValue(crBkgd), GetGValue(crBkgd), GetBValue(crBkgd), 255);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT CDxtexView::CreateVertexBuffer(VOID)
|
|
{
|
|
LPDIRECT3DDEVICE8 pd3ddev = PDxtexApp()->Pd3ddev();
|
|
|
|
// Create the the vertex buffer
|
|
if( FAILED( pd3ddev->CreateVertexBuffer( 6 * sizeof(CUSTOMVERTEX),
|
|
0 /* Usage */, D3DFVF_CUSTOMVERTEX,
|
|
D3DPOOL_DEFAULT, &m_pVB ) ) )
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT CDxtexView::RenderScene(VOID)
|
|
{
|
|
CWaitCursor waitCursor;
|
|
HRESULT hr;
|
|
LPDIRECT3DDEVICE8 pd3ddev = PDxtexApp()->Pd3ddev();
|
|
|
|
LPDIRECT3DSURFACE8 psurf;
|
|
|
|
if (m_pSwapChain == NULL)
|
|
return E_FAIL;
|
|
|
|
// Vertices for our quad
|
|
CUSTOMVERTEX vertexArray[] =
|
|
{
|
|
// x, y, z, rhw, color
|
|
{ 0.0f, 0.0f, 0.5f, 1.0f, 0xffffffff, 0.0, 0.0, },
|
|
{ (FLOAT)m_rcSrc.right, 0.0f, 0.5f, 1.0f, 0xffffffff, 1.0, 0.0, },
|
|
{ (FLOAT)m_rcSrc.right, (FLOAT)m_rcSrc.bottom, 0.5f, 1.0f, 0xffffffff, 1.0, 1.0, },
|
|
|
|
{ (FLOAT)m_rcSrc.right, (FLOAT)m_rcSrc.bottom, 0.5f, 1.0f, 0xffffffff, 1.0, 1.0, },
|
|
{ 0.0f, (FLOAT)m_rcSrc.bottom, 0.5f, 1.0f, 0xffffffff, 0.0, 1.0, },
|
|
{ 0.0f, 0.0f, 0.5f, 1.0f, 0xffffffff, 0.0, 0.0, },
|
|
};
|
|
|
|
// Copy the global vertex data into the vertex buffer
|
|
VOID* pVertices;
|
|
if( FAILED( m_pVB->Lock( 0, sizeof(vertexArray), (BYTE**)&pVertices, 0 ) ) )
|
|
return E_FAIL;
|
|
memcpy( pVertices, vertexArray, sizeof(vertexArray) );
|
|
m_pVB->Unlock();
|
|
|
|
hr = m_pSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &psurf);
|
|
|
|
hr = pd3ddev->SetRenderTarget(psurf, NULL);
|
|
|
|
ReleasePpo(&psurf);
|
|
|
|
hr = pd3ddev->Clear(0, NULL, D3DCLEAR_TARGET, m_dwClearColor, 0.0f, 0);
|
|
|
|
hr = pd3ddev->BeginScene();
|
|
|
|
// If the texture uses premultiplied alpha, the source blend should be D3DBLEND_ONE
|
|
// since RGB is already at the level we want. With nonpremultiplied alpha, the
|
|
// source blend should be D3DBLEND_SRCALPHA.
|
|
D3DSURFACE_DESC sd;
|
|
m_ptexCur->GetLevelDesc(0, &sd);
|
|
if (!m_bViewAlpha && (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4))
|
|
{
|
|
if (FAILED(hr = pd3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE)))
|
|
return hr;
|
|
}
|
|
else
|
|
{
|
|
if (FAILED(hr = pd3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA)))
|
|
return hr;
|
|
}
|
|
hr = pd3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
|
hr = pd3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
|
|
|
pd3ddev->SetTexture(0, m_ptexCur);
|
|
pd3ddev->SetStreamSource( 0, m_pVB, sizeof(CUSTOMVERTEX) );
|
|
pd3ddev->SetVertexShader( D3DFVF_CUSTOMVERTEX );
|
|
pd3ddev->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );
|
|
pd3ddev->SetTexture(0, NULL);
|
|
|
|
hr = pd3ddev->EndScene();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
void CDxtexView::OnViewOriginal()
|
|
{
|
|
if (GetDocument()->PtexOrig() == NULL)
|
|
return;
|
|
BuildViewSurface(TRUE, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
|
|
RenderScene();
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
InvalidateRect(&m_rcDest, FALSE); // force redraw of this view
|
|
}
|
|
|
|
|
|
void CDxtexView::OnViewCompressed()
|
|
{
|
|
if (GetDocument()->PtexNew() == NULL)
|
|
return;
|
|
BuildViewSurface(FALSE, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
|
|
RenderScene();
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
InvalidateRect(&m_rcDest, FALSE); // force redraw of this view
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdateViewOriginal(CCmdUI* pCmdUI)
|
|
{
|
|
if (GetDocument()->PtexOrig() == NULL)
|
|
{
|
|
pCmdUI->Enable(FALSE);
|
|
pCmdUI->SetCheck(0);
|
|
}
|
|
else
|
|
{
|
|
pCmdUI->Enable(TRUE);
|
|
pCmdUI->SetCheck(m_bViewOrig);
|
|
}
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdateViewCompressed(CCmdUI* pCmdUI)
|
|
{
|
|
if (GetDocument()->PtexNew() == NULL)
|
|
{
|
|
pCmdUI->Enable(FALSE);
|
|
pCmdUI->SetCheck(0);
|
|
}
|
|
else
|
|
{
|
|
pCmdUI->Enable(TRUE);
|
|
pCmdUI->SetCheck(!m_bViewOrig);
|
|
}
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
|
|
{
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
if (lHint == 1)
|
|
{
|
|
BuildViewSurface(m_bViewOrig, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
|
|
RenderScene();
|
|
}
|
|
else if (lHint == 2)
|
|
{
|
|
UpdateDevice();
|
|
RenderScene();
|
|
}
|
|
else if (lHint == 3)
|
|
{
|
|
RenderScene();
|
|
}
|
|
|
|
CScrollView::OnUpdate(pSender, lHint, pHint);
|
|
}
|
|
|
|
|
|
void CDxtexView::OnViewSmallerMipLevel()
|
|
{
|
|
m_lwMipCur++;
|
|
if (m_lwSliceCur > 0)
|
|
m_lwSliceCur /= 2;
|
|
BuildViewSurface(m_bViewOrig, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
|
|
UpdateDevice();
|
|
RenderScene();
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
SetScrollSizes(MM_TEXT, CSize(m_rcDest.Width(), m_rcDest.Height()));
|
|
Invalidate(); // force redraw of this view
|
|
}
|
|
|
|
|
|
void CDxtexView::OnViewLargerMipLevel()
|
|
{
|
|
m_lwMipCur--;
|
|
if (m_lwSliceCur > 0)
|
|
m_lwSliceCur *= 2;
|
|
BuildViewSurface(m_bViewOrig, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
|
|
UpdateDevice();
|
|
RenderScene();
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
SetScrollSizes(MM_TEXT, CSize(m_rcDest.Width(), m_rcDest.Height()));
|
|
Invalidate(); // force redraw of this view
|
|
}
|
|
|
|
|
|
void CDxtexView::OnViewAlphaChannel(VOID)
|
|
{
|
|
BuildViewSurface(m_bViewOrig, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, !m_bViewAlpha);
|
|
RenderScene();
|
|
Invalidate(); // force redraw of this view
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdateViewAlphaChannel(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_bViewAlpha);
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdateViewLargerMipLevel(CCmdUI* pCmdUI)
|
|
{
|
|
if (m_lwMipCur > 0)
|
|
pCmdUI->Enable(TRUE);
|
|
else
|
|
pCmdUI->Enable(FALSE);
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdateViewSmallerMipLevel(CCmdUI* pCmdUI)
|
|
{
|
|
if (m_lwMipCur < (LONG)GetDocument()->NumMips() - 1)
|
|
pCmdUI->Enable(TRUE);
|
|
else
|
|
pCmdUI->Enable(FALSE);
|
|
}
|
|
|
|
|
|
void CDxtexView::OnViewZoomIn()
|
|
{
|
|
if (m_fZoom < 8.0f)
|
|
m_fZoom *= 2.0f;
|
|
m_rcDest.right = (LONG)(m_rcSrc.right * m_fZoom);
|
|
m_rcDest.bottom = (LONG)(m_rcSrc.bottom * m_fZoom);
|
|
SetScrollSizes(MM_TEXT, CSize(m_rcDest.Width(), m_rcDest.Height()));
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
Invalidate(); // force redraw of this view
|
|
}
|
|
|
|
|
|
void CDxtexView::OnViewZoomOut()
|
|
{
|
|
if (m_fZoom > 0.125f)
|
|
m_fZoom /= 2.0f;
|
|
m_rcDest.right = (LONG)(m_rcSrc.right * m_fZoom);
|
|
m_rcDest.bottom = (LONG)(m_rcSrc.bottom * m_fZoom);
|
|
SetScrollSizes(MM_TEXT, CSize(m_rcDest.Width(), m_rcDest.Height()));
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
Invalidate(); // force redraw of this view
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdateViewZoomIn(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(m_fZoom < 8.0f);
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdateViewZoomOut(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(m_fZoom > 0.125f);
|
|
}
|
|
|
|
|
|
CString CDxtexView::GetStrTitleMods(VOID)
|
|
{
|
|
CString strTitleMods;
|
|
strTitleMods = "(";
|
|
|
|
// Append alpha, if in alpha mode
|
|
if (m_bViewAlpha)
|
|
strTitleMods += "Alpha, ";
|
|
|
|
// Show format
|
|
LPDIRECT3DBASETEXTURE8 ptex;
|
|
CString strFormat;
|
|
D3DFORMAT fmt;
|
|
|
|
if (m_bViewOrig)
|
|
ptex = GetDocument()->PtexOrig();
|
|
else
|
|
ptex = GetDocument()->PtexNew();
|
|
|
|
if (GetDocument()->IsVolumeMap())
|
|
{
|
|
D3DVOLUME_DESC vd;
|
|
((LPDIRECT3DVOLUMETEXTURE8)ptex)->GetLevelDesc(0, &vd);
|
|
fmt = vd.Format;
|
|
}
|
|
else if (!GetDocument()->IsCubeMap())
|
|
{
|
|
D3DSURFACE_DESC sd;
|
|
((LPDIRECT3DTEXTURE8)ptex)->GetLevelDesc(0, &sd);
|
|
fmt = sd.Format;
|
|
}
|
|
else
|
|
{
|
|
D3DSURFACE_DESC sd;
|
|
((LPDIRECT3DCUBETEXTURE8)ptex)->GetLevelDesc(0, &sd);
|
|
fmt = sd.Format;
|
|
}
|
|
|
|
strTitleMods += FormatName(fmt);
|
|
strTitleMods += TEXT(", ");
|
|
|
|
// Append cube map info, if a cube map
|
|
switch (m_CubeFaceCur)
|
|
{
|
|
case D3DCUBEMAP_FACE_NEGATIVE_X:
|
|
strTitleMods += "Negative X, ";
|
|
break;
|
|
case D3DCUBEMAP_FACE_POSITIVE_X:
|
|
strTitleMods += "Positive X, ";
|
|
break;
|
|
case D3DCUBEMAP_FACE_NEGATIVE_Y:
|
|
strTitleMods += "Negative Y, ";
|
|
break;
|
|
case D3DCUBEMAP_FACE_POSITIVE_Y:
|
|
strTitleMods += "Positive Y, ";
|
|
break;
|
|
case D3DCUBEMAP_FACE_NEGATIVE_Z:
|
|
strTitleMods += "Negative Z, ";
|
|
break;
|
|
case D3DCUBEMAP_FACE_POSITIVE_Z:
|
|
strTitleMods += "Positive Z, ";
|
|
break;
|
|
}
|
|
|
|
if (m_lwSliceCur >= 0)
|
|
{
|
|
CString strSlice;
|
|
strSlice.Format("Slice %d of %d, ", m_lwSliceCur + 1, GetDocument()->DwDepthAt(m_lwMipCur));
|
|
strTitleMods += strSlice;
|
|
}
|
|
|
|
// Append mip info, if multiple mip levels
|
|
DWORD dwNumMips = GetDocument()->NumMips();
|
|
if (dwNumMips > 1)
|
|
{
|
|
CString strMipInfo;
|
|
strMipInfo.Format("Mip %d of %d, ", m_lwMipCur + 1, dwNumMips);
|
|
strTitleMods += strMipInfo;
|
|
}
|
|
|
|
// Append view magnification
|
|
CString strView;
|
|
strView.Format("%d", (LONG)(100 * m_fZoom));
|
|
strTitleMods += strView + "%";
|
|
|
|
strTitleMods += ")";
|
|
return strTitleMods;
|
|
}
|
|
|
|
|
|
CString CDxtexView::FormatName(D3DFORMAT fmt)
|
|
{
|
|
CString str;
|
|
switch (fmt)
|
|
{
|
|
case D3DFMT_A8R8G8B8:
|
|
str = TEXT("A8R8G8B8");
|
|
break;
|
|
case D3DFMT_A1R5G5B5:
|
|
str = TEXT("A1R5G5B5");
|
|
break;
|
|
case D3DFMT_A4R4G4B4:
|
|
str = TEXT("A4R4G4B4");
|
|
break;
|
|
case D3DFMT_R8G8B8:
|
|
str = TEXT("R8G8B8");
|
|
break;
|
|
case D3DFMT_R5G6B5:
|
|
str = TEXT("R5G6B5");
|
|
break;
|
|
case D3DFMT_X8R8G8B8:
|
|
str = TEXT("X8R8G8B8");
|
|
break;
|
|
case D3DFMT_X1R5G5B5:
|
|
str = TEXT("X1R5G5B5");
|
|
break;
|
|
case D3DFMT_R3G3B2:
|
|
str = TEXT("R3G3B2");
|
|
break;
|
|
case D3DFMT_A8R3G3B2:
|
|
str = TEXT("A8R3G3B2");
|
|
break;
|
|
case D3DFMT_X4R4G4B4:
|
|
str = TEXT("X4R4G4B4");
|
|
break;
|
|
case D3DFMT_DXT1:
|
|
str = TEXT("DXT1");
|
|
break;
|
|
case D3DFMT_DXT2:
|
|
str = TEXT("DXT2");
|
|
break;
|
|
case D3DFMT_DXT3:
|
|
str = TEXT("DXT3");
|
|
break;
|
|
case D3DFMT_DXT4:
|
|
str = TEXT("DXT4");
|
|
break;
|
|
case D3DFMT_DXT5:
|
|
str = TEXT("DXT5");
|
|
break;
|
|
default:
|
|
str = TEXT("unknown fmt");
|
|
break;
|
|
}
|
|
return str;
|
|
}
|
|
|
|
void CDxtexView::OnViewChangeBackgroundColor()
|
|
{
|
|
CHOOSECOLOR cc;
|
|
COLORREF crArray[16];
|
|
|
|
ZeroMemory(&cc, sizeof(cc));
|
|
cc.lStructSize = sizeof(cc);
|
|
cc.hwndOwner = GetSafeHwnd();
|
|
cc.rgbResult = PDxtexApp()->GetProfileInt("Settings", "Background Color", RGB(0, 255, 255));
|
|
cc.lpCustColors = crArray;
|
|
cc.Flags = CC_RGBINIT | CC_ANYCOLOR | CC_FULLOPEN;
|
|
|
|
if (ChooseColor(&cc))
|
|
{
|
|
PDxtexApp()->WriteProfileInt("Settings", "Background Color", cc.rgbResult);
|
|
|
|
// Update all views of all documents of our one doc template
|
|
POSITION posTemp = PDxtexApp()->GetFirstDocTemplatePosition();
|
|
CDocTemplate* pDocTemplate = PDxtexApp()->GetNextDocTemplate(posTemp);
|
|
CDocument* pdoc;
|
|
POSITION pos = pDocTemplate->GetFirstDocPosition();
|
|
while (pos != NULL)
|
|
{
|
|
pdoc = pDocTemplate->GetNextDoc(pos);
|
|
pdoc->UpdateAllViews(NULL, 2);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CDxtexView::OnFileOpenSubsurface()
|
|
{
|
|
GetDocument()->OpenSubsurface(m_CubeFaceCur, m_lwMipCur, m_lwSliceCur);
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdateFileOpenSubsurface(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(TRUE);
|
|
}
|
|
|
|
|
|
void CDxtexView::OnFileOpenAlphaSubsurface()
|
|
{
|
|
GetDocument()->OpenAlphaSubsurface(m_CubeFaceCur, m_lwMipCur, m_lwSliceCur);
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdateFileOpenAlphaSubsurface(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(TRUE);
|
|
}
|
|
|
|
|
|
HRESULT CDxtexView::BuildViewSurface(BOOL bOrig, D3DCUBEMAP_FACES FaceType, LONG lwSlice, LONG lwMip, BOOL bViewAlpha)
|
|
{
|
|
HRESULT hr;
|
|
LPDIRECT3DDEVICE8 pd3ddev = PDxtexApp()->Pd3ddev();
|
|
LPDIRECT3DBASETEXTURE8 ptex;
|
|
BOOL bIsCubeMap = GetDocument()->IsCubeMap();
|
|
BOOL bIsVolumeMap = GetDocument()->IsVolumeMap();
|
|
D3DSURFACE_DESC sd;
|
|
D3DVOLUME_DESC vd;
|
|
|
|
ReleasePpo(&m_ptexCur);
|
|
|
|
if (bIsVolumeMap && lwSlice == -1)
|
|
lwSlice = 0;
|
|
|
|
if (bIsCubeMap && FaceType == D3DCUBEMAP_FACE_FORCE_DWORD)
|
|
FaceType = D3DCUBEMAP_FACE_POSITIVE_X;
|
|
|
|
m_bViewOrig = bOrig;
|
|
m_bViewAlpha = bViewAlpha;
|
|
m_lwSliceCur = lwSlice;
|
|
m_lwMipCur = lwMip;
|
|
m_CubeFaceCur = FaceType;
|
|
|
|
if (bOrig)
|
|
ptex = GetDocument()->PtexOrig();
|
|
else
|
|
ptex = GetDocument()->PtexNew();
|
|
|
|
if (bIsVolumeMap)
|
|
{
|
|
((LPDIRECT3DVOLUMETEXTURE8)ptex)->GetLevelDesc(m_lwMipCur, &vd);
|
|
sd.Width = vd.Width;
|
|
sd.Height = vd.Height;
|
|
}
|
|
else if (!bIsCubeMap)
|
|
{
|
|
((LPDIRECT3DTEXTURE8)ptex)->GetLevelDesc(m_lwMipCur, &sd);
|
|
}
|
|
else
|
|
{
|
|
((LPDIRECT3DCUBETEXTURE8)ptex)->GetLevelDesc(m_lwMipCur, &sd);
|
|
}
|
|
|
|
hr = pd3ddev->CreateTexture(sd.Width, sd.Height, 1,
|
|
0 /* Usage */, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_ptexCur);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
m_rcSrc.SetRect(0, 0, sd.Width, sd.Height);
|
|
m_rcDest.SetRect(0, 0, (INT)(sd.Width * m_fZoom), (INT)(sd.Height * m_fZoom));
|
|
|
|
LPDIRECT3DSURFACE8 psurfSrc = NULL;
|
|
LPDIRECT3DSURFACE8 psurfDest = NULL;
|
|
|
|
hr = m_ptexCur->GetSurfaceLevel(0, &psurfDest);
|
|
|
|
if (bIsVolumeMap)
|
|
{
|
|
LPDIRECT3DVOLUME8 pvolSrc;
|
|
hr = ((LPDIRECT3DVOLUMETEXTURE8)ptex)->GetVolumeLevel(m_lwMipCur, &pvolSrc);
|
|
hr = LoadSurfaceFromVolumeSlice(pvolSrc, m_lwSliceCur, psurfDest);
|
|
ReleasePpo(&pvolSrc);
|
|
}
|
|
else if (!bIsCubeMap)
|
|
{
|
|
hr = ((LPDIRECT3DTEXTURE8)ptex)->GetSurfaceLevel(m_lwMipCur, &psurfSrc);
|
|
hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL,
|
|
D3DX_FILTER_TRIANGLE, 0);
|
|
}
|
|
else
|
|
{
|
|
hr = ((LPDIRECT3DCUBETEXTURE8)ptex)->GetCubeMapSurface(FaceType, m_lwMipCur, &psurfSrc);
|
|
hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL,
|
|
D3DX_FILTER_TRIANGLE, 0);
|
|
}
|
|
|
|
|
|
if (bViewAlpha)
|
|
{
|
|
// Move alpha channels into RGB (and set alpha to 0xff)
|
|
D3DLOCKED_RECT lr;
|
|
|
|
hr = psurfDest->LockRect(&lr, NULL, 0);
|
|
|
|
DWORD xp;
|
|
DWORD yp;
|
|
DWORD* pdwRow = (DWORD*)lr.pBits;
|
|
DWORD* pdw;
|
|
DWORD dwAlpha;
|
|
LONG dataBytesPerRow = 4 * sd.Width;
|
|
|
|
for (yp = 0; yp < sd.Height; yp++)
|
|
{
|
|
pdw = pdwRow;
|
|
for (xp = 0; xp < sd.Width; xp++)
|
|
{
|
|
dwAlpha = *pdw >> 24;
|
|
*pdw = 0xff000000 | (dwAlpha << 16) | (dwAlpha << 8) | (dwAlpha);
|
|
pdw++;
|
|
}
|
|
pdwRow += lr.Pitch / 4;
|
|
}
|
|
psurfDest->UnlockRect();
|
|
}
|
|
|
|
ReleasePpo(&psurfSrc);
|
|
ReleasePpo(&psurfDest);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT CDxtexView::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;
|
|
}
|
|
|
|
|
|
void CDxtexView::OnViewNegX()
|
|
{
|
|
BuildViewSurface(m_bViewOrig, D3DCUBEMAP_FACE_NEGATIVE_X, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
RenderScene();
|
|
Invalidate(); // force redraw of this view
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdateViewNegX(CCmdUI* pCmdUI)
|
|
{
|
|
BOOL bEnable = GetDocument()->IsCubeMap();
|
|
pCmdUI->Enable(bEnable);
|
|
pCmdUI->SetCheck(m_CubeFaceCur == D3DCUBEMAP_FACE_NEGATIVE_X);
|
|
}
|
|
|
|
|
|
void CDxtexView::OnViewPosX()
|
|
{
|
|
BuildViewSurface(m_bViewOrig, D3DCUBEMAP_FACE_POSITIVE_X, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
RenderScene();
|
|
Invalidate(); // force redraw of this view
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdateViewPosX(CCmdUI* pCmdUI)
|
|
{
|
|
BOOL bEnable = GetDocument()->IsCubeMap();
|
|
pCmdUI->Enable(bEnable);
|
|
pCmdUI->SetCheck(m_CubeFaceCur == D3DCUBEMAP_FACE_POSITIVE_X);
|
|
}
|
|
|
|
|
|
void CDxtexView::OnViewNegY()
|
|
{
|
|
BuildViewSurface(m_bViewOrig, D3DCUBEMAP_FACE_NEGATIVE_Y, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
RenderScene();
|
|
Invalidate(); // force redraw of this view
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdateViewNegY(CCmdUI* pCmdUI)
|
|
{
|
|
BOOL bEnable = GetDocument()->IsCubeMap();
|
|
pCmdUI->Enable(bEnable);
|
|
pCmdUI->SetCheck(m_CubeFaceCur == D3DCUBEMAP_FACE_NEGATIVE_Y);
|
|
}
|
|
|
|
|
|
void CDxtexView::OnViewPosY()
|
|
{
|
|
BuildViewSurface(m_bViewOrig, D3DCUBEMAP_FACE_POSITIVE_Y, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
RenderScene();
|
|
Invalidate(); // force redraw of this view
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdateViewPosY(CCmdUI* pCmdUI)
|
|
{
|
|
BOOL bEnable = GetDocument()->IsCubeMap();
|
|
pCmdUI->Enable(bEnable);
|
|
pCmdUI->SetCheck(m_CubeFaceCur == D3DCUBEMAP_FACE_POSITIVE_Y);
|
|
}
|
|
|
|
|
|
void CDxtexView::OnViewNegZ()
|
|
{
|
|
BuildViewSurface(m_bViewOrig, D3DCUBEMAP_FACE_NEGATIVE_Z, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
RenderScene();
|
|
Invalidate(); // force redraw of this view
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdateViewNegZ(CCmdUI* pCmdUI)
|
|
{
|
|
BOOL bEnable = GetDocument()->IsCubeMap();
|
|
pCmdUI->Enable(bEnable);
|
|
pCmdUI->SetCheck(m_CubeFaceCur == D3DCUBEMAP_FACE_NEGATIVE_Z);
|
|
}
|
|
|
|
|
|
void CDxtexView::OnViewPosZ()
|
|
{
|
|
BuildViewSurface(m_bViewOrig, D3DCUBEMAP_FACE_POSITIVE_Z, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
RenderScene();
|
|
Invalidate(); // force redraw of this view
|
|
}
|
|
|
|
|
|
void CDxtexView::OnUpdateViewPosZ(CCmdUI* pCmdUI)
|
|
{
|
|
BOOL bEnable = GetDocument()->IsCubeMap();
|
|
pCmdUI->Enable(bEnable);
|
|
pCmdUI->SetCheck(m_CubeFaceCur == D3DCUBEMAP_FACE_POSITIVE_Z);
|
|
}
|
|
|
|
void CDxtexView::OnFileOpenFace()
|
|
{
|
|
GetDocument()->OpenCubeFace(m_CubeFaceCur);
|
|
}
|
|
|
|
void CDxtexView::OnUpdateFileOpenFace(CCmdUI* pCmdUI)
|
|
{
|
|
BOOL bEnable = (m_CubeFaceCur != D3DCUBEMAP_FACE_FORCE_DWORD);
|
|
pCmdUI->Enable(bEnable);
|
|
}
|
|
|
|
void CDxtexView::OnFileOpenAlphaFace()
|
|
{
|
|
GetDocument()->OpenAlphaCubeFace(m_CubeFaceCur);
|
|
}
|
|
|
|
void CDxtexView::OnUpdateFileOpenAlphaFace(CCmdUI* pCmdUI)
|
|
{
|
|
BOOL bEnable = (m_CubeFaceCur != D3DCUBEMAP_FACE_FORCE_DWORD);
|
|
pCmdUI->Enable(bEnable);
|
|
}
|
|
|
|
void CDxtexView::OnViewHigherVolumeSlice()
|
|
{
|
|
m_lwSliceCur++;
|
|
BuildViewSurface(m_bViewOrig, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
|
|
UpdateDevice();
|
|
RenderScene();
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
Invalidate(); // force redraw of this view
|
|
}
|
|
|
|
void CDxtexView::OnUpdateViewHigherVolumeSlice(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(GetDocument()->IsVolumeMap() && m_lwSliceCur < (LONG)GetDocument()->DwDepthAt(m_lwMipCur) - 1);
|
|
}
|
|
|
|
void CDxtexView::OnViewLowerVolumeSlice()
|
|
{
|
|
m_lwSliceCur--;
|
|
BuildViewSurface(m_bViewOrig, m_CubeFaceCur, m_lwSliceCur, m_lwMipCur, m_bViewAlpha);
|
|
UpdateDevice();
|
|
RenderScene();
|
|
m_bTitleModsChanged = TRUE; // force title bar update
|
|
Invalidate(); // force redraw of this view
|
|
}
|
|
|
|
void CDxtexView::OnUpdateViewLowerVolumeSlice(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(GetDocument()->IsVolumeMap() && m_lwSliceCur > 0);
|
|
}
|
|
|