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