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