1 // dxtexDoc.cpp : implementation of the CDxtexDoc class
13 static char THIS_FILE
[] = __FILE__
;
16 // Helper function that tells whether the given D3DFMT has a working alpha channel
17 BOOL
FormatContainsAlpha( D3DFORMAT fmt
)
28 case D3DFMT_A2R10G10B10
:
29 case D3DFMT_A16B16G16R16
:
36 /////////////////////////////////////////////////////////////////////////////
39 IMPLEMENT_DYNCREATE(CDxtexDoc
, CDocument
)
41 BEGIN_MESSAGE_MAP(CDxtexDoc
, CDocument
)
42 //{{AFX_MSG_MAP(CDxtexDoc)
43 ON_COMMAND(ID_FILE_OPENALPHA
, OnFileOpenAlpha
)
44 ON_COMMAND(ID_FORMAT_GENERATEMIPMAPS
, OnGenerateMipMaps
)
45 ON_COMMAND(ID_FORMAT_CHANGECUBEMAPFACES
, OnFormatChangeCubeMapFaces
)
46 ON_UPDATE_COMMAND_UI(ID_FILE_OPENALPHA
, OnUpdateFileOpenAlpha
)
47 ON_UPDATE_COMMAND_UI(ID_FORMAT_GENERATEMIPMAPS
, OnUpdateFormatGenerateMipmaps
)
48 ON_UPDATE_COMMAND_UI(ID_FORMAT_CHANGECUBEMAPFACES
, OnUpdateFormatChangeCubeMapFaces
)
49 ON_COMMAND(ID_FORMAT_MAKEINTOVOLUMEMAP
, OnFormatMakeIntoVolumeMap
)
50 ON_UPDATE_COMMAND_UI(ID_FORMAT_MAKEINTOVOLUMEMAP
, OnUpdateFormatMakeIntoVolumeMap
)
51 ON_COMMAND(ID_FORMAT_CHANGESURFACEFMT
, OnFormatChangeSurfaceFmt
)
52 ON_COMMAND(ID_FORMAT_RESIZE
, OnFormatResize
)
53 ON_UPDATE_COMMAND_UI(ID_FORMAT_RESIZE
, OnUpdateFormatResize
)
54 ON_COMMAND(ID_FORMAT_GENERATESPECULARLOOKUP
, OnFormatGeneratespecularlookup
)
55 ON_UPDATE_COMMAND_UI(ID_FORMAT_GENERATESPECULARLOOKUP
, OnUpdateFormatGeneratespecularlookup
)
59 /////////////////////////////////////////////////////////////////////////////
60 // CDxtexDoc diagnostics
63 void CDxtexDoc::AssertValid() const
65 CDocument::AssertValid();
68 void CDxtexDoc::Dump(CDumpContext
& dc
) const
74 /////////////////////////////////////////////////////////////////////////////
75 // CDxtexDoc construction/destruction
77 CDxtexDoc::CDxtexDoc()
86 m_bTitleModsChanged
= FALSE
;
90 CDxtexDoc::~CDxtexDoc()
92 ReleasePpo(&m_ptexOrig
);
93 ReleasePpo(&m_ptexNew
);
97 BOOL
CDxtexDoc::OnNewDocument()
100 LPDIRECT3DDEVICE9 pd3ddev
= PDxtexApp()->Pd3ddev();
102 if (!CDocument::OnNewDocument())
107 if (IDCANCEL
== dlg
.DoModal())
110 m_dwWidth
= dlg
.m_dwWidth
;
111 m_dwHeight
= dlg
.m_dwHeight
;
112 m_numMips
= dlg
.m_numMips
;
114 if (dlg
.m_iTexType
== 0)
116 LPDIRECT3DTEXTURE9 pmiptex
;
117 hr
= pd3ddev
->CreateTexture(m_dwWidth
, m_dwHeight
, m_numMips
,
118 0, dlg
.m_fmt
, D3DPOOL_MANAGED
, &pmiptex
, NULL
);
121 AfxMessageBox(ID_ERROR_CANTCREATETEXTURE
);
124 m_ptexOrig
= pmiptex
;
127 else if (dlg
.m_iTexType
== 1)
130 LPDIRECT3DCUBETEXTURE9 pcubetex
;
131 m_dwCubeMapFlags
= DDS_CUBEMAP_ALLFACES
;
132 hr
= pd3ddev
->CreateCubeTexture(m_dwWidth
, m_numMips
,
133 0, dlg
.m_fmt
, D3DPOOL_MANAGED
, &pcubetex
, NULL
);
136 AfxMessageBox(ID_ERROR_CANTCREATETEXTURE
);
139 m_ptexOrig
= pcubetex
;
143 LPDIRECT3DVOLUMETEXTURE9 pvoltex
;
144 m_dwDepth
= dlg
.m_dwDepth
;
145 hr
= pd3ddev
->CreateVolumeTexture(m_dwWidth
, m_dwHeight
, m_dwDepth
, m_numMips
,
146 0, dlg
.m_fmt
, D3DPOOL_SYSTEMMEM
, &pvoltex
, NULL
);
149 AfxMessageBox(ID_ERROR_CANTCREATETEXTURE
);
152 m_ptexOrig
= pvoltex
;
159 BOOL
CDxtexDoc::OnOpenDocument(LPCTSTR lpszPathName
)
161 LPDIRECT3DDEVICE9 pd3ddev
= PDxtexApp()->Pd3ddev();
162 D3DXIMAGE_INFO imageinfo
;
163 D3DXIMAGE_INFO imageinfo2
;
165 if( FAILED( D3DXGetImageInfoFromFile( lpszPathName
, &imageinfo
) ) )
167 AfxMessageBox(ID_ERROR_COULDNTLOADFILE
);
171 switch( imageinfo
.ResourceType
)
173 case D3DRTYPE_TEXTURE
:
174 if( FAILED( D3DXCreateTextureFromFileEx( pd3ddev
, lpszPathName
,
175 imageinfo
.Width
, imageinfo
.Height
, imageinfo
.MipLevels
, 0,
176 imageinfo
.Format
, D3DPOOL_MANAGED
, D3DX_FILTER_NONE
, D3DX_FILTER_NONE
, 0,
177 &imageinfo2
, NULL
, (LPDIRECT3DTEXTURE9
*)&m_ptexOrig
) ) )
179 AfxMessageBox(ID_ERROR_COULDNTLOADFILE
);
182 m_dwWidth
= imageinfo2
.Width
;
183 m_dwHeight
= imageinfo2
.Height
;
185 m_numMips
= imageinfo2
.MipLevels
;
187 if( imageinfo
.ImageFileFormat
== D3DXIFF_BMP
)
189 // Look for "foo_a.bmp" for alpha channel
190 CString strPath
= lpszPathName
;
191 int i
= strPath
.ReverseFind('.');
193 strPath
= strPath
.Left(i
) + "_a.bmp";
195 if (CFile::GetStatus(strPath
, status
))
197 // Make sure there's an alpha channel to load alpha image into
198 if (FAILED(EnsureAlpha(&m_ptexOrig
)))
201 LPDIRECT3DSURFACE9 psurf
;
203 hr
= ((LPDIRECT3DTEXTURE9
)m_ptexOrig
)->GetSurfaceLevel(0, &psurf
);
207 hr
= LoadAlphaIntoSurface(strPath
, psurf
);
216 case D3DRTYPE_VOLUMETEXTURE
:
217 if( FAILED( D3DXCreateVolumeTextureFromFileEx( pd3ddev
, lpszPathName
,
218 imageinfo
.Width
, imageinfo
.Height
, imageinfo
.Depth
, imageinfo
.MipLevels
,
219 0, imageinfo
.Format
, D3DPOOL_MANAGED
, D3DX_FILTER_NONE
, D3DX_FILTER_NONE
,
220 0, &imageinfo2
, NULL
, (LPDIRECT3DVOLUMETEXTURE9
*)&m_ptexOrig
) ) )
222 AfxMessageBox(ID_ERROR_COULDNTLOADFILE
);
225 m_dwWidth
= imageinfo2
.Width
;
226 m_dwHeight
= imageinfo2
.Height
;
227 m_dwDepth
= imageinfo2
.Depth
;
228 m_numMips
= imageinfo2
.MipLevels
;
231 case D3DRTYPE_CUBETEXTURE
:
232 if( FAILED( D3DXCreateCubeTextureFromFileEx( pd3ddev
, lpszPathName
,
233 imageinfo
.Width
, imageinfo
.MipLevels
, 0, imageinfo
.Format
,
234 D3DPOOL_MANAGED
, D3DX_FILTER_NONE
, D3DX_FILTER_NONE
,
235 0, &imageinfo2
, NULL
, (LPDIRECT3DCUBETEXTURE9
*)&m_ptexOrig
) ) )
237 AfxMessageBox(ID_ERROR_COULDNTLOADFILE
);
240 m_dwWidth
= imageinfo2
.Width
;
241 m_dwHeight
= imageinfo2
.Height
;
243 m_numMips
= imageinfo2
.MipLevels
;
244 m_dwCubeMapFlags
= DDS_CUBEMAP_ALLFACES
;
248 AfxMessageBox(ID_ERROR_COULDNTLOADFILE
);
256 BOOL
CDxtexDoc::OnSaveDocument(LPCTSTR lpszPathName
)
258 LPDIRECT3DBASETEXTURE9 ptex
;
259 ptex
= (m_ptexNew
== NULL
? m_ptexOrig
: m_ptexNew
);
261 if( FAILED( D3DXSaveTextureToFile( lpszPathName
, D3DXIFF_DDS
, ptex
, NULL
) ) )
263 AfxMessageBox(ID_ERROR_COULDNTSAVEFILE
);
267 SetModifiedFlag(FALSE
);
275 D3DFORMAT
CDxtexDoc::GetFormat(LPDIRECT3DBASETEXTURE9 ptex
)
277 LPDIRECT3DTEXTURE9 pmiptex
= NULL
;
278 LPDIRECT3DCUBETEXTURE9 pcubetex
= NULL
;
279 LPDIRECT3DVOLUMETEXTURE9 pvoltex
= NULL
;
283 pvoltex
= (LPDIRECT3DVOLUMETEXTURE9
)ptex
;
284 else if (IsCubeMap())
285 pcubetex
= (LPDIRECT3DCUBETEXTURE9
)ptex
;
287 pmiptex
= (LPDIRECT3DTEXTURE9
)ptex
;
292 pvoltex
->GetLevelDesc(0, &vd
);
295 else if (pcubetex
!= NULL
)
298 pcubetex
->GetLevelDesc(0, &sd
);
304 pmiptex
->GetLevelDesc(0, &sd
);
312 // If *pptex's current format has less than 4 bits of alpha, change
313 // it to a similar format that has at least 4 bits of alpha.
314 HRESULT
CDxtexDoc::EnsureAlpha(LPDIRECT3DBASETEXTURE9
* pptex
)
317 D3DFORMAT fmtCur
= GetFormat(*pptex
);
318 D3DFORMAT fmtNew
= D3DFMT_UNKNOWN
;
319 LPDIRECT3DBASETEXTURE9 ptex
= NULL
;
324 fmtNew
= D3DFMT_A8R8G8B8
;
330 if( fmtNew
!= D3DFMT_UNKNOWN
)
332 if (FAILED(hr
= ChangeFormat(m_ptexOrig
, fmtNew
, &ptex
)))
334 ReleasePpo(&m_ptexOrig
);
344 /////////////////////////////////////////////////////////////////////////////
345 // CDxtexDoc commands
347 HRESULT
CDxtexDoc::LoadAlphaBmp(CString
& strPath
)
350 LPDIRECT3DTEXTURE9 pmiptex
;
351 LPDIRECT3DSURFACE9 psurf
;
356 pmiptex
= (LPDIRECT3DTEXTURE9
)m_ptexOrig
;
357 hr
= pmiptex
->GetSurfaceLevel(0, &psurf
);
361 hr
= LoadAlphaIntoSurface(strPath
, psurf
);
366 UpdateAllViews(NULL
, 1); // tell CView to pick up new surface pointers
373 HRESULT
CDxtexDoc::ChangeFormat(LPDIRECT3DBASETEXTURE9 ptexCur
, D3DFORMAT fmtTo
,
374 LPDIRECT3DBASETEXTURE9
* pptexNew
)
377 LPDIRECT3DDEVICE9 pd3ddev
= PDxtexApp()->Pd3ddev();
378 LPDIRECT3DTEXTURE9 pmiptex
;
379 LPDIRECT3DCUBETEXTURE9 pcubetex
;
380 LPDIRECT3DVOLUMETEXTURE9 pvoltex
;
382 LPDIRECT3DTEXTURE9 pmiptexNew
;
383 LPDIRECT3DCUBETEXTURE9 pcubetexNew
;
384 LPDIRECT3DVOLUMETEXTURE9 pvoltexNew
;
388 pvoltex
= (LPDIRECT3DVOLUMETEXTURE9
)ptexCur
;
390 pvoltex
->GetLevelDesc(0, &vd
);
393 else if (IsCubeMap())
395 pcubetex
= (LPDIRECT3DCUBETEXTURE9
)ptexCur
;
397 pcubetex
->GetLevelDesc(0, &sd
);
402 pmiptex
= (LPDIRECT3DTEXTURE9
)ptexCur
;
404 pmiptex
->GetLevelDesc(0, &sd
);
408 if (fmtFrom
== D3DFMT_DXT2
|| fmtFrom
== D3DFMT_DXT4
)
410 if (fmtTo
== D3DFMT_DXT1
)
412 AfxMessageBox(ID_ERROR_PREMULTTODXT1
);
414 else if (fmtTo
!= D3DFMT_DXT2
&& fmtTo
!= D3DFMT_DXT4
)
416 AfxMessageBox(ID_ERROR_PREMULTALPHA
);
423 hr
= pd3ddev
->CreateVolumeTexture(m_dwWidth
, m_dwHeight
, m_dwDepth
, m_numMips
,
424 0, fmtTo
, D3DPOOL_SYSTEMMEM
, &pvoltexNew
, NULL
);
427 *pptexNew
= pvoltexNew
;
428 if (FAILED(BltAllLevels(D3DCUBEMAP_FACE_FORCE_DWORD
, ptexCur
, *pptexNew
)))
431 else if (IsCubeMap())
433 hr
= pd3ddev
->CreateCubeTexture(m_dwWidth
, m_numMips
,
434 0, fmtTo
, D3DPOOL_MANAGED
, &pcubetexNew
, NULL
);
437 *pptexNew
= pcubetexNew
;
438 if (FAILED(hr
= BltAllLevels(D3DCUBEMAP_FACE_NEGATIVE_X
, ptexCur
, *pptexNew
)))
440 if (FAILED(hr
= BltAllLevels(D3DCUBEMAP_FACE_POSITIVE_X
, ptexCur
, *pptexNew
)))
442 if (FAILED(hr
= BltAllLevels(D3DCUBEMAP_FACE_NEGATIVE_Y
, ptexCur
, *pptexNew
)))
444 if (FAILED(hr
= BltAllLevels(D3DCUBEMAP_FACE_POSITIVE_Y
, ptexCur
, *pptexNew
)))
446 if (FAILED(hr
= BltAllLevels(D3DCUBEMAP_FACE_NEGATIVE_Z
, ptexCur
, *pptexNew
)))
448 if (FAILED(hr
= BltAllLevels(D3DCUBEMAP_FACE_POSITIVE_Z
, ptexCur
, *pptexNew
)))
453 if ((fmtTo
== D3DFMT_DXT1
|| fmtTo
== D3DFMT_DXT2
||
454 fmtTo
== D3DFMT_DXT3
|| fmtTo
== D3DFMT_DXT4
||
455 fmtTo
== D3DFMT_DXT5
) && (m_dwWidth
% 4 != 0 || m_dwHeight
% 4 != 0))
457 AfxMessageBox(ID_ERROR_NEEDMULTOF4
);
461 hr
= pd3ddev
->CreateTexture(m_dwWidth
, m_dwHeight
, m_numMips
,
462 0, fmtTo
, D3DPOOL_MANAGED
, &pmiptexNew
, NULL
);
465 *pptexNew
= pmiptexNew
;
466 if (FAILED(BltAllLevels(D3DCUBEMAP_FACE_FORCE_DWORD
, ptexCur
, *pptexNew
)))
475 HRESULT
CDxtexDoc::Compress(D3DFORMAT fmtTo
, BOOL bSwitchView
)
478 LPDIRECT3DBASETEXTURE9 ptexNew
= NULL
;
480 if (FAILED(hr
= ChangeFormat(m_ptexOrig
, fmtTo
, &ptexNew
)))
483 ReleasePpo(&m_ptexNew
);
487 m_bTitleModsChanged
= TRUE
; // force title bar update
490 if( AfxGetMainWnd() != NULL
)
491 AfxGetMainWnd()->PostMessage(WM_COMMAND
, ID_VIEW_COMPRESSED
, 0);
500 void CDxtexDoc::OnGenerateMipMaps()
508 void CDxtexDoc::GenerateMipMaps()
514 LPDIRECT3DTEXTURE9 pddsNew
= NULL
;
517 LPDIRECT3DDEVICE9 pd3ddev
= PDxtexApp()->Pd3ddev();
518 LPDIRECT3DTEXTURE9 pmiptex
= NULL
;
519 LPDIRECT3DCUBETEXTURE9 pcubetex
= NULL
;
520 LPDIRECT3DVOLUMETEXTURE9 pvoltex
= NULL
;
521 LPDIRECT3DTEXTURE9 pmiptexNew
= NULL
;
522 LPDIRECT3DCUBETEXTURE9 pcubetexNew
= NULL
;
523 LPDIRECT3DVOLUMETEXTURE9 pvoltexNew
= NULL
;
524 LPDIRECT3DSURFACE9 psurfSrc
;
525 LPDIRECT3DSURFACE9 psurfDest
;
526 LPDIRECT3DVOLUME9 pvolSrc
;
527 LPDIRECT3DVOLUME9 pvolDest
;
530 pvoltex
= (LPDIRECT3DVOLUMETEXTURE9
)m_ptexOrig
;
531 else if (IsCubeMap())
532 pcubetex
= (LPDIRECT3DCUBETEXTURE9
)m_ptexOrig
;
534 pmiptex
= (LPDIRECT3DTEXTURE9
)m_ptexOrig
;
539 pvoltex
->GetLevelDesc(0, &vd
);
542 else if (pcubetex
!= NULL
)
545 pcubetex
->GetLevelDesc(0, &sd
);
551 pmiptex
->GetLevelDesc(0, &sd
);
556 lwTempH
= m_dwHeight
;
562 lwTempW
= lwTempW
/ 2;
567 lwTempH
= lwTempH
/ 2;
569 m_numMips
= lwPowsW
> lwPowsH
? lwPowsW
: lwPowsH
;
571 // Create destination mipmap surface - same format as source
574 if (FAILED(hr
= pd3ddev
->CreateVolumeTexture(m_dwWidth
, m_dwHeight
, m_dwDepth
,
575 m_numMips
, 0, fmt
, D3DPOOL_SYSTEMMEM
, &pvoltexNew
, NULL
)))
579 hr
= pvoltex
->GetVolumeLevel(0, &pvolSrc
);
580 hr
= pvoltexNew
->GetVolumeLevel(0, &pvolDest
);
581 hr
= D3DXLoadVolumeFromVolume(pvolDest
, NULL
, NULL
, pvolSrc
, NULL
, NULL
,
582 D3DX_FILTER_TRIANGLE
, 0);
583 ReleasePpo(&pvolSrc
);
584 ReleasePpo(&pvolDest
);
585 hr
= D3DXFilterVolumeTexture(pvoltexNew
, NULL
, 0, D3DX_FILTER_TRIANGLE
);
587 else if (pmiptex
!= NULL
)
589 if (FAILED(hr
= pd3ddev
->CreateTexture(m_dwWidth
, m_dwHeight
, m_numMips
,
590 0, fmt
, D3DPOOL_MANAGED
, &pmiptexNew
, NULL
)))
594 hr
= pmiptex
->GetSurfaceLevel(0, &psurfSrc
);
595 hr
= pmiptexNew
->GetSurfaceLevel(0, &psurfDest
);
596 hr
= D3DXLoadSurfaceFromSurface(psurfDest
, NULL
, NULL
, psurfSrc
, NULL
, NULL
,
597 D3DX_FILTER_TRIANGLE
, 0);
598 ReleasePpo(&psurfSrc
);
599 ReleasePpo(&psurfDest
);
600 hr
= D3DXFilterTexture(pmiptexNew
, NULL
, 0, D3DX_FILTER_TRIANGLE
);
604 if (FAILED(hr
= pd3ddev
->CreateCubeTexture(m_dwWidth
, m_numMips
,
605 0, fmt
, D3DPOOL_MANAGED
, &pcubetexNew
, NULL
)))
609 hr
= pcubetex
->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_X
, 0, &psurfSrc
);
610 hr
= pcubetexNew
->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_X
, 0, &psurfDest
);
611 hr
= D3DXLoadSurfaceFromSurface(psurfDest
, NULL
, NULL
, psurfSrc
, NULL
, NULL
,
612 D3DX_FILTER_TRIANGLE
, 0);
613 ReleasePpo(&psurfSrc
);
614 ReleasePpo(&psurfDest
);
615 hr
= pcubetex
->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_X
, 0, &psurfSrc
);
616 hr
= pcubetexNew
->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_X
, 0, &psurfDest
);
617 hr
= D3DXLoadSurfaceFromSurface(psurfDest
, NULL
, NULL
, psurfSrc
, NULL
, NULL
,
618 D3DX_FILTER_TRIANGLE
, 0);
619 ReleasePpo(&psurfSrc
);
620 ReleasePpo(&psurfDest
);
621 hr
= pcubetex
->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y
, 0, &psurfSrc
);
622 hr
= pcubetexNew
->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y
, 0, &psurfDest
);
623 hr
= D3DXLoadSurfaceFromSurface(psurfDest
, NULL
, NULL
, psurfSrc
, NULL
, NULL
,
624 D3DX_FILTER_TRIANGLE
, 0);
625 ReleasePpo(&psurfSrc
);
626 ReleasePpo(&psurfDest
);
627 hr
= pcubetex
->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Y
, 0, &psurfSrc
);
628 hr
= pcubetexNew
->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Y
, 0, &psurfDest
);
629 hr
= D3DXLoadSurfaceFromSurface(psurfDest
, NULL
, NULL
, psurfSrc
, NULL
, NULL
,
630 D3DX_FILTER_TRIANGLE
, 0);
631 ReleasePpo(&psurfSrc
);
632 ReleasePpo(&psurfDest
);
633 hr
= pcubetex
->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Z
, 0, &psurfSrc
);
634 hr
= pcubetexNew
->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Z
, 0, &psurfDest
);
635 hr
= D3DXLoadSurfaceFromSurface(psurfDest
, NULL
, NULL
, psurfSrc
, NULL
, NULL
,
636 D3DX_FILTER_TRIANGLE
, 0);
637 ReleasePpo(&psurfSrc
);
638 ReleasePpo(&psurfDest
);
639 hr
= pcubetex
->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Z
, 0, &psurfSrc
);
640 hr
= pcubetexNew
->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Z
, 0, &psurfDest
);
641 hr
= D3DXLoadSurfaceFromSurface(psurfDest
, NULL
, NULL
, psurfSrc
, NULL
, NULL
,
642 D3DX_FILTER_TRIANGLE
, 0);
643 ReleasePpo(&psurfSrc
);
644 ReleasePpo(&psurfDest
);
645 hr
= D3DXFilterCubeTexture(pcubetexNew
, NULL
, 0, D3DX_FILTER_TRIANGLE
);
648 ReleasePpo(&m_ptexOrig
);
649 if (pvoltexNew
!= NULL
)
650 m_ptexOrig
= pvoltexNew
;
651 else if (pcubetexNew
!= NULL
)
652 m_ptexOrig
= pcubetexNew
;
654 m_ptexOrig
= pmiptexNew
;
656 if (m_ptexNew
!= NULL
)
658 // Rather than filtering down the (probably-compressed) m_ptexNew
659 // top level, compress each mip level from the (probably-uncompressed)
660 // m_ptexOrig levels.
661 if (pvoltexNew
!= NULL
)
664 ((LPDIRECT3DVOLUMETEXTURE9
)m_ptexNew
)->GetLevelDesc(0, &vd
);
667 else if (pcubetexNew
!= NULL
)
670 ((LPDIRECT3DTEXTURE9
)m_ptexNew
)->GetLevelDesc(0, &sd
);
676 ((LPDIRECT3DCUBETEXTURE9
)m_ptexNew
)->GetLevelDesc(0, &sd
);
679 Compress(fmt
, FALSE
);
682 m_bTitleModsChanged
= TRUE
; // Generate title bar update
683 UpdateAllViews(NULL
, 1); // tell CView to pick up new surface pointers
688 ReleasePpo(&pddsNew
);
692 void CDxtexDoc::SetPathName(LPCTSTR lpszPathName
, BOOL bAddToMRU
)
694 CDocument::SetPathName(lpszPathName
, bAddToMRU
);
696 TCHAR
* pszLeaf
= strrchr(lpszPathName
, '\\');
700 TCHAR
* pszExtension
= strrchr(lpszPathName
, '.');
701 if( pszExtension
&& lstrcmpi(pszExtension
, ".dds") != 0)
703 lstrcpy(pszExtension
, "");
704 SetModifiedFlag(TRUE
);
706 m_strPathName
.Empty();
711 DWORD
CDxtexDoc::NumMips(VOID
)
717 void CDxtexDoc::OnFileOpenAlpha()
721 LPDIRECT3DTEXTURE9 pmiptex
;
723 if (IsCubeMap() || IsVolumeMap())
726 // Premultiplied-alpha files don't support this feature:
728 ((LPDIRECT3DTEXTURE9
)m_ptexOrig
)->GetLevelDesc(0, &sd
);
729 if (sd
.Format
== D3DFMT_DXT2
|| sd
.Format
== D3DFMT_DXT4
)
731 AfxMessageBox(ID_ERROR_PREMULTALPHA
);
735 // Check if the original has alpha
736 if( !FormatContainsAlpha(sd
.Format
) )
738 // If it doesn't then see if the new does
739 if (m_ptexNew
!= NULL
)
741 ((LPDIRECT3DTEXTURE9
)m_ptexNew
)->GetLevelDesc(0, &sd
);
742 if( !FormatContainsAlpha(sd
.Format
) )
744 AfxMessageBox(ID_ERROR_NEEDALPHA
);
749 ReleasePpo(&m_ptexOrig
);
750 m_ptexOrig
= m_ptexNew
;
752 if( AfxGetMainWnd() != NULL
)
753 AfxGetMainWnd()->PostMessage(WM_COMMAND
, ID_VIEW_ORIGINAL
, 0);
758 AfxMessageBox(ID_ERROR_NEEDALPHA
);
763 pmiptex
= (LPDIRECT3DTEXTURE9
)m_ptexOrig
;
765 if (!PromptForBmp(&fileName
))
768 LPDIRECT3DSURFACE9 psurf
;
769 if (FAILED(hr
= pmiptex
->GetSurfaceLevel(0, &psurf
)))
772 if (FAILED(hr
= LoadAlphaIntoSurface(fileName
, psurf
)))
776 else if (m_ptexNew
!= NULL
)
778 ((LPDIRECT3DTEXTURE9
)m_ptexNew
)->GetLevelDesc(0, &sd
);
779 Compress(sd
.Format
, FALSE
);
781 UpdateAllViews(NULL
, 1);
785 HRESULT
CDxtexDoc::LoadAlphaIntoSurface(CString
& strPath
, LPDIRECT3DSURFACE9 psurf
)
789 LPDIRECT3DDEVICE9 pd3ddev
= PDxtexApp()->Pd3ddev();
790 LPDIRECT3DTEXTURE9 ptexAlpha
;
791 LPDIRECT3DSURFACE9 psurfAlpha
;
792 LPDIRECT3DSURFACE9 psurfTarget
;
796 // Load the alpha BMP into psurfAlpha, a new A8R8G8B8 surface
797 hr
= D3DXCreateTextureFromFileEx(pd3ddev
, strPath
, sd
.Width
, sd
.Height
, 1, 0,
798 D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, D3DX_FILTER_TRIANGLE
,
799 D3DX_FILTER_TRIANGLE
, 0, NULL
, NULL
, &ptexAlpha
);
800 hr
= ptexAlpha
->GetSurfaceLevel(0, &psurfAlpha
);
802 // Copy the target surface into an A8R8G8B8 surface
803 hr
= pd3ddev
->CreateOffscreenPlainSurface(sd
.Width
, sd
.Height
, D3DFMT_A8R8G8B8
, D3DPOOL_SCRATCH
, &psurfTarget
, NULL
);
804 hr
= D3DXLoadSurfaceFromSurface(psurfTarget
, NULL
, NULL
, psurf
, NULL
, NULL
,
805 D3DX_FILTER_TRIANGLE
, 0);
807 // Fill in the alpha channels of psurfTarget based on the blue channel of psurfAlpha
808 D3DLOCKED_RECT lrSrc
;
809 D3DLOCKED_RECT lrDest
;
811 hr
= psurfAlpha
->LockRect(&lrSrc
, NULL
, D3DLOCK_READONLY
);
812 hr
= psurfTarget
->LockRect(&lrDest
, NULL
, 0);
816 DWORD
* pdwRowSrc
= (DWORD
*)lrSrc
.pBits
;
817 DWORD
* pdwRowDest
= (DWORD
*)lrDest
.pBits
;
821 LONG dataBytesPerRow
= 4 * sd
.Width
;
823 for (yp
= 0; yp
< sd
.Height
; yp
++)
826 pdwDest
= pdwRowDest
;
827 for (xp
= 0; xp
< sd
.Width
; xp
++)
829 dwAlpha
= *pdwSrc
<< 24;
830 *pdwDest
&= 0x00ffffff;
836 pdwRowSrc
+= lrSrc
.Pitch
/ 4;
837 pdwRowDest
+= lrDest
.Pitch
/ 4;
840 psurfAlpha
->UnlockRect();
841 psurfTarget
->UnlockRect();
843 // Copy psurfTarget back into real surface
844 hr
= D3DXLoadSurfaceFromSurface(psurf
, NULL
, NULL
, psurfTarget
, NULL
, NULL
,
845 D3DX_FILTER_TRIANGLE
, 0);
847 // Release allocated interfaces
848 ReleasePpo(&psurfTarget
);
849 ReleasePpo(&psurfAlpha
);
850 ReleasePpo(&ptexAlpha
);
856 BOOL
CDxtexDoc::PromptForBmp(CString
* pstrPath
)
858 CFileDialog
dlgFile(TRUE
);
861 VERIFY(title
.LoadString(AFX_IDS_OPENFILE
));
866 strFilter
+= "Image Files (*.dds, *.bmp, *.tga, *.jpg, *.png, *.dib)";
867 strFilter
+= (TCHAR
)'\0'; // next string please
868 strFilter
+= _T("*.dds;*.bmp;*.tga;*.jpg;*.png;*.dib");
869 strFilter
+= (TCHAR
)'\0'; // last string
870 dlgFile
.m_ofn
.nMaxCustFilter
++;
872 // append the "*.*" all files filter
874 VERIFY(allFilter
.LoadString(AFX_IDS_ALLFILTER
));
875 strFilter
+= allFilter
;
876 strFilter
+= (TCHAR
)'\0'; // next string please
877 strFilter
+= _T("*.*");
878 strFilter
+= (TCHAR
)'\0'; // last string
879 dlgFile
.m_ofn
.nMaxCustFilter
++;
881 dlgFile
.m_ofn
.lpstrFilter
= strFilter
;
882 dlgFile
.m_ofn
.lpstrTitle
= title
;
883 dlgFile
.m_ofn
.lpstrFile
= pstrPath
->GetBuffer(_MAX_PATH
);
885 INT_PTR nResult
= dlgFile
.DoModal();
886 pstrPath
->ReleaseBuffer();
893 void CDxtexDoc::OpenSubsurface(D3DCUBEMAP_FACES FaceType
, LONG lwMip
, LONG lwSlice
)
897 LPDIRECT3DDEVICE9 pd3ddev
= PDxtexApp()->Pd3ddev();
898 LPDIRECT3DTEXTURE9 ptex
= NULL
;
899 LPDIRECT3DSURFACE9 psurfOrig
= NULL
;
900 LPDIRECT3DSURFACE9 psurfNew
= NULL
;
902 if (!PromptForBmp(&fileName
))
907 hr
= D3DXCreateTextureFromFile(pd3ddev
, fileName
, &ptex
);
908 hr
= ptex
->GetSurfaceLevel(0, &psurfOrig
);
910 else if (IsCubeMap())
912 hr
= ((LPDIRECT3DCUBETEXTURE9
)m_ptexOrig
)->GetCubeMapSurface(FaceType
, lwMip
, &psurfOrig
);
913 if (m_ptexNew
!= NULL
)
914 hr
= ((LPDIRECT3DCUBETEXTURE9
)m_ptexNew
)->GetCubeMapSurface(FaceType
, lwMip
, &psurfNew
);
915 hr
= D3DXLoadSurfaceFromFile(psurfOrig
, NULL
, NULL
, fileName
, NULL
, D3DX_FILTER_TRIANGLE
, 0, NULL
);
919 hr
= ((LPDIRECT3DTEXTURE9
)m_ptexOrig
)->GetSurfaceLevel(lwMip
, &psurfOrig
);
920 if (m_ptexNew
!= NULL
)
921 hr
= ((LPDIRECT3DTEXTURE9
)m_ptexNew
)->GetSurfaceLevel(lwMip
, &psurfNew
);
922 hr
= D3DXLoadSurfaceFromFile(psurfOrig
, NULL
, NULL
, fileName
, NULL
, D3DX_FILTER_TRIANGLE
, 0, NULL
);
925 // Look for "foo_a.bmp" for alpha channel
926 int i
= fileName
.ReverseFind('.');
927 fileName
= fileName
.Left(i
) + "_a.bmp";
929 if (CFile::GetStatus(fileName
, status
))
931 if (FAILED(hr
= LoadAlphaIntoSurface(fileName
, psurfOrig
)))
937 LPDIRECT3DVOLUME9 pvol
;
938 hr
= ((LPDIRECT3DVOLUMETEXTURE9
)m_ptexOrig
)->GetVolumeLevel(lwMip
, &pvol
);
939 hr
= LoadVolumeSliceFromSurface(pvol
, lwSlice
, psurfOrig
);
943 hr
= ((LPDIRECT3DVOLUMETEXTURE9
)m_ptexNew
)->GetVolumeLevel(lwMip
, &pvol
);
944 hr
= LoadVolumeSliceFromSurface(pvol
, lwSlice
, psurfOrig
);
948 else if (psurfNew
!= NULL
)
950 hr
= D3DXLoadSurfaceFromSurface(psurfNew
, NULL
, NULL
, psurfOrig
, NULL
, NULL
, D3DX_FILTER_TRIANGLE
, 0);
953 ReleasePpo(&psurfOrig
);
954 ReleasePpo(&psurfNew
);
957 SetModifiedFlag(TRUE
);
958 UpdateAllViews(NULL
, 1);
962 void CDxtexDoc::OpenAlphaSubsurface(D3DCUBEMAP_FACES FaceType
, LONG lwMip
, LONG lwSlice
)
966 LPDIRECT3DDEVICE9 pd3ddev
= PDxtexApp()->Pd3ddev();
967 LPDIRECT3DTEXTURE9 ptexOrig
= NULL
;
968 LPDIRECT3DTEXTURE9 ptexNew
= NULL
;
969 LPDIRECT3DSURFACE9 psurfOrig
= NULL
;
970 LPDIRECT3DSURFACE9 psurfNew
= NULL
;
971 LPDIRECT3DVOLUME9 pvolOrig
= NULL
;
972 LPDIRECT3DVOLUME9 pvolNew
= NULL
;
974 DWORD dwWidth
= m_dwWidth
;
975 DWORD dwHeight
= m_dwHeight
;
979 for (int i
= 0; i
< lwMip
; i
++)
984 hr
= pd3ddev
->CreateTexture(dwWidth
, dwHeight
, 1,
985 0, D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, &ptexOrig
, NULL
);
986 hr
= ptexOrig
->GetSurfaceLevel(0, &psurfOrig
);
987 hr
= ((LPDIRECT3DVOLUMETEXTURE9
)m_ptexOrig
)->GetVolumeLevel(lwMip
, &pvolOrig
);
988 hr
= LoadSurfaceFromVolumeSlice(pvolOrig
, lwSlice
, psurfOrig
);
989 if (m_ptexNew
!= NULL
)
991 hr
= pd3ddev
->CreateTexture(dwWidth
, dwHeight
, 1,
992 0, D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, &ptexNew
, NULL
);
993 hr
= ptexNew
->GetSurfaceLevel(0, &psurfOrig
);
994 hr
= ((LPDIRECT3DVOLUMETEXTURE9
)m_ptexOrig
)->GetVolumeLevel(lwMip
, &pvolNew
);
995 hr
= LoadSurfaceFromVolumeSlice(pvolNew
, lwSlice
, psurfOrig
);
998 else if (IsCubeMap())
1000 hr
= ((LPDIRECT3DCUBETEXTURE9
)m_ptexOrig
)->GetCubeMapSurface(FaceType
, lwMip
, &psurfOrig
);
1001 ((LPDIRECT3DCUBETEXTURE9
)m_ptexOrig
)->GetLevelDesc(lwMip
, &sd
);
1002 if (sd
.Format
== D3DFMT_DXT2
|| sd
.Format
== D3DFMT_DXT4
)
1004 AfxMessageBox(ID_ERROR_PREMULTALPHA
);
1007 if (m_ptexNew
!= NULL
)
1009 hr
= ((LPDIRECT3DCUBETEXTURE9
)m_ptexNew
)->GetCubeMapSurface(FaceType
, lwMip
, &psurfNew
);
1010 ((LPDIRECT3DCUBETEXTURE9
)m_ptexNew
)->GetLevelDesc(lwMip
, &sd
);
1011 if (sd
.Format
== D3DFMT_DXT2
|| sd
.Format
== D3DFMT_DXT4
)
1013 AfxMessageBox(ID_ERROR_PREMULTALPHA
);
1020 BOOL bAlphaFound
= FALSE
;
1021 hr
= ((LPDIRECT3DTEXTURE9
)m_ptexOrig
)->GetSurfaceLevel(lwMip
, &psurfOrig
);
1022 ((LPDIRECT3DTEXTURE9
)m_ptexOrig
)->GetLevelDesc(lwMip
, &sd
);
1023 if (sd
.Format
== D3DFMT_DXT2
|| sd
.Format
== D3DFMT_DXT4
)
1025 AfxMessageBox(ID_ERROR_PREMULTALPHA
);
1029 // Check if the original has alpha
1030 if( FormatContainsAlpha(sd
.Format
) )
1035 if (m_ptexNew
!= NULL
)
1037 hr
= ((LPDIRECT3DTEXTURE9
)m_ptexNew
)->GetSurfaceLevel(lwMip
, &psurfNew
);
1038 ((LPDIRECT3DTEXTURE9
)m_ptexNew
)->GetLevelDesc(lwMip
, &sd
);
1039 if (sd
.Format
== D3DFMT_DXT2
|| sd
.Format
== D3DFMT_DXT4
)
1041 AfxMessageBox(ID_ERROR_PREMULTALPHA
);
1044 // Check if the new has alpha
1045 if( FormatContainsAlpha(sd
.Format
) )
1051 if( bAlphaFound
== FALSE
)
1053 AfxMessageBox(ID_ERROR_NEEDALPHA
);
1058 if (!PromptForBmp(&fileName
))
1061 if (FAILED(hr
= LoadAlphaIntoSurface(fileName
, psurfOrig
)))
1064 if (psurfNew
!= NULL
)
1066 if (FAILED(hr
= LoadAlphaIntoSurface(fileName
, psurfNew
)))
1070 if (pvolOrig
!= NULL
)
1072 hr
= LoadVolumeSliceFromSurface(pvolOrig
, lwSlice
, psurfOrig
);
1074 if (pvolNew
!= NULL
)
1076 hr
= LoadVolumeSliceFromSurface(pvolNew
, lwSlice
, psurfNew
);
1079 ReleasePpo(&psurfOrig
);
1080 ReleasePpo(&psurfNew
);
1081 ReleasePpo(&ptexOrig
);
1082 ReleasePpo(&ptexNew
);
1083 ReleasePpo(&pvolOrig
);
1084 ReleasePpo(&pvolNew
);
1086 SetModifiedFlag(TRUE
);
1087 UpdateAllViews(NULL
, 1);
1091 void CDxtexDoc::OnFormatChangeCubeMapFaces()
1094 LPDIRECT3DDEVICE9 pd3ddev
= PDxtexApp()->Pd3ddev();
1096 LPDIRECT3DCUBETEXTURE9 ptexCube
;
1098 LPDIRECT3DSURFACE9 psurfSrc
;
1099 LPDIRECT3DSURFACE9 psurfDest
;
1101 CCubeMapDlg cubeMapDlg
;
1102 if (IDCANCEL
== cubeMapDlg
.DoModal())
1105 // Change m_ptexOrig into a cubemap
1106 ((LPDIRECT3DTEXTURE9
)m_ptexOrig
)->GetLevelDesc(0, &sd
);
1107 hr
= D3DXCreateCubeTexture(pd3ddev
, m_dwWidth
, m_numMips
, 0, sd
.Format
, D3DPOOL_MANAGED
, &ptexCube
);
1108 for (iLevel
= 0; iLevel
< m_numMips
; iLevel
++)
1110 hr
= ((LPDIRECT3DTEXTURE9
)m_ptexOrig
)->GetSurfaceLevel(iLevel
, &psurfSrc
);
1111 hr
= ptexCube
->GetCubeMapSurface((D3DCUBEMAP_FACES
)cubeMapDlg
.m_iFace
, iLevel
, &psurfDest
);
1112 hr
= D3DXLoadSurfaceFromSurface(psurfDest
, NULL
, NULL
,
1113 psurfSrc
, NULL
, NULL
, D3DX_FILTER_TRIANGLE
, 0);
1114 ReleasePpo(&psurfSrc
);
1115 ReleasePpo(&psurfDest
);
1117 ReleasePpo(&m_ptexOrig
);
1118 m_ptexOrig
= ptexCube
;
1120 // Change m_ptexNew into a cubemap too
1121 if (m_ptexNew
!= NULL
)
1123 ((LPDIRECT3DTEXTURE9
)m_ptexNew
)->GetLevelDesc(0, &sd
);
1124 hr
= D3DXCreateCubeTexture(pd3ddev
, m_dwWidth
, m_numMips
, 0, sd
.Format
, D3DPOOL_MANAGED
, &ptexCube
);
1125 for (iLevel
= 0; iLevel
< m_numMips
; iLevel
++)
1127 hr
= ((LPDIRECT3DTEXTURE9
)m_ptexNew
)->GetSurfaceLevel(iLevel
, &psurfSrc
);
1128 hr
= ptexCube
->GetCubeMapSurface((D3DCUBEMAP_FACES
)cubeMapDlg
.m_iFace
, iLevel
, &psurfDest
);
1129 hr
= D3DXLoadSurfaceFromSurface(psurfDest
, NULL
, NULL
,
1130 psurfSrc
, NULL
, NULL
, D3DX_FILTER_TRIANGLE
, 0);
1131 ReleasePpo(&psurfSrc
);
1132 ReleasePpo(&psurfDest
);
1134 ReleasePpo(&m_ptexNew
);
1135 m_ptexNew
= ptexCube
;
1137 m_dwCubeMapFlags
= DDS_CUBEMAP_ALLFACES
;
1139 UpdateAllViews(NULL
, 1); // tell CView to pick up new surface pointers
1143 void CDxtexDoc::OnFormatMakeIntoVolumeMap()
1146 LPDIRECT3DDEVICE9 pd3ddev
= PDxtexApp()->Pd3ddev();
1148 LPDIRECT3DVOLUMETEXTURE9 ptexVolume
;
1150 LPDIRECT3DSURFACE9 psurfSrc
;
1151 LPDIRECT3DVOLUME9 pvolumeDest
;
1154 CVolumeMapDlg volumeMapDlg
;
1155 if (IDCANCEL
== volumeMapDlg
.DoModal())
1158 numLayers
= (1 << volumeMapDlg
.m_powLayers
) * 2;
1160 // Change m_ptexOrig into a volumemap
1161 ((LPDIRECT3DTEXTURE9
)m_ptexOrig
)->GetLevelDesc(0, &sd
);
1162 hr
= pd3ddev
->CreateVolumeTexture(m_dwWidth
, m_dwHeight
, numLayers
,
1163 m_numMips
, 0, sd
.Format
, D3DPOOL_SYSTEMMEM
, &ptexVolume
, NULL
);
1166 for (iLevel
= 0; iLevel
< m_numMips
; iLevel
++)
1168 hr
= ((LPDIRECT3DTEXTURE9
)m_ptexOrig
)->GetSurfaceLevel(iLevel
, &psurfSrc
);
1169 hr
= ptexVolume
->GetVolumeLevel(iLevel
, &pvolumeDest
);
1170 hr
= LoadVolumeSliceFromSurface(pvolumeDest
, 0, psurfSrc
);
1171 ReleasePpo(&psurfSrc
);
1172 ReleasePpo(&pvolumeDest
);
1174 ReleasePpo(&m_ptexOrig
);
1175 m_ptexOrig
= ptexVolume
;
1177 // Change m_ptexNew into a volumemap too
1178 if (m_ptexNew
!= NULL
)
1180 ((LPDIRECT3DTEXTURE9
)m_ptexNew
)->GetLevelDesc(0, &sd
);
1181 hr
= pd3ddev
->CreateVolumeTexture(m_dwWidth
, m_dwHeight
, numLayers
,
1182 m_numMips
, 0, sd
.Format
, D3DPOOL_SYSTEMMEM
, &ptexVolume
, NULL
);
1185 for (iLevel
= 0; iLevel
< m_numMips
; iLevel
++)
1187 hr
= ((LPDIRECT3DTEXTURE9
)m_ptexNew
)->GetSurfaceLevel(iLevel
, &psurfSrc
);
1188 hr
= ptexVolume
->GetVolumeLevel(iLevel
, &pvolumeDest
);
1189 hr
= LoadVolumeSliceFromSurface(pvolumeDest
, 0, psurfSrc
);
1190 ReleasePpo(&psurfSrc
);
1191 ReleasePpo(&pvolumeDest
);
1193 ReleasePpo(&m_ptexNew
);
1194 m_ptexNew
= ptexVolume
;
1196 m_dwDepth
= numLayers
;
1198 UpdateAllViews(NULL
, 1); // tell CView to pick up new surface pointers
1202 HRESULT
CDxtexDoc::LoadVolumeSliceFromSurface(LPDIRECT3DVOLUME9 pVolume
, UINT iSlice
, LPDIRECT3DSURFACE9 psurf
)
1211 psurf
->GetDesc(&sd
);
1212 pVolume
->GetDesc(&vd
);
1215 boxSrc
.Right
= sd
.Width
;
1217 boxSrc
.Bottom
= sd
.Height
;
1222 boxDest
.Right
= vd
.Width
;
1224 boxDest
.Bottom
= vd
.Height
;
1225 boxDest
.Front
= iSlice
;
1226 boxDest
.Back
= iSlice
+ 1;
1228 hr
= psurf
->LockRect(&lr
, NULL
, 0);
1232 hr
= D3DXLoadVolumeFromMemory(pVolume
, NULL
, &boxDest
, lr
.pBits
, sd
.Format
, lr
.Pitch
,
1233 0, NULL
, &boxSrc
, D3DX_FILTER_TRIANGLE
, 0);
1235 psurf
->UnlockRect();
1241 HRESULT
CDxtexDoc::LoadSurfaceFromVolumeSlice(LPDIRECT3DVOLUME9 pVolume
, UINT iSlice
, LPDIRECT3DSURFACE9 psurf
)
1249 pVolume
->GetDesc(&vd
);
1252 box
.Right
= vd
.Width
;
1254 box
.Bottom
= vd
.Height
;
1256 box
.Back
= iSlice
+ 1;
1259 rc
.right
= vd
.Width
;
1261 rc
.bottom
= vd
.Height
;
1263 hr
= pVolume
->LockBox(&lb
, &box
, 0);
1267 hr
= D3DXLoadSurfaceFromMemory(psurf
, NULL
, NULL
, lb
.pBits
, vd
.Format
, lb
.RowPitch
,
1268 NULL
, &rc
, D3DX_FILTER_TRIANGLE
, 0);
1270 pVolume
->UnlockBox();
1276 HRESULT
CDxtexDoc::BltAllLevels(D3DCUBEMAP_FACES FaceType
,
1277 LPDIRECT3DBASETEXTURE9 ptexSrc
, LPDIRECT3DBASETEXTURE9 ptexDest
)
1280 LPDIRECT3DTEXTURE9 pmiptexSrc
;
1281 LPDIRECT3DTEXTURE9 pmiptexDest
;
1282 LPDIRECT3DCUBETEXTURE9 pcubetexSrc
;
1283 LPDIRECT3DCUBETEXTURE9 pcubetexDest
;
1284 LPDIRECT3DVOLUMETEXTURE9 pvoltexSrc
;
1285 LPDIRECT3DVOLUMETEXTURE9 pvoltexDest
;
1290 pvoltexSrc
= (LPDIRECT3DVOLUMETEXTURE9
)ptexSrc
;
1291 pvoltexDest
= (LPDIRECT3DVOLUMETEXTURE9
)ptexDest
;
1293 else if (IsCubeMap())
1295 pcubetexSrc
= (LPDIRECT3DCUBETEXTURE9
)ptexSrc
;
1296 pcubetexDest
= (LPDIRECT3DCUBETEXTURE9
)ptexDest
;
1300 pmiptexSrc
= (LPDIRECT3DTEXTURE9
)ptexSrc
;
1301 pmiptexDest
= (LPDIRECT3DTEXTURE9
)ptexDest
;
1304 for (iLevel
= 0; iLevel
< m_numMips
; iLevel
++)
1308 LPDIRECT3DVOLUME9 pvolSrc
= NULL
;
1309 LPDIRECT3DVOLUME9 pvolDest
= NULL
;
1310 hr
= pvoltexSrc
->GetVolumeLevel(iLevel
, &pvolSrc
);
1311 hr
= pvoltexDest
->GetVolumeLevel(iLevel
, &pvolDest
);
1312 hr
= D3DXLoadVolumeFromVolume(pvolDest
, NULL
, NULL
,
1313 pvolSrc
, NULL
, NULL
, D3DX_FILTER_TRIANGLE
, 0);
1314 ReleasePpo(&pvolSrc
);
1315 ReleasePpo(&pvolDest
);
1317 else if (IsCubeMap())
1319 LPDIRECT3DSURFACE9 psurfSrc
= NULL
;
1320 LPDIRECT3DSURFACE9 psurfDest
= NULL
;
1321 hr
= pcubetexSrc
->GetCubeMapSurface(FaceType
, iLevel
, &psurfSrc
);
1322 hr
= pcubetexDest
->GetCubeMapSurface(FaceType
, iLevel
, &psurfDest
);
1323 hr
= D3DXLoadSurfaceFromSurface(psurfDest
, NULL
, NULL
,
1324 psurfSrc
, NULL
, NULL
, D3DX_FILTER_TRIANGLE
, 0);
1325 ReleasePpo(&psurfSrc
);
1326 ReleasePpo(&psurfDest
);
1330 LPDIRECT3DSURFACE9 psurfSrc
= NULL
;
1331 LPDIRECT3DSURFACE9 psurfDest
= NULL
;
1332 hr
= pmiptexSrc
->GetSurfaceLevel(iLevel
, &psurfSrc
);
1333 hr
= pmiptexDest
->GetSurfaceLevel(iLevel
, &psurfDest
);
1334 hr
= D3DXLoadSurfaceFromSurface(psurfDest
, NULL
, NULL
,
1335 psurfSrc
, NULL
, NULL
, D3DX_FILTER_TRIANGLE
, 0);
1336 ReleasePpo(&psurfSrc
);
1337 ReleasePpo(&psurfDest
);
1345 HRESULT
CDxtexDoc::Resize(DWORD dwWidthNew
, DWORD dwHeightNew
)
1348 LPDIRECT3DTEXTURE9 pmiptexNew
;
1349 LPDIRECT3DDEVICE9 pd3ddev
= PDxtexApp()->Pd3ddev();
1351 hr
= pd3ddev
->CreateTexture(dwWidthNew
, dwHeightNew
, m_numMips
,
1352 0, GetFormat(m_ptexOrig
), D3DPOOL_MANAGED
, &pmiptexNew
, NULL
);
1355 if (FAILED(BltAllLevels(D3DCUBEMAP_FACE_FORCE_DWORD
, m_ptexOrig
, pmiptexNew
)))
1357 ReleasePpo(&m_ptexOrig
);
1358 m_ptexOrig
= pmiptexNew
;
1360 if( m_ptexNew
!= NULL
)
1362 hr
= pd3ddev
->CreateTexture(dwWidthNew
, dwHeightNew
, m_numMips
,
1363 0, GetFormat(m_ptexOrig
), D3DPOOL_MANAGED
, &pmiptexNew
, NULL
);
1366 if (FAILED(BltAllLevels(D3DCUBEMAP_FACE_FORCE_DWORD
, m_ptexNew
, pmiptexNew
)))
1368 ReleasePpo(&m_ptexNew
);
1369 m_ptexNew
= pmiptexNew
;
1372 m_dwWidth
= dwWidthNew
;
1373 m_dwHeight
= dwHeightNew
;
1374 SetModifiedFlag(TRUE
);
1375 UpdateAllViews(NULL
, 4);
1381 void CDxtexDoc::OpenCubeFace(D3DCUBEMAP_FACES FaceType
)
1385 LPDIRECT3DSURFACE9 psurfOrig
= NULL
;
1386 LPDIRECT3DSURFACE9 psurfNew
= NULL
;
1391 hr
= ((LPDIRECT3DCUBETEXTURE9
)m_ptexOrig
)->GetCubeMapSurface(FaceType
, 0, &psurfOrig
);
1392 if (m_ptexNew
!= NULL
)
1393 hr
= ((LPDIRECT3DCUBETEXTURE9
)m_ptexNew
)->GetCubeMapSurface(FaceType
, 0, &psurfNew
);
1395 if (!PromptForBmp(&fileName
))
1398 hr
= D3DXLoadSurfaceFromFile(psurfOrig
, NULL
, NULL
, fileName
, NULL
, D3DX_FILTER_TRIANGLE
, 0, NULL
);
1400 // Look for "foo_a.bmp" for alpha channel
1401 int i
= fileName
.ReverseFind('.');
1402 fileName
= fileName
.Left(i
) + "_a.bmp";
1404 if (CFile::GetStatus(fileName
, status
))
1406 if (FAILED(hr
= LoadAlphaIntoSurface(fileName
, psurfOrig
)))
1412 hr
= D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE9
)m_ptexOrig
, NULL
, 0, D3DX_FILTER_TRIANGLE
);
1416 if (psurfNew
!= NULL
)
1418 hr
= D3DXLoadSurfaceFromSurface(psurfNew
, NULL
, NULL
, psurfOrig
, NULL
, NULL
, D3DX_FILTER_TRIANGLE
, 0);
1422 hr
= D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE9
)m_ptexNew
, NULL
, 0, D3DX_FILTER_TRIANGLE
);
1426 ReleasePpo(&psurfOrig
);
1427 ReleasePpo(&psurfNew
);
1429 SetModifiedFlag(TRUE
);
1430 UpdateAllViews(NULL
, 1);
1434 void CDxtexDoc::OpenAlphaCubeFace(D3DCUBEMAP_FACES FaceType
)
1438 LPDIRECT3DSURFACE9 psurfOrig
= NULL
;
1439 LPDIRECT3DSURFACE9 psurfNew
= NULL
;
1445 hr
= ((LPDIRECT3DCUBETEXTURE9
)m_ptexOrig
)->GetCubeMapSurface(FaceType
, 0, &psurfOrig
);
1446 ((LPDIRECT3DCUBETEXTURE9
)m_ptexOrig
)->GetLevelDesc(0, &sd
);
1447 if (sd
.Format
== D3DFMT_DXT2
|| sd
.Format
== D3DFMT_DXT4
)
1449 AfxMessageBox(ID_ERROR_PREMULTALPHA
);
1452 if (m_ptexNew
!= NULL
)
1454 hr
= ((LPDIRECT3DCUBETEXTURE9
)m_ptexNew
)->GetCubeMapSurface(FaceType
, 0, &psurfNew
);
1457 if (!PromptForBmp(&fileName
))
1460 if (FAILED(hr
= LoadAlphaIntoSurface(fileName
, psurfOrig
)))
1463 if (psurfNew
!= NULL
)
1465 if (FAILED(hr
= LoadAlphaIntoSurface(fileName
, psurfNew
)))
1471 hr
= D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE9
)m_ptexOrig
, NULL
, 0, D3DX_FILTER_TRIANGLE
);
1475 if (psurfNew
!= NULL
)
1477 hr
= D3DXLoadSurfaceFromSurface(psurfNew
, NULL
, NULL
, psurfOrig
, NULL
, NULL
, D3DX_FILTER_TRIANGLE
, 0);
1481 hr
= D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE9
)m_ptexNew
, NULL
, 0, D3DX_FILTER_TRIANGLE
);
1485 ReleasePpo(&psurfOrig
);
1486 ReleasePpo(&psurfNew
);
1488 SetModifiedFlag(TRUE
);
1489 UpdateAllViews(NULL
, 1);
1493 DWORD
CDxtexDoc::DwDepthAt(LONG lwMip
)
1495 DWORD dwDepth
= m_dwDepth
;
1496 while (lwMip
> 0 && dwDepth
> 1)
1505 void CDxtexDoc::OnFormatChangeSurfaceFmt()
1507 CChangeFmtDlg changeFmtDlg
;
1508 LPDIRECT3DBASETEXTURE9 ptex
;
1510 ptex
= (m_ptexNew
== NULL
? m_ptexOrig
: m_ptexNew
);
1515 ((LPDIRECT3DVOLUMETEXTURE9
)ptex
)->GetLevelDesc(0, &vd
);
1516 changeFmtDlg
.m_fmt
= vd
.Format
;
1518 else if (IsCubeMap())
1521 ((LPDIRECT3DCUBETEXTURE9
)ptex
)->GetLevelDesc(0, &sd
);
1522 changeFmtDlg
.m_fmt
= sd
.Format
;
1527 ((LPDIRECT3DTEXTURE9
)ptex
)->GetLevelDesc(0, &sd
);
1528 changeFmtDlg
.m_fmt
= sd
.Format
;
1531 changeFmtDlg
.m_bVolume
= IsVolumeMap();
1533 if (IDCANCEL
== changeFmtDlg
.DoModal())
1536 Compress(changeFmtDlg
.m_fmt
, TRUE
);
1540 void CDxtexDoc::OnUpdateFileOpenAlpha(CCmdUI
* pCmdUI
)
1542 pCmdUI
->Enable(!IsCubeMap() && !IsVolumeMap());
1546 void CDxtexDoc::OnUpdateFormatGenerateMipmaps(CCmdUI
* pCmdUI
)
1548 pCmdUI
->Enable(m_numMips
<= 1);
1552 void CDxtexDoc::OnUpdateFormatChangeCubeMapFaces(CCmdUI
* pCmdUI
)
1554 pCmdUI
->Enable(!IsCubeMap() && !IsVolumeMap());
1558 void CDxtexDoc::OnUpdateFormatMakeIntoVolumeMap(CCmdUI
* pCmdUI
)
1560 pCmdUI
->Enable(!IsCubeMap() && !IsVolumeMap());
1564 void CDxtexDoc::OnFormatResize()
1566 CResizeDialog resizeDialog
;
1568 resizeDialog
.m_oldWidth
.Format("%d", m_dwWidth
);
1569 resizeDialog
.m_oldHeight
.Format("%d", m_dwHeight
);
1570 resizeDialog
.m_newWidth
= m_dwWidth
;
1571 resizeDialog
.m_newHeight
= m_dwHeight
;
1572 resizeDialog
.m_oldWidth
.Format("%d", m_dwWidth
);
1573 if( IDOK
== resizeDialog
.DoModal() )
1574 Resize(resizeDialog
.m_newWidth
, resizeDialog
.m_newHeight
);
1578 void CDxtexDoc::OnUpdateFormatResize(CCmdUI
* pCmdUI
)
1580 pCmdUI
->Enable(!IsCubeMap() && !IsVolumeMap());
1583 struct GenerateSpecularLookupData
1588 VOID WINAPI
SpecularColorFill(D3DXVECTOR4
* pOut
, const D3DXVECTOR2
* pTexCoord
, const D3DXVECTOR2
* pTexelSize
, LPVOID pData
)
1590 float d
= pTexCoord
->x
;
1591 float s
= static_cast<float>(pow(pTexCoord
->y
, reinterpret_cast<GenerateSpecularLookupData
*>(pData
)->power
));
1593 if (pTexCoord
->x
< pTexelSize
->x
)
1602 void CDxtexDoc::OnFormatGeneratespecularlookup()
1609 CSpecularPowerDialog specularPowerDialog
;
1610 if( IDOK
== specularPowerDialog
.DoModal() )
1612 GenerateSpecularLookupData specularLookupData
;
1613 specularLookupData
.power
= static_cast<float>(atof(specularPowerDialog
.m_specularPower
));
1615 // TODO: Add your command handler code here
1616 HRESULT hresult
= D3DXFillTexture((LPDIRECT3DTEXTURE9
)m_ptexOrig
, SpecularColorFill
, &specularLookupData
);
1618 SetModifiedFlag(TRUE
);
1619 UpdateAllViews(NULL
, 4);
1623 void CDxtexDoc::OnUpdateFormatGeneratespecularlookup(CCmdUI
* pCmdUI
)
1625 // TODO: Add your command update UI handler code here
1626 pCmdUI
->Enable(!IsCubeMap() && !IsVolumeMap());