1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "object_viewer.h"
20 #include "texture_anim_dlg.h"
21 #include "attrib_dlg.h"
22 #include "texture_chooser.h"
23 #include "nel/3d/ps_particle.h"
24 #include "nel/3d/ps_particle_basic.h"
25 #include "nel/3d/texture_grouped.h"
26 #include "nel/3d/texture_file.h"
29 #include "nel/misc/smart_ptr.h"
30 #include "multi_tex_dlg.h"
33 /////////////////////////////////////////////////////////////////////////////
34 // CTextureAnimDlg dialog
37 CTextureAnimDlg::CTextureAnimDlg(CParticleWorkspace::CNode
*ownerNode
,
38 NL3D::CPSTexturedParticle
*p
,
39 NL3D::CPSMultiTexturedParticle
*mtp
/*= NULL*/)
42 _TextureChooser(NULL
),
43 _TextureIndexDialog(NULL
),
48 //{{AFX_DATA_INIT(CTextureAnimDlg)
49 m_EnableTextureAnim
= p
->getTextureGroup() ? TRUE
: FALSE
;
50 m_MultiTexEnable
= FALSE
;
54 CTextureAnimDlg::~CTextureAnimDlg()
58 _MultiTexDlg
->DestroyWindow();
66 BOOL
CTextureAnimDlg::EnableWindow( BOOL bEnable
)
68 if (_TextureChooser
) _TextureChooser
->EnableWindow(bEnable
);
69 GetDlgItem(IDC_CHOOSE_TEXTURES
)->EnableWindow(bEnable
& m_EnableTextureAnim
);
70 GetDlgItem(IDC_ENABLE_TEXTURE_ANIM
)->EnableWindow(bEnable
);
73 ((CButton
*) GetDlgItem(IDC_MULTITEX
))->EnableWindow(bEnable
);
74 GetDlgItem(IDC_EDIT_MULTITEX
)->EnableWindow(bEnable
& (_MTP
->isMultiTextureEnabled() ? 1 : 0));
76 if (_TextureIndexDialog
)
78 _TextureIndexDialog
->EnableWindow(bEnable
);
80 return CDialog::EnableWindow(bEnable
);
83 void CTextureAnimDlg::init(sint x
, sint y
, CWnd
*pParent
)
85 Create(IDD_TEXTURE_ANIM
, pParent
);
88 MoveWindow(x
, y
, x
+ r
.right
, y
+ r
.bottom
);
92 GetDlgItem(IDC_MULTITEX
)->ShowWindow(FALSE
);
93 GetDlgItem(IDC_EDIT_MULTITEX
)->ShowWindow(FALSE
);
94 GetDlgItem(IDC_MULTITEX_BORDER
)->ShowWindow(FALSE
);
99 void CTextureAnimDlg::cleanCtrl(void)
103 _TextureChooser
->DestroyWindow();
104 delete _TextureChooser
;
105 _TextureChooser
= NULL
;
107 if (_TextureIndexDialog
)
109 _TextureIndexDialog
->DestroyWindow();
110 delete _TextureIndexDialog
;
111 _TextureIndexDialog
= NULL
;
116 void CTextureAnimDlg::setupCtrl(void)
118 // is there an animation ?
119 if (_EditedParticle
->getTextureGroup())
121 if (!_TextureIndexDialog
)
124 _TextureIndexDialog
= new CAttribDlgInt("TEXTURE_INDEX", _Node
, 0, _EditedParticle
->getTextureGroup()->getNbTextures() - 1);
125 _TextureIndexWrapper
.P
= _EditedParticle
;
126 _TextureIndexDialog
->setWrapper(&_TextureIndexWrapper
);
127 _TextureIndexDialog
->setSchemeWrapper(&_TextureIndexWrapper
);
129 HBITMAP bmh
= LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_ANIM_SEQUENCE
));
130 _TextureIndexDialog
->init(bmh
, 0, 30, this);
131 m_ChooseTextures
.EnableWindow(TRUE
);
135 int display
= _MTP
->isMultiTextureEnabled() ? 1 : 0;
136 m_MultiTexEnable
= display
;
137 GetDlgItem(IDC_EDIT_MULTITEX
)->EnableWindow(display
);
138 GetDlgItem(IDC_MULTITEX
)->EnableWindow(TRUE
);
141 else // no animation, just show a texture chooser
143 _TextureChooser
= new CTextureChooser(_MTP
, _Node
);
144 _TextureWrapper
.P
= _EditedParticle
;
145 _TextureChooser
->setWrapper(&_TextureWrapper
);
146 _TextureChooser
->init(0, 30, this);
147 m_ChooseTextures
.EnableWindow(FALSE
);
152 ((CButton
*) GetDlgItem(IDC_MULTITEX
))->SetCheck(0);
153 GetDlgItem(IDC_EDIT_MULTITEX
)->EnableWindow(0);
154 GetDlgItem(IDC_MULTITEX
)->EnableWindow(0);
164 void CTextureAnimDlg::DoDataExchange(CDataExchange
* pDX
)
166 CDialog::DoDataExchange(pDX
);
167 //{{AFX_DATA_MAP(CTextureAnimDlg)
168 DDX_Control(pDX
, IDC_CHOOSE_TEXTURES
, m_ChooseTextures
);
169 DDX_Check(pDX
, IDC_ENABLE_TEXTURE_ANIM
, m_EnableTextureAnim
);
170 DDX_Check(pDX
, IDC_MULTITEX
, m_MultiTexEnable
);
175 BEGIN_MESSAGE_MAP(CTextureAnimDlg
, CDialog
)
176 //{{AFX_MSG_MAP(CTextureAnimDlg)
177 ON_BN_CLICKED(IDC_CHOOSE_TEXTURES
, OnChooseTextures
)
178 ON_BN_CLICKED(IDC_ENABLE_TEXTURE_ANIM
, OnEnableTextureAnim
)
179 ON_BN_CLICKED(IDC_MULTITEX
, OnMultiTex
)
180 ON_BN_CLICKED(IDC_EDIT_MULTITEX
, OnEditMultitex
)
184 /////////////////////////////////////////////////////////////////////////////
185 // CTextureAnimDlg message handlers
187 void CTextureAnimDlg::OnChooseTextures()
190 _GradientInterface
.P
= _EditedParticle
;
191 CValueGradientDlg
vd(&_GradientInterface
, _Node
, false, this, NULL
, false, 1);
192 _GradientInterface
.Dlg
= &vd
;
196 void CTextureAnimDlg::OnEnableTextureAnim()
199 if (!m_EnableTextureAnim
)
201 _EditedParticle
->setTexture(NULL
);
205 // put a dummy texture as a first texture
206 NLMISC::CSmartPtr
<NL3D::ITexture
> tex
= (NL3D::ITexture
*) new NL3D::CTextureFile(std::string(""));
207 NL3D::CTextureGrouped
*tg
= new NL3D::CTextureGrouped
;
208 tg
->setTextures(&tex
, 1);
209 _EditedParticle
->setTextureGroup(tg
);
210 _EditedParticle
->setTextureIndex(0);
214 updateModifiedFlag();
218 ////////////////////////////////////////////////////////
219 // CTextureAnimDlg::CGradientInterface implementation //
220 ////////////////////////////////////////////////////////
224 CEditAttribDlg
*CTextureAnimDlg::CGradientInterface::createDialog(uint index
, CValueGradientDlg
*grad
, CParticleWorkspace::CNode
*ownerNode
)
226 CTextureChooser
*tc
= new CTextureChooser(NULL
, ownerNode
);
227 _TextureWrapper
.P
= P
;
228 _TextureWrapper
.Dlg
= Dlg
;
229 _TextureWrapper
.Index
= index
;
230 _TextureWrapper
.OwnerNode
= ownerNode
;
231 tc
->setWrapper(&_TextureWrapper
);
234 void CTextureAnimDlg::CGradientInterface::modifyGradient(TAction action
, uint index
)
237 nlassert(P
->getTextureGroup());
238 std::vector
< NLMISC::CSmartPtr
<NL3D::ITexture
> > textureList
;
239 textureList
.resize(P
->getTextureGroup()->getNbTextures());
240 P
->getTextureGroup()->getTextures(&textureList
[0]);
244 case IValueGradientDlgClient::Add
:
246 // we duplicate the last texture, so that they have the same size
247 NLMISC::CSmartPtr
<NL3D::ITexture
> lastTex
= textureList
[textureList
.size() - 1];
248 textureList
.push_back(lastTex
);
251 case IValueGradientDlgClient::Insert
:
253 // we duplicate the current texture, so that they have the same size
254 NLMISC::CSmartPtr
<NL3D::ITexture
> tex
= textureList
[index
];
255 textureList
.insert(textureList
.begin() + index
, tex
);
258 case IValueGradientDlgClient::Delete
:
259 textureList
.erase(textureList
.begin() + index
);
263 P
->getTextureGroup()->setTextures(&textureList
[0], (uint
)textureList
.size());
265 void CTextureAnimDlg::CGradientInterface::displayValue(CDC
*dc
, uint index
, sint x
, sint y
)
267 const uint tSize
= 20;
268 NLMISC::CSmartPtr
<NL3D::ITexture
> tex
= P
->getTextureGroup()->getTexture(index
);
271 // make copy of the texture
272 NLMISC::CBitmap
cb(* ((NL3D::ITexture
*) tex
));
274 cb
.convertToType(NLMISC::CBitmap::RGBA
);
275 cb
.resample(tSize
, tSize
);
278 uint32
*dat
= (uint32
*) &(cb
.getPixels()[0]);
280 HBITMAP myBitmap
= ::CreateBitmap(tSize
, tSize
, 1, 32, dat
);
282 HDC bitmapDc
= ::CreateCompatibleDC(dc
->m_hDC
);
283 HGDIOBJ old
= ::SelectObject(bitmapDc
, myBitmap
);
285 // display the texture
286 ::BitBlt(dc
->m_hDC
, x
+ 20, y
+ 10, tSize
, tSize
, bitmapDc
, 0, 0, SRCCOPY
);
289 ::SelectObject(bitmapDc
, old
);
290 ::DeleteDC(bitmapDc
);
291 ::DeleteObject(myBitmap
);
294 uint32
CTextureAnimDlg::CGradientInterface::getSchemeSize(void) const
296 nlassert(P
->getTextureGroup());
297 return P
->getTextureGroup()->getNbTextures();
299 uint32
CTextureAnimDlg::CGradientInterface::getNbSteps(void) const
303 void CTextureAnimDlg::CGradientInterface::setNbSteps(uint32 value
)
305 // this should never be called, as we don't allow nbsteps to be called
310 ///////////////////////////////////////////////////////////////////////////
311 // CTextureAnimDlg::CGradientInterface::CTextureWrapper implementation //
312 ///////////////////////////////////////////////////////////////////////////
315 NL3D::ITexture
*CTextureAnimDlg::CGradientInterface::CTextureWrapper::get(void)
318 nlassert(P
->getTextureGroup());
319 return P
->getTextureGroup()->getTexture(Index
);
321 void CTextureAnimDlg::CGradientInterface::CTextureWrapper::set(NL3D::ITexture
*t
)
324 nlassert(P
->getTextureGroup());
326 // if a texture is added, it must have the same size than other textures
327 if (P
->getTextureGroup()->getNbTextures() > 1)
329 NLMISC::CSmartPtr
<NL3D::ITexture
> tex
= P
->getTextureGroup()->getTexture(0);
333 if (t
->getWidth() != tex
->getWidth() || t
->getHeight() != tex
->getHeight())
335 ::MessageBox(NULL
, _T("All textures must have the same size !"), _T("error"), MB_OK
);
339 if (t
->PixelFormat
!= tex
->PixelFormat
)
341 ::MessageBox(NULL
, _T("All textures must have the same pixel format !"), _T("error"), MB_OK
);
346 std::vector
< NLMISC::CSmartPtr
<NL3D::ITexture
> > textureList
;
347 textureList
.resize(P
->getTextureGroup()->getNbTextures());
348 P
->getTextureGroup()->getTextures(&textureList
[0]);
350 textureList
[Index
] = t
;
353 P
->getTextureGroup()->setTextures(&textureList
[0], (uint
)textureList
.size());
355 Dlg
->invalidateGrad();
358 void CTextureAnimDlg::OnMultiTex()
361 _MTP
->enableMultiTexture(m_MultiTexEnable
? true : false /* VC WARNING */);
363 updateModifiedFlag();
366 void CTextureAnimDlg::childPopupClosed(CWnd
*child
)
368 nlassert(_MultiTexDlg
== child
);
369 _MultiTexDlg
->DestroyWindow();
375 void CTextureAnimDlg::OnEditMultitex()
378 _MultiTexDlg
= new CMultiTexDlg(_Node
, _MTP
, this, this);
379 _MultiTexDlg
->init(this);