1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     demo_Models.cpp
4 
5   Copyright (C)2009-2012 Nintendo Co., Ltd.  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   $Rev: 46365 $
14  *---------------------------------------------------------------------------*/
15 
16 #include <nn/dbg.h>
17 #include <nn/assert.h>
18 
19 #include <cmath>
20 
21 #include "demo_Models.h"
22 
23 namespace demo {
24 
25 namespace {
GetBufferOffset(size_t size)26     inline u8* GetBufferOffset(size_t size)
27     {
28         return (u8*)NULL + size;
29     }
30 } // namespace (unnamed)
31 
32 /* ------------------------------------------------------------------------
33         ModelBase class (abstract class)
34    ------------------------------------------------------------------------ */
ModelBase()35 ModelBase::ModelBase() : m_AttributeFlag(0), m_IndexSize(0)
36 {
37     m_DataSize[0] = m_DataSize[1] = m_DataSize[2] = m_DataSize[3] = 0;
38     m_Initialized = false;
39 }
40 
FinalizeImpl()41 void ModelBase::FinalizeImpl()
42 {
43     if (!m_Initialized)
44     {
45         return;
46     }
47 
48     glDeleteBuffers(1, &m_ArrayBufferObjectId);
49     glDeleteBuffers(1, &m_ElementArrayBufferObjectId);
50     m_Initialized = false;
51 }
52 
Draw()53 void ModelBase::Draw()
54 {
55     if (!m_Initialized)
56     {
57         NN_PANIC("Model is not initialized.\n");
58     }
59 
60     glBindBuffer(GL_ARRAY_BUFFER, m_ArrayBufferObjectId);
61     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ElementArrayBufferObjectId);
62 
63     int attrNum = 0;
64     size_t offset = 0;
65 
66     if (m_AttributeFlag & ATTR_POSITION)
67     {
68         glVertexAttribPointer(attrNum, detail::ATTR_NUM_POS, GL_FLOAT, GL_FALSE, 0, 0);
69         ++attrNum;
70         offset += m_DataSize[attrNum-1];
71     }
72 
73     if (m_AttributeFlag & ATTR_NORMAL)
74     {
75         glVertexAttribPointer(attrNum, detail::ATTR_NUM_NORMAL, GL_FLOAT, GL_FALSE, 0, GetBufferOffset(offset));
76         ++attrNum;
77         offset += m_DataSize[attrNum-1];
78     }
79 
80     if (m_AttributeFlag & ATTR_VERTEX_COLOR)
81     {
82         glVertexAttribPointer(attrNum, detail::ATTR_NUM_COLOR, GL_FLOAT, GL_FALSE, 0, GetBufferOffset(offset));
83         ++attrNum;
84         offset += m_DataSize[attrNum-1];
85     }
86 
87     if (m_AttributeFlag & ATTR_TEX_COORDINATE)
88     {
89         glVertexAttribPointer(attrNum, detail::ATTR_NUM_TEX, GL_FLOAT, GL_FALSE, 0, GetBufferOffset(offset));
90         ++attrNum;
91     }
92 
93     for (int i=0; i<attrNum; ++i)
94     {
95         glEnableVertexAttribArray(i);
96     }
97 
98     glDrawElements(GL_TRIANGLES, m_IndexSize/sizeof(u16), GL_UNSIGNED_SHORT, 0);
99 
100     glBindBuffer(GL_ARRAY_BUFFER, 0);
101     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
102 
103     for (int j=0; j<attrNum; ++j)
104     {
105         glDisableVertexAttribArray(j);
106     }
107 }
108 
InitializeCore(u16 * indices,f32 * attr1,f32 * attr2,f32 * attr3,f32 * attr4)109 void ModelBase::InitializeCore(u16* indices, f32* attr1, f32* attr2, f32* attr3, f32* attr4)
110 {
111     if (indices == NULL || attr1 == NULL)
112     {
113         NN_PANIC("illegal input.\n");
114     }
115 
116     glGenBuffers(1, &m_ArrayBufferObjectId);
117     glBindBuffer(GL_ARRAY_BUFFER, m_ArrayBufferObjectId);
118     glBufferData(GL_ARRAY_BUFFER, m_DataSize[0] + m_DataSize[1] + m_DataSize[2] + m_DataSize[3], 0, GL_STATIC_DRAW);
119     glBufferSubData(GL_ARRAY_BUFFER, 0, m_DataSize[0], attr1);
120 
121     // If there are more than two vertex attributes, specify them in order
122     if ( attr2 != NULL )
123     {
124         glBufferSubData(GL_ARRAY_BUFFER, m_DataSize[0], m_DataSize[1], attr2);
125         if ( attr3 != NULL )
126         {
127             glBufferSubData(GL_ARRAY_BUFFER, m_DataSize[0] + m_DataSize[1], m_DataSize[2], attr3);
128             if ( attr4 != NULL )
129             {
130                 glBufferSubData(GL_ARRAY_BUFFER, m_DataSize[0] + m_DataSize[1] + m_DataSize[2], m_DataSize[3], attr4);
131             }
132         }
133     }
134 
135     glGenBuffers(1, &m_ElementArrayBufferObjectId);
136     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ElementArrayBufferObjectId);
137     glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_IndexSize, indices, GL_STATIC_DRAW);
138 
139     glBindBuffer(GL_ARRAY_BUFFER, 0);
140     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
141 
142     m_Initialized = true;
143 }
144 
145 /* ------------------------------------------------------------------------
146         Cube class
147    ------------------------------------------------------------------------ */
Initialize(u8 flag,f32 r,f32 g,f32 b,f32 alpha)148 void CubeModel::Initialize(u8 flag, f32 r, f32 g, f32 b, f32 alpha)
149 {
150     if (m_Initialized)
151     {
152         return;
153     }
154 
155     m_DataSize[0] = m_DataSize[1] = m_DataSize[2] = m_DataSize[3] = 0;
156     m_AttributeFlag = flag;
157 
158     // Define in counterclockwise order the vertices of the triangles that form the surfaces
159     f32 positions[] =
160     {
161          0.5f, -0.5f,  0.5f,   0.5f, -0.5f, -0.5f,   0.5f,  0.5f, -0.5f,   0.5f,  0.5f,  0.5f, // +X
162         -0.5f, -0.5f, -0.5f,  -0.5f, -0.5f,  0.5f,  -0.5f,  0.5f,  0.5f,  -0.5f,  0.5f, -0.5f, // -X
163         -0.5f,  0.5f,  0.5f,   0.5f,  0.5f,  0.5f,   0.5f,  0.5f, -0.5f,  -0.5f,  0.5f, -0.5f, // +Y
164         -0.5f, -0.5f, -0.5f,   0.5f, -0.5f, -0.5f,   0.5f, -0.5f,  0.5f,  -0.5f, -0.5f,  0.5f, // -Y
165         -0.5f, -0.5f,  0.5f,   0.5f, -0.5f,  0.5f,   0.5f,  0.5f,  0.5f,  -0.5f,  0.5f,  0.5f, // +Z
166          0.5f, -0.5f, -0.5f,  -0.5f, -0.5f, -0.5f,  -0.5f,  0.5f, -0.5f,   0.5f,  0.5f, -0.5f  // -Z
167     };
168 
169     f32 len = ::std::sqrt(0.5*0.5+0.5*0.5+0.5*0.5);
170 
171     f32 normals[] =
172     {
173          0.5f/len, -0.5f/len,  0.5f/len,   0.5f/len, -0.5f/len, -0.5f/len,   0.5f/len,  0.5f/len, -0.5f/len,   0.5f/len,  0.5f/len,  0.5f/len, // +X
174         -0.5f/len, -0.5f/len, -0.5f/len,  -0.5f/len, -0.5f/len,  0.5f/len,  -0.5f/len,  0.5f/len,  0.5f/len,  -0.5f/len,  0.5f/len, -0.5f/len, // -X
175         -0.5f/len,  0.5f/len,  0.5f/len,   0.5f/len,  0.5f/len,  0.5f/len,   0.5f/len,  0.5f/len, -0.5f/len,  -0.5f/len,  0.5f/len, -0.5f/len, // +Y
176         -0.5f/len, -0.5f/len, -0.5f/len,   0.5f/len, -0.5f/len, -0.5f/len,   0.5f/len, -0.5f/len,  0.5f/len,  -0.5f/len, -0.5f/len,  0.5f/len, // -Y
177         -0.5f/len, -0.5f/len,  0.5f/len,   0.5f/len, -0.5f/len,  0.5f/len,   0.5f/len,  0.5f/len,  0.5f/len,  -0.5f/len,  0.5f/len,  0.5f/len, // +Z
178          0.5f/len, -0.5f/len, -0.5f/len,  -0.5f/len, -0.5f/len, -0.5f/len,  -0.5f/len,  0.5f/len, -0.5f/len,   0.5f/len,  0.5f/len, -0.5f/len  // -Z
179     };
180 
181     f32 colors[] =
182     {
183         r, g, b, alpha,  r, g, b, alpha,  r, g, b, alpha,  r, g, b, alpha,
184         r, g, b, alpha,  r, g, b, alpha,  r, g, b, alpha,  r, g, b, alpha,
185         r, g, b, alpha,  r, g, b, alpha,  r, g, b, alpha,  r, g, b, alpha,
186         r, g, b, alpha,  r, g, b, alpha,  r, g, b, alpha,  r, g, b, alpha,
187         r, g, b, alpha,  r, g, b, alpha,  r, g, b, alpha,  r, g, b, alpha,
188         r, g, b, alpha,  r, g, b, alpha,  r, g, b, alpha,  r, g, b, alpha
189     };
190 
191     f32 texcoords[] =
192     {
193         0.0f, 0.0f,   1.0f, 0.0f,   1.0f, 1.0f,   0.0f, 1.0f,  // +X
194         0.0f, 0.0f,   1.0f, 0.0f,   1.0f, 1.0f,   0.0f, 1.0f,  // -X
195         0.0f, 0.0f,   1.0f, 0.0f,   1.0f, 1.0f,   0.0f, 1.0f,  // +Y
196         0.0f, 0.0f,   1.0f, 0.0f,   1.0f, 1.0f,   0.0f, 1.0f,  // -Y
197         0.0f, 0.0f,   1.0f, 0.0f,   1.0f, 1.0f,   0.0f, 1.0f,  // +Z
198         0.0f, 0.0f,   1.0f, 0.0f,   1.0f, 1.0f,   0.0f, 1.0f,  // -Z
199     };
200 
201     u16 indices[] =
202     {
203          0,  1,  2,  0,  2,  3,
204          4,  5,  6,  4,  6,  7,
205          8,  9, 10,  8, 10, 11,
206         12, 13, 14, 12, 14, 15,
207         16, 17, 18, 16, 18, 19,
208         20, 21, 22, 20, 22, 23
209     };
210     m_IndexSize = sizeof(indices);
211 
212     int attrNum = 0;
213     f32* attrBufPtr[4] = {NULL, NULL, NULL, NULL};
214     if (flag & ATTR_POSITION)
215     {
216         attrBufPtr[attrNum] = positions;
217         m_DataSize[attrNum] = sizeof(positions);
218         ++attrNum;
219     }
220 
221     if (flag & ATTR_NORMAL)
222     {
223         attrBufPtr[attrNum] = normals;
224         m_DataSize[attrNum] = sizeof(normals);
225         ++attrNum;
226     }
227 
228     if (flag & ATTR_VERTEX_COLOR)
229     {
230         attrBufPtr[attrNum] = colors;
231         m_DataSize[attrNum] = sizeof(colors);
232         ++attrNum;
233     }
234 
235     if (flag & ATTR_TEX_COORDINATE)
236     {
237         attrBufPtr[attrNum] = texcoords;
238         m_DataSize[attrNum] = sizeof(texcoords);
239         ++attrNum;
240     }
241 
242     InitializeCore(indices, attrBufPtr[0], attrBufPtr[1], attrBufPtr[2], attrBufPtr[3]);
243 }
244 
245 /* ------------------------------------------------------------------------
246    ------------------------------------------------------------------------ */
247 
248 }
249 
250