1 // dxtexView.cpp : implementation of the CDxtexView class
12 static char THIS_FILE
[] = __FILE__
;
15 // Our custom vertex type
21 FLOAT tu
, tv
; // The texture coordinates
24 #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1)
27 IMPLEMENT_DYNCREATE(CDxtexView
, CScrollView
)
29 BEGIN_MESSAGE_MAP(CDxtexView
, CScrollView
)
30 //{{AFX_MSG_MAP(CDxtexView)
32 ON_COMMAND(ID_FILE_OPENSUBSURFACE
, OnFileOpenSubsurface
)
33 ON_COMMAND(ID_FILE_OPENALPHASUBSURFACE
, OnFileOpenAlphaSubsurface
)
34 ON_COMMAND(ID_FILE_OPENFACE
, OnFileOpenFace
)
35 ON_COMMAND(ID_FILE_OPENALPHAFACE
, OnFileOpenAlphaFace
)
36 ON_COMMAND(ID_VIEW_ORIGINAL
, OnViewOriginal
)
37 ON_COMMAND(ID_VIEW_COMPRESSED
, OnViewCompressed
)
38 ON_COMMAND(ID_VIEW_SMALLERMIPLEVEL
, OnViewSmallerMipLevel
)
39 ON_COMMAND(ID_VIEW_LARGERMIPLEVEL
, OnViewLargerMipLevel
)
40 ON_COMMAND(ID_VIEW_ALPHACHANNEL
, OnViewAlphaChannel
)
41 ON_COMMAND(ID_VIEW_RGBONLY
, OnViewRgbOnly
)
42 ON_COMMAND(ID_VIEW_ZOOMIN
, OnViewZoomIn
)
43 ON_COMMAND(ID_VIEW_ZOOMOUT
, OnViewZoomOut
)
44 ON_COMMAND(ID_VIEW_CHANGEBACKGROUNDCOLOR
, OnViewChangeBackgroundColor
)
45 ON_COMMAND(ID_VIEW_NEGX
, OnViewNegX
)
46 ON_COMMAND(ID_VIEW_POSX
, OnViewPosX
)
47 ON_COMMAND(ID_VIEW_NEGY
, OnViewNegY
)
48 ON_COMMAND(ID_VIEW_POSY
, OnViewPosY
)
49 ON_COMMAND(ID_VIEW_NEGZ
, OnViewNegZ
)
50 ON_COMMAND(ID_VIEW_POSZ
, OnViewPosZ
)
51 ON_COMMAND(ID_VIEW_HIGHERVOLUMESLICE
, OnViewHigherVolumeSlice
)
52 ON_COMMAND(ID_VIEW_LOWERVOLUMESLICE
, OnViewLowerVolumeSlice
)
53 ON_UPDATE_COMMAND_UI(ID_FILE_OPENSUBSURFACE
, OnUpdateFileOpenSubsurface
)
54 ON_UPDATE_COMMAND_UI(ID_FILE_OPENALPHASUBSURFACE
, OnUpdateFileOpenAlphaSubsurface
)
55 ON_UPDATE_COMMAND_UI(ID_FILE_OPENFACE
, OnUpdateFileOpenFace
)
56 ON_UPDATE_COMMAND_UI(ID_FILE_OPENALPHAFACE
, OnUpdateFileOpenAlphaFace
)
57 ON_UPDATE_COMMAND_UI(ID_VIEW_ORIGINAL
, OnUpdateViewOriginal
)
58 ON_UPDATE_COMMAND_UI(ID_VIEW_COMPRESSED
, OnUpdateViewCompressed
)
59 ON_UPDATE_COMMAND_UI(ID_VIEW_ALPHACHANNEL
, OnUpdateViewAlphaChannel
)
60 ON_UPDATE_COMMAND_UI(ID_VIEW_RGBONLY
, OnUpdateViewRgbOnly
)
61 ON_UPDATE_COMMAND_UI(ID_VIEW_LARGERMIPLEVEL
, OnUpdateViewLargerMipLevel
)
62 ON_UPDATE_COMMAND_UI(ID_VIEW_SMALLERMIPLEVEL
, OnUpdateViewSmallerMipLevel
)
63 ON_UPDATE_COMMAND_UI(ID_VIEW_ZOOMIN
, OnUpdateViewZoomIn
)
64 ON_UPDATE_COMMAND_UI(ID_VIEW_ZOOMOUT
, OnUpdateViewZoomOut
)
65 ON_UPDATE_COMMAND_UI(ID_VIEW_NEGX
, OnUpdateViewNegX
)
66 ON_UPDATE_COMMAND_UI(ID_VIEW_POSX
, OnUpdateViewPosX
)
67 ON_UPDATE_COMMAND_UI(ID_VIEW_NEGY
, OnUpdateViewNegY
)
68 ON_UPDATE_COMMAND_UI(ID_VIEW_POSY
, OnUpdateViewPosY
)
69 ON_UPDATE_COMMAND_UI(ID_VIEW_NEGZ
, OnUpdateViewNegZ
)
70 ON_UPDATE_COMMAND_UI(ID_VIEW_POSZ
, OnUpdateViewPosZ
)
71 ON_UPDATE_COMMAND_UI(ID_VIEW_HIGHERVOLUMESLICE
, OnUpdateViewHigherVolumeSlice
)
72 ON_UPDATE_COMMAND_UI(ID_VIEW_LOWERVOLUMESLICE
, OnUpdateViewLowerVolumeSlice
)
76 static UINT
GetSurfaceSize(D3DSURFACE_DESC
* pDesc
)
78 switch( pDesc
->Format
)
80 case D3DFMT_A16B16G16R16
:
81 return pDesc
->Width
* pDesc
->Height
* 8;
85 case D3DFMT_A2R10G10B10
:
86 return pDesc
->Width
* pDesc
->Height
* 4;
89 return pDesc
->Width
* pDesc
->Height
* 3;
96 return pDesc
->Width
* pDesc
->Height
* 2;
99 return pDesc
->Width
* pDesc
->Height
* 1;
102 return pDesc
->Width
* pDesc
->Height
/ 2;
108 return pDesc
->Width
* pDesc
->Height
* 1;
115 static UINT
GetVolumeSize(D3DVOLUME_DESC
* pDesc
)
117 switch( pDesc
->Format
)
119 case D3DFMT_A16B16G16R16
:
120 return pDesc
->Width
* pDesc
->Height
* pDesc
->Depth
* 8;
122 case D3DFMT_A8R8G8B8
:
123 case D3DFMT_X8R8G8B8
:
124 case D3DFMT_A2R10G10B10
:
125 return pDesc
->Width
* pDesc
->Height
* pDesc
->Depth
* 4;
128 return pDesc
->Width
* pDesc
->Height
* pDesc
->Depth
* 3;
130 case D3DFMT_A1R5G5B5
:
131 case D3DFMT_X1R5G5B5
:
132 case D3DFMT_A4R4G4B4
:
133 case D3DFMT_X4R4G4B4
:
135 return pDesc
->Width
* pDesc
->Height
* pDesc
->Depth
* 2;
138 return pDesc
->Width
* pDesc
->Height
* pDesc
->Depth
* 1;
141 return pDesc
->Width
* pDesc
->Height
* pDesc
->Depth
/ 2;
147 return pDesc
->Width
* pDesc
->Height
* pDesc
->Depth
* 1;
155 CDxtexView::CDxtexView()
161 m_CubeFaceCur
= D3DCUBEMAP_FACE_FORCE_DWORD
;
166 m_bViewAlpha
= FALSE
;
170 CDxtexView::~CDxtexView()
173 ReleasePpo(&m_ptexCur
);
174 ReleasePpo(&m_pSwapChain
);
178 // Note: repaints don't require re-rendering, just recopy from back buffer to view's DC
179 void CDxtexView::OnDraw(CDC
* pDC
)
181 CDxtexDoc
* pDoc
= GetDocument();
191 rcDest
.OffsetRect(pDC
->GetViewportOrg());
193 // REVIEW: only update dirty region?
194 if (m_pSwapChain
!= NULL
)
196 if( PDxtexApp()->HandlePossibleLostDevice() )
198 hr
= m_pSwapChain
->Present(&rcSrc
, &rcDest
, GetSafeHwnd(), NULL
, 0);
199 if( hr
== D3DERR_DEVICELOST
)
201 PDxtexApp()->DeviceIsLost();
210 void CDxtexView::AssertValid() const
212 CScrollView::AssertValid();
216 void CDxtexView::Dump(CDumpContext
& dc
) const
218 CScrollView::Dump(dc
);
222 CDxtexDoc
* CDxtexView::GetDocument() // non-debug version is inline
224 ASSERT(m_pDocument
->IsKindOf(RUNTIME_CLASS(CDxtexDoc
)));
225 return (CDxtexDoc
*)m_pDocument
;
230 void CDxtexView::OnLButtonUp(UINT nFlags
, CPoint point
)
232 // Button click means toggle compressed / uncompressed view
238 CScrollView::OnLButtonUp(nFlags
, point
);
242 void CDxtexView::OnInitialUpdate()
245 SetClassLongPtr(GetSafeHwnd(), GCLP_HBRBACKGROUND
, (LONG_PTR
)CreateSolidBrush(RGB(100, 100, 120)));
247 SetClassLong(GetSafeHwnd(), GCL_HBRBACKGROUND
, (LONG
)CreateSolidBrush(RGB(100, 100, 120)));
250 if (GetDocument()->IsCubeMap())
251 m_CubeFaceCur
= D3DCUBEMAP_FACE_POSITIVE_X
;
253 m_CubeFaceCur
= D3DCUBEMAP_FACE_FORCE_DWORD
;
254 if (GetDocument()->IsVolumeMap())
256 BuildViewSurface(m_bViewOrig
, m_CubeFaceCur
, m_lwSliceCur
, m_lwMipCur
, m_bViewAlpha
);
258 CreateVertexBuffer();
261 SetScrollSizes(MM_TEXT
, CSize(m_rcDest
.Width(), m_rcDest
.Height()));
264 CScrollView::OnInitialUpdate();
266 m_bTitleModsChanged
= TRUE
; // force title bar update
270 VOID
CDxtexView::GetImageInfo(CString
& strInfo
)
272 LPDIRECT3DBASETEXTURE9 ptex
;
285 ptex
= GetDocument()->PtexOrig();
287 ptex
= GetDocument()->PtexNew();
289 if (GetDocument()->IsVolumeMap())
291 ((LPDIRECT3DVOLUMETEXTURE9
)ptex
)->GetLevelDesc(0, &vd
);
294 dwHeight
= vd
.Height
;
297 else if (!GetDocument()->IsCubeMap())
299 ((LPDIRECT3DTEXTURE9
)ptex
)->GetLevelDesc(0, &sd
);
302 dwHeight
= sd
.Height
;
307 ((LPDIRECT3DCUBETEXTURE9
)ptex
)->GetLevelDesc(0, &sd
);
310 dwHeight
= sd
.Height
;
314 strFormat
= FormatName(fmt
);
316 // Count bytes in main surface chain
317 if (GetDocument()->IsVolumeMap())
319 for (iLevel
= 0; iLevel
< GetDocument()->NumMips(); iLevel
++)
321 ((LPDIRECT3DVOLUMETEXTURE9
)ptex
)->GetLevelDesc(iLevel
, &vd
);
322 dwBytes
+= GetVolumeSize(&vd
);
325 else if (!GetDocument()->IsCubeMap())
327 dwBytes
+= NumBytesInSurfaces(D3DCUBEMAP_FACE_FORCE_DWORD
, ptex
);
331 dwBytes
+= NumBytesInSurfaces(D3DCUBEMAP_FACE_POSITIVE_X
, ptex
);
332 dwBytes
+= NumBytesInSurfaces(D3DCUBEMAP_FACE_NEGATIVE_X
, ptex
);
333 dwBytes
+= NumBytesInSurfaces(D3DCUBEMAP_FACE_POSITIVE_Y
, ptex
);
334 dwBytes
+= NumBytesInSurfaces(D3DCUBEMAP_FACE_NEGATIVE_Y
, ptex
);
335 dwBytes
+= NumBytesInSurfaces(D3DCUBEMAP_FACE_POSITIVE_Z
, ptex
);
336 dwBytes
+= NumBytesInSurfaces(D3DCUBEMAP_FACE_NEGATIVE_Z
, ptex
);
340 wsprintf(sz
, "%d x %d, %s, %d bytes", dwWidth
, dwHeight
, (LPCTSTR
)strFormat
, dwBytes
);
342 wsprintf(sz
, "%d x %d x %d, %s, %d bytes", dwWidth
, dwHeight
, dwDepth
, (LPCTSTR
)strFormat
, dwBytes
);
347 DWORD
CDxtexView::NumBytesInSurfaces(D3DCUBEMAP_FACES FaceType
, LPDIRECT3DBASETEXTURE9 ptex
)
350 LPDIRECT3DTEXTURE9 pmiptex
= NULL
;
351 LPDIRECT3DCUBETEXTURE9 pcubetex
= NULL
;
355 if (FaceType
== D3DCUBEMAP_FACE_FORCE_DWORD
)
356 pmiptex
= (LPDIRECT3DTEXTURE9
)ptex
;
358 pcubetex
= (LPDIRECT3DCUBETEXTURE9
)ptex
;
360 for (iLevel
= 0; iLevel
< GetDocument()->NumMips(); iLevel
++)
363 pmiptex
->GetLevelDesc(iLevel
, &sd
);
365 pcubetex
->GetLevelDesc(iLevel
, &sd
);
366 dwBytes
+= GetSurfaceSize(&sd
);
373 HRESULT
CDxtexView::UpdateDevice(VOID
)
376 LPDIRECT3D9 pd3d
= PDxtexApp()->Pd3d();
377 LPDIRECT3DDEVICE9 pd3ddev
= PDxtexApp()->Pd3ddev();
378 D3DDISPLAYMODE dispMode
;
379 D3DPRESENT_PARAMETERS presentParams
;
381 pd3d
->GetAdapterDisplayMode(D3DADAPTER_DEFAULT
, &dispMode
);
383 ReleasePpo(&m_pSwapChain
);
384 ZeroMemory(&presentParams
, sizeof(presentParams
));
385 presentParams
.Windowed
= TRUE
;
386 presentParams
.SwapEffect
= D3DSWAPEFFECT_COPY
;
387 presentParams
.BackBufferWidth
= m_rcSrc
.Width();
388 presentParams
.BackBufferHeight
= m_rcSrc
.Height();
389 presentParams
.BackBufferFormat
= dispMode
.Format
;
391 if (FAILED(hr
= pd3ddev
->CreateAdditionalSwapChain(&presentParams
, &m_pSwapChain
)))
395 crBkgd
= PDxtexApp()->GetProfileInt("Settings", "Background Color", RGB(0, 255, 255));
396 m_dwClearColor
= D3DCOLOR_RGBA(GetRValue(crBkgd
), GetGValue(crBkgd
), GetBValue(crBkgd
), 255);
401 HRESULT
CDxtexView::InvalidateDeviceObjects(VOID
)
403 ReleasePpo( &m_pSwapChain
);
407 HRESULT
CDxtexView::RestoreDeviceObjects(VOID
)
415 HRESULT
CDxtexView::CreateVertexBuffer(VOID
)
417 LPDIRECT3DDEVICE9 pd3ddev
= PDxtexApp()->Pd3ddev();
419 // Create the the vertex buffer
420 if( FAILED( pd3ddev
->CreateVertexBuffer( 6 * sizeof(CUSTOMVERTEX
),
421 0 /* Usage */, D3DFVF_CUSTOMVERTEX
,
422 D3DPOOL_MANAGED
, &m_pVB
, NULL
) ) )
431 HRESULT
CDxtexView::RenderScene(VOID
)
433 CWaitCursor waitCursor
;
435 LPDIRECT3DDEVICE9 pd3ddev
= PDxtexApp()->Pd3ddev();
437 LPDIRECT3DSURFACE9 psurf
;
439 if (m_pSwapChain
== NULL
)
442 // Vertices for our quad
443 CUSTOMVERTEX vertexArray
[] =
445 // x, y, z, rhw, color
446 { 0.0f
, 0.0f
, 0.5f
, 1.0f
, 0xffffffff, 0.0, 0.0, },
447 { (FLOAT
)m_rcSrc
.right
, 0.0f
, 0.5f
, 1.0f
, 0xffffffff, 1.0, 0.0, },
448 { (FLOAT
)m_rcSrc
.right
, (FLOAT
)m_rcSrc
.bottom
, 0.5f
, 1.0f
, 0xffffffff, 1.0, 1.0, },
450 { (FLOAT
)m_rcSrc
.right
, (FLOAT
)m_rcSrc
.bottom
, 0.5f
, 1.0f
, 0xffffffff, 1.0, 1.0, },
451 { 0.0f
, (FLOAT
)m_rcSrc
.bottom
, 0.5f
, 1.0f
, 0xffffffff, 0.0, 1.0, },
452 { 0.0f
, 0.0f
, 0.5f
, 1.0f
, 0xffffffff, 0.0, 0.0, },
455 // Copy the global vertex data into the vertex buffer
457 if( FAILED( m_pVB
->Lock( 0, sizeof(vertexArray
), (void**)&pVertices
, 0 ) ) )
459 memcpy( pVertices
, vertexArray
, sizeof(vertexArray
) );
462 hr
= m_pSwapChain
->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO
, &psurf
);
464 hr
= pd3ddev
->SetRenderTarget(0, psurf
);
468 hr
= pd3ddev
->Clear(0, NULL
, D3DCLEAR_TARGET
, m_dwClearColor
, 0.0f
, 0);
470 hr
= pd3ddev
->BeginScene();
472 // If the texture uses premultiplied alpha, the source blend should be D3DBLEND_ONE
473 // since RGB is already at the level we want. With nonpremultiplied alpha, the
474 // source blend should be D3DBLEND_SRCALPHA.
476 m_ptexCur
->GetLevelDesc(0, &sd
);
477 if (!m_bViewAlpha
&& (sd
.Format
== D3DFMT_DXT2
|| sd
.Format
== D3DFMT_DXT4
))
479 if (FAILED(hr
= pd3ddev
->SetRenderState(D3DRS_SRCBLEND
, D3DBLEND_ONE
)))
484 if (FAILED(hr
= pd3ddev
->SetRenderState(D3DRS_SRCBLEND
, D3DBLEND_SRCALPHA
)))
487 hr
= pd3ddev
->SetRenderState(D3DRS_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
488 hr
= pd3ddev
->SetRenderState(D3DRS_ALPHABLENDENABLE
, m_bRgbOnly
? FALSE
: TRUE
);
490 pd3ddev
->SetTexture(0, m_ptexCur
);
491 pd3ddev
->SetStreamSource( 0, m_pVB
, 0, sizeof(CUSTOMVERTEX
) );
492 pd3ddev
->SetFVF( D3DFVF_CUSTOMVERTEX
);
493 pd3ddev
->DrawPrimitive( D3DPT_TRIANGLELIST
, 0, 2 );
494 pd3ddev
->SetTexture(0, NULL
);
496 hr
= pd3ddev
->EndScene();
502 void CDxtexView::OnViewOriginal()
504 if (GetDocument()->PtexOrig() == NULL
)
506 BuildViewSurface(TRUE
, m_CubeFaceCur
, m_lwSliceCur
, m_lwMipCur
, m_bViewAlpha
);
508 m_bTitleModsChanged
= TRUE
; // force title bar update
509 InvalidateRect(&m_rcDest
, FALSE
); // force redraw of this view
513 void CDxtexView::OnViewCompressed()
515 if (GetDocument()->PtexNew() == NULL
)
517 BuildViewSurface(FALSE
, m_CubeFaceCur
, m_lwSliceCur
, m_lwMipCur
, m_bViewAlpha
);
519 m_bTitleModsChanged
= TRUE
; // force title bar update
520 InvalidateRect(&m_rcDest
, FALSE
); // force redraw of this view
524 void CDxtexView::OnUpdateViewOriginal(CCmdUI
* pCmdUI
)
526 if (GetDocument()->PtexOrig() == NULL
)
528 pCmdUI
->Enable(FALSE
);
533 pCmdUI
->Enable(TRUE
);
534 pCmdUI
->SetCheck(m_bViewOrig
);
539 void CDxtexView::OnUpdateViewCompressed(CCmdUI
* pCmdUI
)
541 if (GetDocument()->PtexNew() == NULL
)
543 pCmdUI
->Enable(FALSE
);
548 pCmdUI
->Enable(TRUE
);
549 pCmdUI
->SetCheck(!m_bViewOrig
);
554 void CDxtexView::OnUpdate(CView
* pSender
, LPARAM lHint
, CObject
* pHint
)
556 m_bTitleModsChanged
= TRUE
; // force title bar update
559 BuildViewSurface(m_bViewOrig
, m_CubeFaceCur
, m_lwSliceCur
, m_lwMipCur
, m_bViewAlpha
);
573 BuildViewSurface(m_bViewOrig
, m_CubeFaceCur
, m_lwSliceCur
, m_lwMipCur
, m_bViewAlpha
);
576 SetScrollSizes(MM_TEXT
, CSize(m_rcDest
.Width(), m_rcDest
.Height()));
580 CScrollView::OnUpdate(pSender
, lHint
, pHint
);
584 void CDxtexView::OnViewSmallerMipLevel()
587 if (m_lwSliceCur
> 0)
589 BuildViewSurface(m_bViewOrig
, m_CubeFaceCur
, m_lwSliceCur
, m_lwMipCur
, m_bViewAlpha
);
592 m_bTitleModsChanged
= TRUE
; // force title bar update
593 SetScrollSizes(MM_TEXT
, CSize(m_rcDest
.Width(), m_rcDest
.Height()));
594 Invalidate(); // force redraw of this view
598 void CDxtexView::OnViewLargerMipLevel()
601 if (m_lwSliceCur
> 0)
603 BuildViewSurface(m_bViewOrig
, m_CubeFaceCur
, m_lwSliceCur
, m_lwMipCur
, m_bViewAlpha
);
606 m_bTitleModsChanged
= TRUE
; // force title bar update
607 SetScrollSizes(MM_TEXT
, CSize(m_rcDest
.Width(), m_rcDest
.Height()));
608 Invalidate(); // force redraw of this view
612 void CDxtexView::OnViewAlphaChannel(VOID
)
615 BuildViewSurface(m_bViewOrig
, m_CubeFaceCur
, m_lwSliceCur
, m_lwMipCur
, !m_bViewAlpha
);
617 Invalidate(); // force redraw of this view
618 m_bTitleModsChanged
= TRUE
; // force title bar update
622 void CDxtexView::OnUpdateViewAlphaChannel(CCmdUI
* pCmdUI
)
624 pCmdUI
->SetCheck(m_bViewAlpha
);
627 void CDxtexView::OnViewRgbOnly(VOID
)
629 m_bRgbOnly
= !m_bRgbOnly
;
630 BuildViewSurface(m_bViewOrig
, m_CubeFaceCur
, m_lwSliceCur
, m_lwMipCur
, false);
632 Invalidate(); // force redraw of this view
633 m_bTitleModsChanged
= TRUE
; // force title bar update
637 void CDxtexView::OnUpdateViewRgbOnly(CCmdUI
* pCmdUI
)
639 pCmdUI
->Enable(TRUE
);
640 pCmdUI
->SetCheck(m_bRgbOnly
);
644 void CDxtexView::OnUpdateViewLargerMipLevel(CCmdUI
* pCmdUI
)
647 pCmdUI
->Enable(TRUE
);
649 pCmdUI
->Enable(FALSE
);
653 void CDxtexView::OnUpdateViewSmallerMipLevel(CCmdUI
* pCmdUI
)
655 if (m_lwMipCur
< (LONG
)GetDocument()->NumMips() - 1)
656 pCmdUI
->Enable(TRUE
);
658 pCmdUI
->Enable(FALSE
);
662 void CDxtexView::OnViewZoomIn()
666 m_rcDest
.right
= (LONG
)(m_rcSrc
.right
* m_fZoom
);
667 m_rcDest
.bottom
= (LONG
)(m_rcSrc
.bottom
* m_fZoom
);
668 SetScrollSizes(MM_TEXT
, CSize(m_rcDest
.Width(), m_rcDest
.Height()));
669 m_bTitleModsChanged
= TRUE
; // force title bar update
670 Invalidate(); // force redraw of this view
674 void CDxtexView::OnViewZoomOut()
676 if (m_fZoom
> 0.125f
)
678 m_rcDest
.right
= (LONG
)(m_rcSrc
.right
* m_fZoom
);
679 m_rcDest
.bottom
= (LONG
)(m_rcSrc
.bottom
* m_fZoom
);
680 SetScrollSizes(MM_TEXT
, CSize(m_rcDest
.Width(), m_rcDest
.Height()));
681 m_bTitleModsChanged
= TRUE
; // force title bar update
682 Invalidate(); // force redraw of this view
686 void CDxtexView::OnUpdateViewZoomIn(CCmdUI
* pCmdUI
)
688 pCmdUI
->Enable(m_fZoom
< 8.0f
);
692 void CDxtexView::OnUpdateViewZoomOut(CCmdUI
* pCmdUI
)
694 pCmdUI
->Enable(m_fZoom
> 0.125f
);
698 CString
CDxtexView::GetStrTitleMods(VOID
)
700 CString strTitleMods
;
703 // Append alpha, if in alpha mode
705 strTitleMods
+= "Alpha, ";
708 LPDIRECT3DBASETEXTURE9 ptex
;
713 ptex
= GetDocument()->PtexOrig();
715 ptex
= GetDocument()->PtexNew();
717 if (GetDocument()->IsVolumeMap())
720 ((LPDIRECT3DVOLUMETEXTURE9
)ptex
)->GetLevelDesc(0, &vd
);
723 else if (!GetDocument()->IsCubeMap())
726 ((LPDIRECT3DTEXTURE9
)ptex
)->GetLevelDesc(0, &sd
);
732 ((LPDIRECT3DCUBETEXTURE9
)ptex
)->GetLevelDesc(0, &sd
);
736 strTitleMods
+= FormatName(fmt
);
737 strTitleMods
+= TEXT(", ");
739 // Append cube map info, if a cube map
740 switch (m_CubeFaceCur
)
742 case D3DCUBEMAP_FACE_NEGATIVE_X
:
743 strTitleMods
+= "Negative X, ";
745 case D3DCUBEMAP_FACE_POSITIVE_X
:
746 strTitleMods
+= "Positive X, ";
748 case D3DCUBEMAP_FACE_NEGATIVE_Y
:
749 strTitleMods
+= "Negative Y, ";
751 case D3DCUBEMAP_FACE_POSITIVE_Y
:
752 strTitleMods
+= "Positive Y, ";
754 case D3DCUBEMAP_FACE_NEGATIVE_Z
:
755 strTitleMods
+= "Negative Z, ";
757 case D3DCUBEMAP_FACE_POSITIVE_Z
:
758 strTitleMods
+= "Positive Z, ";
762 if (m_lwSliceCur
>= 0)
765 strSlice
.Format("Slice %d of %d, ", m_lwSliceCur
+ 1, GetDocument()->DwDepthAt(m_lwMipCur
));
766 strTitleMods
+= strSlice
;
769 // Append mip info, if multiple mip levels
770 DWORD dwNumMips
= GetDocument()->NumMips();
774 strMipInfo
.Format("Mip %d of %d, ", m_lwMipCur
+ 1, dwNumMips
);
775 strTitleMods
+= strMipInfo
;
778 // Append view magnification
780 strView
.Format("%d", (LONG
)(100 * m_fZoom
));
781 strTitleMods
+= strView
+ "%";
788 CString
CDxtexView::FormatName(D3DFORMAT fmt
)
793 case D3DFMT_A8R8G8B8
:
794 str
= TEXT("A8R8G8B8");
796 case D3DFMT_A1R5G5B5
:
797 str
= TEXT("A1R5G5B5");
799 case D3DFMT_A4R4G4B4
:
800 str
= TEXT("A4R4G4B4");
803 str
= TEXT("R8G8B8");
806 str
= TEXT("R5G6B5");
808 case D3DFMT_X8R8G8B8
:
809 str
= TEXT("X8R8G8B8");
811 case D3DFMT_X1R5G5B5
:
812 str
= TEXT("X1R5G5B5");
815 str
= TEXT("R3G3B2");
817 case D3DFMT_A8R3G3B2
:
818 str
= TEXT("A8R3G3B2");
820 case D3DFMT_X4R4G4B4
:
821 str
= TEXT("X4R4G4B4");
838 case D3DFMT_A2R10G10B10
:
839 str
= TEXT("A2R10G10B10");
841 case D3DFMT_A16B16G16R16
:
842 str
= TEXT("A16B16G16R16");
845 str
= TEXT("unknown fmt");
851 void CDxtexView::OnViewChangeBackgroundColor()
854 COLORREF crArray
[16];
856 ZeroMemory(&cc
, sizeof(cc
));
857 cc
.lStructSize
= sizeof(cc
);
858 cc
.hwndOwner
= GetSafeHwnd();
859 cc
.rgbResult
= PDxtexApp()->GetProfileInt("Settings", "Background Color", RGB(0, 255, 255));
860 cc
.lpCustColors
= crArray
;
861 cc
.Flags
= CC_RGBINIT
| CC_ANYCOLOR
| CC_FULLOPEN
;
863 if (ChooseColor(&cc
))
865 PDxtexApp()->WriteProfileInt("Settings", "Background Color", cc
.rgbResult
);
867 // Update all views of all documents of our one doc template
868 POSITION posTemp
= PDxtexApp()->GetFirstDocTemplatePosition();
869 CDocTemplate
* pDocTemplate
= PDxtexApp()->GetNextDocTemplate(posTemp
);
871 POSITION pos
= pDocTemplate
->GetFirstDocPosition();
874 pdoc
= pDocTemplate
->GetNextDoc(pos
);
875 pdoc
->UpdateAllViews(NULL
, 2);
881 void CDxtexView::OnFileOpenSubsurface()
883 GetDocument()->OpenSubsurface(m_CubeFaceCur
, m_lwMipCur
, m_lwSliceCur
);
887 void CDxtexView::OnUpdateFileOpenSubsurface(CCmdUI
* pCmdUI
)
889 pCmdUI
->Enable(TRUE
);
893 void CDxtexView::OnFileOpenAlphaSubsurface()
895 GetDocument()->OpenAlphaSubsurface(m_CubeFaceCur
, m_lwMipCur
, m_lwSliceCur
);
899 void CDxtexView::OnUpdateFileOpenAlphaSubsurface(CCmdUI
* pCmdUI
)
901 pCmdUI
->Enable(TRUE
);
905 HRESULT
CDxtexView::BuildViewSurface(BOOL bOrig
, D3DCUBEMAP_FACES FaceType
, LONG lwSlice
, LONG lwMip
, BOOL bViewAlpha
)
908 LPDIRECT3DDEVICE9 pd3ddev
= PDxtexApp()->Pd3ddev();
909 LPDIRECT3DBASETEXTURE9 ptex
;
910 BOOL bIsCubeMap
= GetDocument()->IsCubeMap();
911 BOOL bIsVolumeMap
= GetDocument()->IsVolumeMap();
915 ReleasePpo(&m_ptexCur
);
917 if (bIsVolumeMap
&& lwSlice
== -1)
920 if (bIsCubeMap
&& FaceType
== D3DCUBEMAP_FACE_FORCE_DWORD
)
921 FaceType
= D3DCUBEMAP_FACE_POSITIVE_X
;
924 m_bViewAlpha
= bViewAlpha
;
925 m_lwSliceCur
= lwSlice
;
927 m_CubeFaceCur
= FaceType
;
930 ptex
= GetDocument()->PtexOrig();
932 ptex
= GetDocument()->PtexNew();
936 ((LPDIRECT3DVOLUMETEXTURE9
)ptex
)->GetLevelDesc(m_lwMipCur
, &vd
);
938 sd
.Height
= vd
.Height
;
940 else if (!bIsCubeMap
)
942 ((LPDIRECT3DTEXTURE9
)ptex
)->GetLevelDesc(m_lwMipCur
, &sd
);
946 ((LPDIRECT3DCUBETEXTURE9
)ptex
)->GetLevelDesc(m_lwMipCur
, &sd
);
949 hr
= pd3ddev
->CreateTexture(sd
.Width
, sd
.Height
, 1,
950 0 /* Usage */, D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, &m_ptexCur
, NULL
);
954 m_rcSrc
.SetRect(0, 0, sd
.Width
, sd
.Height
);
955 m_rcDest
.SetRect(0, 0, (INT
)(sd
.Width
* m_fZoom
), (INT
)(sd
.Height
* m_fZoom
));
957 LPDIRECT3DSURFACE9 psurfSrc
= NULL
;
958 LPDIRECT3DSURFACE9 psurfDest
= NULL
;
960 hr
= m_ptexCur
->GetSurfaceLevel(0, &psurfDest
);
964 LPDIRECT3DVOLUME9 pvolSrc
;
965 hr
= ((LPDIRECT3DVOLUMETEXTURE9
)ptex
)->GetVolumeLevel(m_lwMipCur
, &pvolSrc
);
966 hr
= LoadSurfaceFromVolumeSlice(pvolSrc
, m_lwSliceCur
, psurfDest
);
967 ReleasePpo(&pvolSrc
);
969 else if (!bIsCubeMap
)
971 hr
= ((LPDIRECT3DTEXTURE9
)ptex
)->GetSurfaceLevel(m_lwMipCur
, &psurfSrc
);
972 hr
= D3DXLoadSurfaceFromSurface(psurfDest
, NULL
, NULL
, psurfSrc
, NULL
, NULL
,
973 D3DX_FILTER_TRIANGLE
, 0);
977 hr
= ((LPDIRECT3DCUBETEXTURE9
)ptex
)->GetCubeMapSurface(FaceType
, m_lwMipCur
, &psurfSrc
);
978 hr
= D3DXLoadSurfaceFromSurface(psurfDest
, NULL
, NULL
, psurfSrc
, NULL
, NULL
,
979 D3DX_FILTER_TRIANGLE
, 0);
985 // Move alpha channels into RGB (and set alpha to 0xff)
988 hr
= psurfDest
->LockRect(&lr
, NULL
, 0);
992 DWORD
* pdwRow
= (DWORD
*)lr
.pBits
;
995 LONG dataBytesPerRow
= 4 * sd
.Width
;
997 for (yp
= 0; yp
< sd
.Height
; yp
++)
1000 for (xp
= 0; xp
< sd
.Width
; xp
++)
1002 dwAlpha
= *pdw
>> 24;
1003 *pdw
= 0xff000000 | (dwAlpha
<< 16) | (dwAlpha
<< 8) | (dwAlpha
);
1006 pdwRow
+= lr
.Pitch
/ 4;
1008 psurfDest
->UnlockRect();
1011 ReleasePpo(&psurfSrc
);
1012 ReleasePpo(&psurfDest
);
1018 HRESULT
CDxtexView::LoadSurfaceFromVolumeSlice(LPDIRECT3DVOLUME9 pVolume
, UINT iSlice
, LPDIRECT3DSURFACE9 psurf
)
1026 pVolume
->GetDesc(&vd
);
1029 box
.Right
= vd
.Width
;
1031 box
.Bottom
= vd
.Height
;
1033 box
.Back
= iSlice
+ 1;
1036 rc
.right
= vd
.Width
;
1038 rc
.bottom
= vd
.Height
;
1040 hr
= pVolume
->LockBox(&lb
, &box
, 0);
1044 hr
= D3DXLoadSurfaceFromMemory(psurf
, NULL
, NULL
, lb
.pBits
, vd
.Format
, lb
.RowPitch
,
1045 NULL
, &rc
, D3DX_FILTER_TRIANGLE
, 0);
1047 pVolume
->UnlockBox();
1053 void CDxtexView::OnViewNegX()
1055 BuildViewSurface(m_bViewOrig
, D3DCUBEMAP_FACE_NEGATIVE_X
, m_lwSliceCur
, m_lwMipCur
, m_bViewAlpha
);
1056 m_bTitleModsChanged
= TRUE
; // force title bar update
1058 Invalidate(); // force redraw of this view
1062 void CDxtexView::OnUpdateViewNegX(CCmdUI
* pCmdUI
)
1064 BOOL bEnable
= GetDocument()->IsCubeMap();
1065 pCmdUI
->Enable(bEnable
);
1066 pCmdUI
->SetCheck(m_CubeFaceCur
== D3DCUBEMAP_FACE_NEGATIVE_X
);
1070 void CDxtexView::OnViewPosX()
1072 BuildViewSurface(m_bViewOrig
, D3DCUBEMAP_FACE_POSITIVE_X
, m_lwSliceCur
, m_lwMipCur
, m_bViewAlpha
);
1073 m_bTitleModsChanged
= TRUE
; // force title bar update
1075 Invalidate(); // force redraw of this view
1079 void CDxtexView::OnUpdateViewPosX(CCmdUI
* pCmdUI
)
1081 BOOL bEnable
= GetDocument()->IsCubeMap();
1082 pCmdUI
->Enable(bEnable
);
1083 pCmdUI
->SetCheck(m_CubeFaceCur
== D3DCUBEMAP_FACE_POSITIVE_X
);
1087 void CDxtexView::OnViewNegY()
1089 BuildViewSurface(m_bViewOrig
, D3DCUBEMAP_FACE_NEGATIVE_Y
, m_lwSliceCur
, m_lwMipCur
, m_bViewAlpha
);
1090 m_bTitleModsChanged
= TRUE
; // force title bar update
1092 Invalidate(); // force redraw of this view
1096 void CDxtexView::OnUpdateViewNegY(CCmdUI
* pCmdUI
)
1098 BOOL bEnable
= GetDocument()->IsCubeMap();
1099 pCmdUI
->Enable(bEnable
);
1100 pCmdUI
->SetCheck(m_CubeFaceCur
== D3DCUBEMAP_FACE_NEGATIVE_Y
);
1104 void CDxtexView::OnViewPosY()
1106 BuildViewSurface(m_bViewOrig
, D3DCUBEMAP_FACE_POSITIVE_Y
, m_lwSliceCur
, m_lwMipCur
, m_bViewAlpha
);
1107 m_bTitleModsChanged
= TRUE
; // force title bar update
1109 Invalidate(); // force redraw of this view
1113 void CDxtexView::OnUpdateViewPosY(CCmdUI
* pCmdUI
)
1115 BOOL bEnable
= GetDocument()->IsCubeMap();
1116 pCmdUI
->Enable(bEnable
);
1117 pCmdUI
->SetCheck(m_CubeFaceCur
== D3DCUBEMAP_FACE_POSITIVE_Y
);
1121 void CDxtexView::OnViewNegZ()
1123 BuildViewSurface(m_bViewOrig
, D3DCUBEMAP_FACE_NEGATIVE_Z
, m_lwSliceCur
, m_lwMipCur
, m_bViewAlpha
);
1124 m_bTitleModsChanged
= TRUE
; // force title bar update
1126 Invalidate(); // force redraw of this view
1130 void CDxtexView::OnUpdateViewNegZ(CCmdUI
* pCmdUI
)
1132 BOOL bEnable
= GetDocument()->IsCubeMap();
1133 pCmdUI
->Enable(bEnable
);
1134 pCmdUI
->SetCheck(m_CubeFaceCur
== D3DCUBEMAP_FACE_NEGATIVE_Z
);
1138 void CDxtexView::OnViewPosZ()
1140 BuildViewSurface(m_bViewOrig
, D3DCUBEMAP_FACE_POSITIVE_Z
, m_lwSliceCur
, m_lwMipCur
, m_bViewAlpha
);
1141 m_bTitleModsChanged
= TRUE
; // force title bar update
1143 Invalidate(); // force redraw of this view
1147 void CDxtexView::OnUpdateViewPosZ(CCmdUI
* pCmdUI
)
1149 BOOL bEnable
= GetDocument()->IsCubeMap();
1150 pCmdUI
->Enable(bEnable
);
1151 pCmdUI
->SetCheck(m_CubeFaceCur
== D3DCUBEMAP_FACE_POSITIVE_Z
);
1154 void CDxtexView::OnFileOpenFace()
1156 GetDocument()->OpenCubeFace(m_CubeFaceCur
);
1159 void CDxtexView::OnUpdateFileOpenFace(CCmdUI
* pCmdUI
)
1161 BOOL bEnable
= (m_CubeFaceCur
!= D3DCUBEMAP_FACE_FORCE_DWORD
);
1162 pCmdUI
->Enable(bEnable
);
1165 void CDxtexView::OnFileOpenAlphaFace()
1167 GetDocument()->OpenAlphaCubeFace(m_CubeFaceCur
);
1170 void CDxtexView::OnUpdateFileOpenAlphaFace(CCmdUI
* pCmdUI
)
1172 BOOL bEnable
= (m_CubeFaceCur
!= D3DCUBEMAP_FACE_FORCE_DWORD
);
1173 pCmdUI
->Enable(bEnable
);
1176 void CDxtexView::OnViewHigherVolumeSlice()
1179 BuildViewSurface(m_bViewOrig
, m_CubeFaceCur
, m_lwSliceCur
, m_lwMipCur
, m_bViewAlpha
);
1182 m_bTitleModsChanged
= TRUE
; // force title bar update
1183 Invalidate(); // force redraw of this view
1186 void CDxtexView::OnUpdateViewHigherVolumeSlice(CCmdUI
* pCmdUI
)
1188 pCmdUI
->Enable(GetDocument()->IsVolumeMap() && m_lwSliceCur
< (LONG
)GetDocument()->DwDepthAt(m_lwMipCur
) - 1);
1191 void CDxtexView::OnViewLowerVolumeSlice()
1194 BuildViewSurface(m_bViewOrig
, m_CubeFaceCur
, m_lwSliceCur
, m_lwMipCur
, m_bViewAlpha
);
1197 m_bTitleModsChanged
= TRUE
; // force title bar update
1198 Invalidate(); // force redraw of this view
1201 void CDxtexView::OnUpdateViewLowerVolumeSlice(CCmdUI
* pCmdUI
)
1203 pCmdUI
->Enable(GetDocument()->IsVolumeMap() && m_lwSliceCur
> 0);