// DlgCreateMegatexture.cpp : implementation file // #include "stdafx.h" #include "Megatron.h" #include "DlgCreateMegatexture.h" #include #include "Proxies\ProxyHeaders.hpp" #include "ElementProxies\ElementProxies.hpp" #include //#include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CDlgCreateMegatexture dialog CDlgCreateMegatexture::CDlgCreateMegatexture(CWnd* pParent /*=NULL*/) : CDialog(CDlgCreateMegatexture::IDD, pParent) { //{{AFX_DATA_INIT(CDlgCreateMegatexture) //}}AFX_DATA_INIT m_pList = NULL; m_pCell = NULL; m_pImage = NULL; m_pNoteFile = NULL; } CDlgCreateMegatexture::~CDlgCreateMegatexture() { if (m_pCell) delete m_pCell; if (m_pImage) delete m_pImage; } void CDlgCreateMegatexture::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDlgCreateMegatexture) DDX_Control(pDX, IDC_NAME, m_wndName); DDX_Control(pDX, IDC_MEGAPREVIEW, m_wndMegaPreview); DDX_Control(pDX, IDC_LIST, m_wndList); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDlgCreateMegatexture, CDialog) //{{AFX_MSG_MAP(CDlgCreateMegatexture) ON_LBN_SELCHANGE(IDC_LIST, OnSelchangeList) ON_WM_DRAWITEM() ON_BN_CLICKED(IDC_RADIO1, OnRadio1) ON_BN_CLICKED(IDC_RADIO2, OnRadio2) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDlgCreateMegatexture message handlers BOOL CDlgCreateMegatexture::OnInitDialog() { CDialog::OnInitDialog(); CWnd *pWnd = GetDlgItem(IDC_RADIO2); ((CButton *)pWnd)->SetCheck(true); OnRadio2(); CPtrList *poslist = NULL; if (m_pList) { POSITION pos = m_pList->GetHeadPosition(); if (pos) { poslist = (CPtrList *)m_pList->GetNext(pos); } while (pos) { bool bsel = false; if (POSITION pos1 = poslist->Find((LPVOID)pos)) { poslist->RemoveAt(pos1); bsel = true; } Stuff::Page *page = (Stuff::Page *)m_pList->GetNext(pos); Check_Object(page); int index = m_wndList.AddString(page->GetName()); m_wndList.SetItemData(index,(DWORD)page); if (bsel) { m_wndList.SetSel(index,true); } } } OnSelchangeList(); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } static CDWordArray arrVerts; CCell::CCell() { bSplit = false; for (int x=0;x<4;x++) m_arrChildren[x] = NULL; m_image = NULL; state = 0; } CCell::~CCell() { for (int x=0;x<4;x++) if (m_arrChildren[x]) delete m_arrChildren[x]; } CPoint CCell::GetPoint1() { DWORD dw = arrVerts[V1]; CPoint pt(LOWORD(dw),HIWORD(dw)); return pt; } int CCell::AddVert(int x,int y) { DWORD dw = MAKELONG(x,y); return arrVerts.Add(dw); } int CCell::GetXDim() { DWORD dw1 = arrVerts[V1]; WORD x1 = LOWORD(dw1); DWORD dw2 = arrVerts[V2]; WORD x2 = LOWORD(dw2); return (x2-x1); } int CCell::GetYDim() { DWORD dw1 = arrVerts[V1]; WORD y1 = HIWORD(dw1); DWORD dw2 = arrVerts[V2]; WORD y2 = HIWORD(dw2); return (y2-y1); } int CCell::GetV1() { return V1; } int CCell::GetV2() { return V2; } int CCell::SetVerts(int a,int b) { V1 = a; V2 = b; return 1; } int CCell::CreateCell(int xSize,int ySize) { V1 = AddVert(0,0); V2 = AddVert(xSize,ySize); state = 0; // Empty return 1; } CCell *CCell::FillCell(Image *image) { if (2==state) return NULL; int xSize = image->GetWidth(); int ySize = image->GetHeight(); int xdim = GetXDim(); int ydim = GetYDim(); if ((xSize==xdim)&&(ySize==ydim)&&(0==state)) { // use this cell, fill it up totally m_image = image; name = image->GetFileName(); state = 2; return this; } else { if ((xSize<=xdim) && (ySize<=ydim)) { SplitCell(xSize,ySize); BYTE flags = 0; for (int x=0;x<4;x++) { CCell *cell = m_arrChildren[x]->FillCell(image); flags |= (2==m_arrChildren[x]->state) << x; if (cell) { if (15==flags) state = 2; else state = 1; return cell; } } } else { // Cannot fill this cell with something this big, unless I union with neighbors return NULL; } } return NULL; } int CCell::SplitCell(int xSize,int ySize) { if (!bSplit) { CPoint pt1 = GetPoint1(); int xdim = GetXDim(); int ydim = GetYDim(); int topleft = GetV1(); int bottomright = GetV2(); int middle = AddVert(pt1.x+xSize,pt1.y+ySize); int middletop = AddVert(pt1.x+xSize,pt1.y); int middleleft = AddVert(pt1.x,pt1.y+ySize); int middlebottom = AddVert(pt1.x+xSize,pt1.y+ydim); int middleright = AddVert(pt1.x+xdim,pt1.y+ySize); CCell *cell = m_arrChildren[0] = new CCell; cell->SetVerts(topleft,middle); cell = m_arrChildren[1] = new CCell; cell->SetVerts(middletop,middleright); cell = m_arrChildren[2] = new CCell; cell->SetVerts(middleleft,middlebottom); cell = m_arrChildren[3] = new CCell; cell->SetVerts(middle,bottomright); bSplit = true; } return 4; } int BuildMegaTexture(CCell *pCell,Image *pImage) { if (pCell) { if (pCell->m_image) { CPoint pt = pCell->GetPoint1(); pImage->Blt(*(pCell->m_image),pt.x,pt.y); } for (int x=0;x<4;x++) BuildMegaTexture(pCell->m_arrChildren[x],pImage); } return 1; } CCell *ArrangeTextures(Stuff::NotationFile *pMega_file,CString mega_name,int xSize,int ySize,CMapStringToPtr *pMapImages,Image *mega_image) { Stuff::Page *mega_page = pMega_file->AddPage(mega_name); CString str; str.Format("%d %d",xSize,ySize); mega_page->AppendEntry("PageSize",str); CCell *pCell = new CCell; pCell->CreateCell(xSize,ySize); POSITION pos = pMapImages->GetStartPosition(); while (pos) { CString imagename; LPVOID lpvoid; pMapImages->GetNextAssoc(pos,imagename,lpvoid); Image *pImage = (Image *)lpvoid; CCell *cell = pCell->FillCell(pImage); if (NULL == cell) { CString str; str.Format("Could not fit texture %s",imagename); MessageBox(NULL,str,"Fill Cell",MB_OK); } } BuildMegaTexture(pCell,mega_image); return pCell; } void CDlgCreateMegatexture::OnSelchangeList() { CString mega_name = "MegaTexture"; int iCount = m_wndList.GetSelCount(); int *items = new int[iCount]; m_wndList.GetSelItems(iCount,items); CMapStringToPtr mapImages; for (int x=0;xGetName(); const char *entry; if (page->GetEntry("Alias",&entry)) { imagename = entry; } CString path = "content\\textures\\"+imagename; Image *image = new Image; CString fullname = path+".tga"; if (gos_DoesFileExist(fullname)) { image->Load((char *)(LPCTSTR)fullname); } else { fullname = path+".png"; if (gos_DoesFileExist(fullname)) { image->Load((char *)(LPCTSTR)fullname); } } if(image->GetBpp()==32) image->MaskTo(RGBMask(0x00ff0000,0x0000ff00,0x000000ff,0xff000000)); else image->MaskTo(RGBMask(0x00ff0000,0x0000ff00,0x000000ff)); mapImages[imagename] = image; /* m_BackBuffer.DeleteObject(); m_wndMegaPreview.Invalidate(); CDC memDC,*hfDC; hfDC=GetDC(); BOOL bres; bres=m_BackBuffer.CreateCompatibleBitmap(hfDC,image.GetWidth(),image.GetHeight()); Verify(bres); memDC.CreateCompatibleDC(hfDC); memDC.SelectObject(&m_BackBuffer); BITMAPINFOHEADER bhd; BITMAPINFO binf; bhd.biSize=sizeof(BITMAPINFOHEADER); bhd.biWidth=image.GetWidth(); bhd.biHeight=-image.GetHeight(); bhd.biPlanes=1; bhd.biBitCount=image.GetBpp(); bhd.biCompression=BI_RGB; bhd.biSizeImage=0; bhd.biClrImportant=0; binf.bmiHeader=bhd; BYTE *imgdat=(BYTE *)(image.Lock()); SetDIBitsToDevice(memDC,0,0,image.GetWidth(), image.GetHeight(),0,0,0,image.GetWidth(),imgdat, &binf,DIB_RGB_COLORS); image.UnLock(); memDC.DeleteDC(); ReleaseDC(hfDC);*/ } delete items; Stuff::NotationFile mega_file; if (m_pCell) delete m_pCell; if (m_pImage) delete m_pImage; m_pImage = new Image; m_pImage->CreateSolid(pagesize,pagesize,ImgRGBColor(0xff,0xff,0xff,0xff),ITYPE_RGB,32); m_pCell = ArrangeTextures(&mega_file,mega_name,pagesize,pagesize,&mapImages,m_pImage); POSITION pos = mapImages.GetStartPosition(); while (pos) { CString imagename; LPVOID lpvoid; mapImages.GetNextAssoc(pos,imagename,lpvoid); Image *pImage = (Image *)lpvoid; delete pImage; } mapImages.RemoveAll(); //mega_page->AppendEntry("Texture",imagename); // Create the scene stuff /* ElementRenderer::GroupElement *root = new ElementRenderer::GroupElement; Check_Object(root); ElementProxies::ElementSceneProxy *element_scene = ElementProxies::ElementSceneProxy::MakeProxy( root, "content\\textures\\" ); Check_Object(element_scene); ElementProxies::MLRStatePoolProxy *state_library = Cast_Object(ElementProxies::MLRStatePoolProxy *,element_scene->GetStateLibrary()); Check_Object(state_library); Proxies::TextureLibrary *texture_library = state_library->GetTextureLibrary(); Check_Object(texture_library); // do the arranging Proxies::ArrangeMegatexturesProcess arrange_process(&mega_file); texture_library->ArrangeMegatextures(&arrange_process); /* Proxies::BuildMegatexturesProcess build_process(&mega_file); texture_library->BuildMegatextures(&build_process); */ // Recycle the texture library // //delete texture_library; //delete state_library; /* element_scene->Destroy(); if (ElementProxies::MLRTexturePoolProxy::Instance) { ElementProxies::MLRTexturePoolProxy::Instance->CloseLibrary(true); } //delete root; /*CString targa_name = "content\\textures\\"; targa_name+=mega_name+".tga"; Proxies::TextureProxy *texture_proxy = texture_library->UseTextureProxy(mega_name); texture_proxy->SaveAsTarga(targa_name); */ { /* CString path = "content\\textures\\"+mega_name; Image image; CString fullname = path+".tga"; if (gos_DoesFileExist(fullname)) { image.Load((char *)(LPCTSTR)fullname); } /*else { fullname = path+".png"; if (gos_DoesFileExist(fullname)) { image.Load((char *)(LPCTSTR)fullname); } }*/ m_BackBuffer.DeleteObject(); m_wndMegaPreview.Invalidate(); CDC memDC,*hfDC; hfDC=GetDC(); BOOL bres; bres=m_BackBuffer.CreateCompatibleBitmap(hfDC,m_pImage->GetWidth(),m_pImage->GetHeight()); Verify(bres); memDC.CreateCompatibleDC(hfDC); memDC.SelectObject(&m_BackBuffer); BITMAPINFOHEADER bhd; BITMAPINFO binf; bhd.biSize=sizeof(BITMAPINFOHEADER); bhd.biWidth=m_pImage->GetWidth(); bhd.biHeight=-m_pImage->GetHeight(); bhd.biPlanes=1; bhd.biBitCount=m_pImage->GetBpp(); bhd.biCompression=BI_RGB; bhd.biSizeImage=0; bhd.biClrImportant=0; binf.bmiHeader=bhd; BYTE *imgdat=(BYTE *)(m_pImage->Lock()); SetDIBitsToDevice(memDC,0,0,m_pImage->GetWidth(), m_pImage->GetHeight(),0,0,0,m_pImage->GetWidth(),imgdat, &binf,DIB_RGB_COLORS); m_pImage->UnLock(); memDC.DeleteDC(); ReleaseDC(hfDC); } mega_file.IgnoreChanges(); } void CDlgCreateMegatexture::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) { switch (lpDrawItemStruct->CtlID) { case IDC_MEGAPREVIEW: { CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC); HBITMAP hBitmap = m_BackBuffer; if (hBitmap) { CDC memDC; int res; BITMAP bmp; res=m_BackBuffer.GetBitmap(&bmp); Verify(res); BOOL bres; bres=memDC.CreateCompatibleDC(pDC); Verify(bres); memDC.SelectObject(&m_BackBuffer); CRect hfrct; GetClientRect(&hfrct); //pDC->SetStretchBltMode(COLORONCOLOR); bres=pDC->BitBlt(0,0,hfrct.Width(),hfrct.Height(),&memDC,0,0,SRCCOPY); Verify(bres); memDC.DeleteDC(); } return; } } CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct); } int ConstructPage(CCell *pCell,Stuff::Page *page) { if (NULL == pCell) return 0; if (pCell->m_image) // Acutally m_image is already deleted by now so I can't use it { char name[MAX_PATH]; _splitpath(pCell->name,NULL,NULL,name,NULL); CString str; CPoint pt = pCell->GetPoint1(); str.Format("%d %d",pt.x,pt.y); page->AppendEntry(name,str); } int count = 1; for (int x=0;x<4;x++) { count += ConstructPage(pCell->m_arrChildren[x],page); } return count; } void CDlgCreateMegatexture::OnOK() { CString str; m_wndName.GetWindowText(str); if (str.GetLength()==0) { MessageBox("Must give new Megatexture a name"); return; } if (NULL == m_pImage) { MessageBox("Must select at least one image to create Megatexture"); return; } Stuff::Page *page = m_pNoteFile->AddPage(str); CString str1; str1.Format("%d %d",pagesize,pagesize); page->AppendEntry("PageSize",str1); ConstructPage(m_pCell,page); str = "content\\textures\\"+str+".tga"; m_pImage->SaveTga((char *)(LPCTSTR)str); CDialog::OnOK(); } void CDlgCreateMegatexture::OnRadio1() { pagesize = 256; OnSelchangeList(); } void CDlgCreateMegatexture::OnRadio2() { pagesize = 512; OnSelchangeList(); }