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