1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: lyt_Picture.cpp
4
5 Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Revision: 25594 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17
18 #include <nw/lyt/lyt_Common.h>
19 #include <nw/lyt/lyt_DrawInfo.h>
20 #include <nw/lyt/lyt_Layout.h>
21 #include <nw/lyt/lyt_Picture.h>
22 #include <nw/lyt/lyt_TexMap.h>
23 #include <nw/lyt/lyt_Material.h>
24 #include <nw/lyt/lyt_Animation.h>
25 #include <nw/lyt/lyt_ResourceAccessor.h>
26 #include <nw/lyt/lyt_Stopwatch.h>
27
28 using namespace nw::math;
29
30 namespace nw
31 {
32 namespace lyt
33 {
34
35 NW_UT_RUNTIME_TYPEINFO_DEFINITION(Picture, Picture::Base); // 実行時型情報の実体を定義
36
Picture(u8 texNum)37 Picture::Picture(u8 texNum)
38 {
39 NW_ASSERT(texNum <= TexMapMax);
40
41 Init(texNum);
42
43 // マテリアルの作成
44 m_pMaterial = Layout::NewObj<Material>();
45 if (m_pMaterial)
46 {
47 m_pMaterial->ReserveMem(texNum, texNum, texNum);
48 }
49 }
50
Picture(const TexMap & texMap)51 Picture::Picture(const TexMap& texMap)
52 {
53 const int texNum = 1;
54 Init(texNum);
55
56 // マテリアルの作成
57 m_pMaterial = Layout::NewObj<Material>();
58 if (m_pMaterial)
59 {
60 m_pMaterial->ReserveMem(texNum, texNum, texNum);
61 Append(texMap);
62 }
63 }
64
Picture(const res::Picture * pBlock,const ResBlockSet & resBlockSet)65 Picture::Picture(
66 const res::Picture* pBlock,
67 const ResBlockSet& resBlockSet
68 )
69 : Base(pBlock)
70 {
71 const u8 texCoordNum = ut::Min((int)pBlock->texCoordNum, TexMapMax);
72
73 Init(texCoordNum);
74
75 // 頂点カラー
76 for (int i = 0; i < VERTEXCOLOR_MAX; ++i)
77 {
78 m_VtxColors[i] = pBlock->vtxCols[i];
79 }
80
81 // テクスチャ座標
82 if (texCoordNum > 0)
83 {
84 if (! m_TexCoordAry.IsEmpty())
85 {
86 m_TexCoordAry.Copy(reinterpret_cast<const char*>(pBlock) + sizeof(*pBlock), texCoordNum);
87 }
88 }
89
90 // マテリアルの作成
91 {
92 NW_NULL_ASSERT(resBlockSet.pMaterialList);
93 const u32 *const matOffsTbl = internal::ConvertOffsToPtr<u32>(resBlockSet.pMaterialList, sizeof(*resBlockSet.pMaterialList));
94 const res::Material *const pResMaterial = internal::ConvertOffsToPtr<res::Material>(resBlockSet.pMaterialList, matOffsTbl[pBlock->materialIdx]);
95 m_pMaterial = Layout::NewObj<Material>(pResMaterial, resBlockSet);
96 }
97 }
98
99 void
Init(u8 texNum)100 Picture::Init(u8 texNum)
101 {
102 if (texNum > 0)
103 {
104 ReserveTexCoord(texNum);
105 }
106
107 #ifdef NW_LYT_DRAWER_ENABLE
108 m_IsTexCoordInited = false;
109 #endif
110
111 }
112
~Picture()113 Picture::~Picture()
114 {
115 // OSReport("Picture::~Picture()\n");
116
117 if (m_pMaterial && ! m_pMaterial->IsUserAllocated())
118 {
119 Layout::DeleteObj(m_pMaterial);
120 m_pMaterial = 0;
121 }
122
123 m_TexCoordAry.Free();
124 }
125
126 u8
GetMaterialNum() const127 Picture::GetMaterialNum() const
128 {
129 return m_pMaterial? 1 : 0;
130 }
131
132 Material*
GetMaterial(u32 idx) const133 Picture::GetMaterial(u32 idx) const
134 {
135 NW_WARNING(idx < GetMaterialNum(), "idx >= GetMaterialNum() : %d >= %d", idx, GetMaterialNum());
136
137 return idx == 0 ? m_pMaterial : 0;
138 }
139
SetMaterial(Material * pMaterial)140 void Picture::SetMaterial(Material* pMaterial)
141 {
142 if (m_pMaterial == pMaterial)
143 {
144 return;
145 }
146
147 if (m_pMaterial != NULL && !m_pMaterial->IsUserAllocated())
148 {
149 Layout::DeleteObj(m_pMaterial);
150 }
151
152 m_pMaterial = pMaterial;
153 if (pMaterial != NULL)
154 {
155 pMaterial->SetTextureDirty();
156 }
157 }
158
159 void
Append(const TexMap & texMap)160 Picture::Append(const TexMap& texMap)
161 {
162 if (m_pMaterial->GetTexMapNum() >= m_pMaterial->GetTexMapCap() || m_pMaterial->GetTexCoordGenNum() >= m_pMaterial->GetTexCoordGenCap())
163 {
164 NW_WARNING(false, "m_pMaterial->GetTexMapNum(%d) is large. m_pMaterial->GetTexMapCap(%d), m_pMaterial->GetTexCoordGenCap(%d)\n", m_pMaterial->GetTexMapNum(), m_pMaterial->GetTexMapCap(), m_pMaterial->GetTexCoordGenCap());
165 return;
166 }
167
168 const u8 texIdx = m_pMaterial->GetTexMapNum();
169 m_pMaterial->SetTexMapNum(u8(texIdx + 1));
170 m_pMaterial->SetTexMap(texIdx, texMap);
171
172 m_pMaterial->SetTexCoordGenNum(m_pMaterial->GetTexMapNum());
173 m_pMaterial->SetTexCoordGen(texIdx, TexCoordGen());
174
175 SetTexCoordNum(m_pMaterial->GetTexMapNum());
176
177 // サイズが設定されていないときは、サイズを設定する。
178 if (GetSize() == Size(0.f, 0.f) && m_pMaterial->GetTexMapNum() == 1)
179 {
180 const TexSize& texSize = m_pMaterial->GetTexMap(0).GetSize();
181 SetSize(Size(texSize.width, texSize.height));
182 }
183 }
184
185 void
ReserveTexCoord(u8 num)186 Picture::ReserveTexCoord(u8 num)
187 {
188 // TODO:
189 // * Cap値を取得する方法がない。
190 // * 広げることはできるがちじめることができない。
191 m_TexCoordAry.Reserve(num);
192 }
193
194 u8
GetTexCoordNum() const195 Picture::GetTexCoordNum() const
196 {
197 return m_TexCoordAry.GetSize();
198 }
199
200 void
SetTexCoordNum(u8 num)201 Picture::SetTexCoordNum(u8 num)
202 {
203 m_TexCoordAry.SetSize(num);
204 }
205
206 void
GetTexCoord(u32 idx,TexCoordQuad coords) const207 Picture::GetTexCoord(
208 u32 idx,
209 TexCoordQuad coords
210 ) const
211 {
212 return m_TexCoordAry.GetCoord(idx, coords);
213 }
214
215 void
SetTexCoord(u32 idx,const TexCoordQuad coords)216 Picture::SetTexCoord(
217 u32 idx,
218 const TexCoordQuad coords
219 )
220 {
221 m_TexCoordAry.SetCoord(idx, coords);
222
223 if (m_pMaterial != NULL)
224 {
225 m_pMaterial->SetTextureDirty();
226 }
227 }
228
229 const ut::Color8
GetVtxColor(u32 idx) const230 Picture::GetVtxColor(u32 idx) const
231 {
232 NW_ASSERT(idx < VERTEXCOLOR_MAX);
233
234 return m_VtxColors[idx];
235 }
236
237 void
SetVtxColor(u32 idx,ut::Color8 value)238 Picture::SetVtxColor(
239 u32 idx,
240 ut::Color8 value
241 )
242 {
243 NW_ASSERT(idx < VERTEXCOLOR_MAX);
244
245 m_VtxColors[idx] = value;
246 }
247
248 u8
GetVtxColorElement(u32 idx) const249 Picture::GetVtxColorElement(u32 idx) const
250 {
251 return internal::GetVtxColorElement(m_VtxColors, idx);
252 }
253
254 void
SetVtxColorElement(u32 idx,u8 value)255 Picture::SetVtxColorElement(u32 idx, u8 value)
256 {
257 internal::SetVtxColorElement(m_VtxColors, idx, value);
258 }
259
260 #ifdef NW_LYT_DMPGL_ENABLED
261 void
DrawSelf(const DrawInfo & drawInfo)262 Picture::DrawSelf(const DrawInfo& drawInfo)
263 {
264 NW_LYT_STOPWATCH_MEASURE(-300, "nw::lyt::Picture::DrawSelf");
265
266 if (! m_pMaterial)
267 {
268 return;
269 }
270
271 LoadMtx(drawInfo); // 行列
272
273 NW_GL_ASSERT();
274
275 m_pMaterial->SetupGraphics(drawInfo, GetGlobalAlpha());
276
277 NW_GL_ASSERT();
278
279 internal::DrawQuad(
280 drawInfo,
281 GetVtxPos(),
282 GetSize(),
283 m_TexCoordAry.GetSize(),
284 m_TexCoordAry.GetArray(),
285 m_VtxColors);
286
287 NW_GL_ASSERT();
288 }
289 #endif
290
291 } // namespace nw::lyt
292 } // namespace nw
293