1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     gx_TextureCombiner.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: 47228 $
14  *---------------------------------------------------------------------------*/
15 
16 #include <nn.h>
17 #include <nn/gx.h>
18 #include <nn/math.h>
19 #include <nn/fs.h>
20 #include <nn/fnd.h>
21 #include <nn/applet.h>
22 
23 #include "demo.h"
24 
25 namespace {
26 
27 /* Enumerated type */
28 typedef enum CombinerMode {
29     COMB_MODE_ADD = 0,
30     COMB_MODE_SUBTRACT,
31     COMB_MODE_MULT,
32     COMB_MODE_ADDMULT,
33     COMB_MODE_DECAL,
34     COMB_MODE_DECAL2,
35     COMB_MODE_BLEND,
36     COMB_MODE_TWOCOLOR_INTERPOLATE,
37 
38     COMB_MODE_NUM
39 } CombinerMode;
40 
41 static char *g_CombinerModeName[] =
42 {
43     "ADD",
44     "SUBTRACT",
45     "MULTIPLY",
46     "ADD AND MULTIPLY",
47     "DECAL",
48     "DECAL2",
49     "BLENDING",
50     "INTERPOLATE BY TWO COLORS"
51 };
52 
53 /* buffer id */
54 GLuint s_ArrayBufferID;
55 GLuint s_ElementArrayBufferID;
56 
57 /* program id */
58 GLuint s_ProgramID;
59 
60 /* shader id */
61 GLuint s_ShaderID;
62 
63 /* Texture */
64 GLuint s_Texture[2];
65 GLuint s_TextureGray;
66 GLuint s_TextureAlpha;
67 
68 /* Other variables */
69 int s_Count = 1;
70 int s_Mode = COMB_MODE_ADD;
71 
72 GLfloat s_Intensity[4] = {0.0f, 0.0f, 0.0f, 0.0f};
73 
74 nn::fnd::ExpHeap s_AppHeap;
75 uptr s_AddrForGxHeap;
76 const u32 s_GxHeapSize = 0x400000;
77 
78 demo::RenderSystemDrawing s_RenderSystem;
79 
80 } // Namespace
81 
82 // TODO: We will change this at some point so that it loads from a binary file.
83 extern u8 g_TexBitmapUpper[];
84 extern u8 g_TexBitmapLower[];
85 extern u8 g_TexAlpha[];
86 extern u8 g_TexGray[];
87 
88 /* Functions */
89 void LoadObjects(void);
90 void ReadyObjects(void);
91 void DrawDisplay0(void);
92 void DrawDisplay1(void);
93 void SetTextureCombiner(void);
94 void DrawFrame(void);
95 int Initialize(void);
96 
97 /* generate simple object */
LoadObjects(void)98 void LoadObjects(void)
99 {
100     GLfloat coords[] = {
101         -0.5f, 0.5f, 0.f, 1.f,
102         -0.5f,-0.5f, 0.f, 1.f,
103          0.5f, 0.5f, 0.f, 1.f,
104          0.5f,-0.5f, 0.f, 1.f
105     };
106     GLfloat texcoords[] = {
107         0.f, 1.f, 0.f,
108         0.f, 0.f, 0.f,
109         1.f, 1.f, 0.f,
110         1.f, 0.f, 0.f,
111     };
112 
113     GLushort idxs[] = {0, 1, 2, 3};
114 
115     glGenBuffers(1, &s_ArrayBufferID);
116     glBindBuffer(GL_ARRAY_BUFFER, s_ArrayBufferID);
117     glBufferData(GL_ARRAY_BUFFER, sizeof(coords) + sizeof(texcoords), 0, GL_STATIC_DRAW);
118     glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(coords), coords);
119     glBufferSubData(GL_ARRAY_BUFFER, sizeof(coords), sizeof(texcoords), texcoords);
120 
121     glGenBuffers(1, &s_ElementArrayBufferID);
122     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_ElementArrayBufferID);
123     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(idxs), idxs, GL_STATIC_DRAW);
124 
125     glEnableVertexAttribArray(0);
126     glEnableVertexAttribArray(1);
127 
128     glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0) ;
129     glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)sizeof(coords));
130 }
131 
ReadyObjects(void)132 void ReadyObjects(void)
133 {
134     glUseProgram(s_ProgramID);
135     glBindBuffer(GL_ARRAY_BUFFER, s_ArrayBufferID);
136     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_ElementArrayBufferID);
137 
138     glEnableVertexAttribArray(0);
139     glEnableVertexAttribArray(1);
140 
141     glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
142     glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(16*sizeof(GLfloat)));
143 }
144 
DrawDisplay0(void)145 void DrawDisplay0(void)
146 {
147     s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
148     s_RenderSystem.Clear();
149 
150     ReadyObjects();
151 
152     // Texture combiner settings
153     glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_Texture[0].samplerType"), GL_TEXTURE_2D);
154     glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_Texture[1].samplerType"), GL_TEXTURE_2D);
155 
156     if (s_Mode == COMB_MODE_TWOCOLOR_INTERPOLATE)
157     {
158         glActiveTexture(GL_TEXTURE0);
159         glBindTexture(GL_TEXTURE_2D, s_TextureGray);
160         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
161         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
162         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
163         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
164     }
165     else if (s_Mode == COMB_MODE_ADDMULT || s_Mode == COMB_MODE_DECAL)
166     {
167         glActiveTexture(GL_TEXTURE0);
168         glBindTexture(GL_TEXTURE_2D, s_Texture[0]);
169         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
170         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
171         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
172         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
173 
174         glActiveTexture(GL_TEXTURE1);
175         glBindTexture(GL_TEXTURE_2D, s_TextureAlpha);
176         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
177         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
178         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
179         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
180     }
181     else
182     {
183         glActiveTexture(GL_TEXTURE0);
184         glBindTexture(GL_TEXTURE_2D, s_Texture[0]);
185         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
186         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
187         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
188         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
189 
190         glActiveTexture(GL_TEXTURE1);
191         glBindTexture(GL_TEXTURE_2D, s_Texture[1]);
192         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
193         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
194         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
195         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
196     }
197     SetTextureCombiner();
198 
199     nn::math::Matrix44 proj;
200 
201     nn::math::MTX44Frustum(&proj, -0.02f, 0.02f, -0.02f* static_cast<f32>(nn::gx::DISPLAY0_HEIGHT) / static_cast<f32>(nn::gx::DISPLAY0_WIDTH),
202                  0.02f* static_cast<f32>(nn::gx::DISPLAY0_HEIGHT) / static_cast<f32>(nn::gx::DISPLAY0_WIDTH), 0.2f, 10.f);
203     glUniformMatrix4fv(glGetUniformLocation(s_ProgramID, "uProjection"), 1, GL_TRUE, static_cast<f32*>(proj));
204 
205     nn::math::Matrix34 eye;
206     nn::math::Vector3 camPos(0.f, 0.f, 5.5f);
207     nn::math::Vector3 camUp(0.f, 1.f, 0.f);
208     nn::math::Vector3 target(0.f, 0.f, 0.f);
209 
210     nn::math::MTX34LookAt(&eye, &camPos, &camUp, &target);
211     nn::math::Matrix44 mv(eye);
212     glUniformMatrix4fv(glGetUniformLocation(s_ProgramID, "uModelView"), 1, GL_TRUE, static_cast<f32*>(mv));
213 
214     glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0);
215 
216     s_RenderSystem.SwapBuffers();
217 }
218 
DrawDisplay1(void)219 void DrawDisplay1(void)
220 {
221     s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
222     s_RenderSystem.Clear();
223 
224     s_RenderSystem.SetColor(1.0f, 1.0f, 1.0f);
225     s_RenderSystem.DrawText(0.0f, 0.0f, "Count: %d", s_Count);
226     s_RenderSystem.DrawText(0.0f, 8.0f, "MODE: %s", g_CombinerModeName[s_Mode]);
227 
228     s_RenderSystem.SwapBuffers();
229 }
230 
SetTextureCombiner(void)231 void SetTextureCombiner(void)
232 {
233     switch(s_Mode)
234     {
235     case COMB_MODE_ADD:
236         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_TEXTURE0, GL_TEXTURE1, GL_PREVIOUS);
237         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_TEXTURE0, GL_PREVIOUS, GL_PREVIOUS);
238         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
239         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
240         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_ADD);
241         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_REPLACE);
242         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f);
243         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f);
244         break;
245     case COMB_MODE_SUBTRACT:
246         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_TEXTURE0, GL_TEXTURE1, GL_PREVIOUS);
247         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_TEXTURE0, GL_PREVIOUS, GL_PREVIOUS);
248         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
249         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
250         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_SUBTRACT);
251         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_REPLACE);
252         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f);
253         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f);
254         break;
255     case COMB_MODE_MULT:
256         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_TEXTURE0, GL_TEXTURE1, GL_PREVIOUS);
257         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_TEXTURE0, GL_PREVIOUS, GL_PREVIOUS);
258         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
259         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
260         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_MODULATE);
261         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_REPLACE);
262         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f);
263         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f);
264         break;
265     case COMB_MODE_ADDMULT: // Requires texture data with an alpha component.
266         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcRgb"), GL_TEXTURE1, GL_TEXTURE1, GL_TEXTURE0);
267         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcAlpha"), GL_TEXTURE0, GL_CONSTANT, GL_CONSTANT);
268         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_ALPHA, GL_SRC_COLOR);
269         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
270         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineRgb"), GL_MULT_ADD_DMP);
271         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineAlpha"), GL_REPLACE);
272         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].scaleRgb"), 1.0f);
273         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].scaleAlpha"), 1.0f);
274 
275         // Make sure to initialize the following texture combiner
276         glUniform4f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].constRgba"), 0.0f, 0.0f, 0.0f, 0.0f);
277         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].srcRgb"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS);
278         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].srcAlpha"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS);
279         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
280         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
281         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].combineRgb"), GL_REPLACE);
282         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].combineAlpha"), GL_REPLACE);
283         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].scaleRgb"), 1.0f);
284         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].scaleAlpha"), 1.0f);
285 
286         glUniform4f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].constRgba"), 0.0f, 0.0f, 0.0f, 0.0f);
287         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS);
288         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS);
289         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
290         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
291         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_REPLACE);
292         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_REPLACE);
293         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f);
294         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f);
295         break;
296     case COMB_MODE_DECAL: // Requires texture data with an alpha component.
297         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcRgb"), GL_TEXTURE1, GL_TEXTURE0, GL_TEXTURE1);
298         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].srcAlpha"), GL_TEXTURE0, GL_CONSTANT, GL_CONSTANT);
299         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA);
300         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
301         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineRgb"), GL_INTERPOLATE);
302         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].combineAlpha"), GL_REPLACE);
303         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].scaleRgb"), 1.0f);
304         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[0].scaleAlpha"), 1.0f);
305 
306         // Make sure to initialize the following texture combiner
307         glUniform4f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].constRgba"), 0.0f, 0.0f, 0.0f, 0.0f);
308         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].srcRgb"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS);
309         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].srcAlpha"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS);
310         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
311         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
312         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].combineRgb"), GL_REPLACE);
313         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].combineAlpha"), GL_REPLACE);
314         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].scaleRgb"), 1.0f);
315         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].scaleAlpha"), 1.0f);
316 
317         glUniform4f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].constRgba"), 0.0f, 0.0f, 0.0f, 0.0f);
318         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS);
319         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_PREVIOUS, GL_PREVIOUS, GL_PREVIOUS);
320         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
321         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
322         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_REPLACE);
323         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_REPLACE);
324         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f);
325         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f);
326         break;
327     case COMB_MODE_DECAL2:
328         glUniform4fv(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].constRgba"), 1, s_Intensity);
329         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].srcRgb"), GL_TEXTURE1, GL_CONSTANT, GL_PREVIOUS);
330         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].operandRgb"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_COLOR);
331         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].combineRgb"), GL_MODULATE);
332         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].scaleRgb"), 1.0f);
333 
334         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_TEXTURE1, GL_TEXTURE0, GL_PREVIOUS);
335         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_TEXTURE0, GL_PREVIOUS, GL_PREVIOUS);
336         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
337         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
338         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_INTERPOLATE);
339         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_REPLACE);
340         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f);
341         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f);
342         break;
343     case COMB_MODE_BLEND:
344         glUniform4f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].constRgba"), 0.7f, 0.7f, 0.7f, 0.7f);
345         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_TEXTURE0, GL_TEXTURE1, GL_CONSTANT);
346         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_TEXTURE0, GL_TEXTURE1, GL_CONSTANT);
347         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
348         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
349         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_INTERPOLATE);
350         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_INTERPOLATE);
351         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f);
352         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f);
353         break;
354     case COMB_MODE_TWOCOLOR_INTERPOLATE: // Requires gray scale texture
355         glUniform4f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].constRgba"), 1.0f, 1.0f, 0.0f, 1.0f);
356         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].srcRgb"), GL_CONSTANT, GL_TEXTURE0, GL_PREVIOUS);
357         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].operandRgb"), GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR);
358         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].combineRgb"), GL_MODULATE);
359         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[1].scaleRgb"), 1.0f);
360 
361         glUniform4f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].constRgba"), 0.0f, 0.0f, 1.0f, 1.0f);
362         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcRgb"), GL_CONSTANT, GL_TEXTURE0, GL_PREVIOUS);
363         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].srcAlpha"), GL_TEXTURE0, GL_PREVIOUS, GL_PREVIOUS);
364         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandRgb"), GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_COLOR);
365         glUniform3i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].operandAlpha"), GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA);
366         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineRgb"), GL_MULT_ADD_DMP);
367         glUniform1i(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].combineAlpha"), GL_REPLACE);
368         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleRgb"), 1.0f);
369         glUniform1f(glGetUniformLocation(s_ProgramID, "dmp_TexEnv[2].scaleAlpha"), 1.0f);
370         break;
371     default:
372         break;
373     }
374 }
375 
DrawFrame(void)376 void DrawFrame(void)
377 {
378     DrawDisplay0();
379     DrawDisplay1();
380 
381     s_Count++;
382     // Switches texture combiner setting using s_Count value
383     if (s_Count % 100 == 0)
384     {
385         s_Mode++;
386         if (s_Mode >= COMB_MODE_NUM)
387         {
388             s_Mode = COMB_MODE_ADD;
389         }
390     }
391 
392     if (s_Mode == COMB_MODE_DECAL2)
393     {
394         if (s_Count % 10 == 0)
395         {
396             for (int i=0; i<4; i++)
397             {
398                 s_Intensity[i] += 0.1f;
399                 if (s_Intensity[i] > 1.0f)
400                 {
401                     s_Intensity[i] = 0.0f;
402                 }
403             }
404         }
405     }
406 
407     s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH);
408 }
409 
410 /* initialization */
Initialize(void)411 int Initialize(void)
412 {
413     // fs initialization
414     nn::fs::Initialize();
415 
416     const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
417     static char buffer[ROMFS_BUFFER_SIZE];
418     NN_UTIL_PANIC_IF_FAILED(
419         nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE));
420 
421     /* Initialize display */
422     s_AppHeap.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize() );
423     s_AddrForGxHeap = reinterpret_cast<uptr>(s_AppHeap.Allocate(s_GxHeapSize));
424     s_RenderSystem.Initialize(s_AddrForGxHeap, s_GxHeapSize);
425 
426     s_ProgramID = glCreateProgram();
427     s_ShaderID = glCreateShader(GL_VERTEX_SHADER);
428 
429     nn::fs::FileReader file(L"rom:/shader.shbin");
430     size_t fileSize = file.GetSize();
431     void* buf = s_AppHeap.Allocate(fileSize);
432 
433     s32 read = file.Read(buf, fileSize);
434     glShaderBinary(1, &s_ShaderID, GL_PLATFORM_BINARY_DMP, buf, read);
435     file.Finalize();
436     s_AppHeap.Free(buf);
437 
438     glAttachShader(s_ProgramID, s_ShaderID);
439     glAttachShader(s_ProgramID, GL_DMP_FRAGMENT_SHADER_DMP);
440 
441     glBindAttribLocation(s_ProgramID, 0, "aPosition");
442     glBindAttribLocation(s_ProgramID, 1, "aTexCoord");
443 
444     glLinkProgram(s_ProgramID);
445     glValidateProgram(s_ProgramID);
446     glUseProgram(s_ProgramID);
447 
448     // Load Texture
449     glGenTextures(2, s_Texture);
450     glGenTextures(1, &s_TextureGray);
451     glGenTextures(1, &s_TextureAlpha);
452 
453     // TODO: Native texture formats supported
454     glBindTexture(GL_TEXTURE_2D, s_Texture[0]);
455     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, g_TexBitmapUpper);
456 
457     glBindTexture(GL_TEXTURE_2D, s_Texture[1]);
458     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, g_TexBitmapLower);
459 
460     glBindTexture(GL_TEXTURE_2D, s_TextureGray);
461     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 32, 32, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, g_TexGray);
462 
463     glBindTexture(GL_TEXTURE_2D, s_TextureAlpha);
464     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, g_TexAlpha);
465 
466     glBindTexture(GL_TEXTURE_2D, 0);
467 
468     s_RenderSystem.SetClearColor(NN_GX_DISPLAY0, 0.36f, 0.42f, 0.5f, 1.0f);
469     s_RenderSystem.SetClearColor(NN_GX_DISPLAY1, 0.36f, 0.42f, 0.5f, 1.0f);
470 
471     glClearDepthf(1.f);
472 
473     glEnable(GL_CULL_FACE);
474     glFrontFace(GL_CCW);
475     glCullFace(GL_BACK);
476 
477     LoadObjects();
478 
479     return 0;
480 }
481 
nnMain(void)482 void nnMain(void)
483 {
484     // Call only nn::applet::Enable to also allow execution from the HOME Menu
485     // HOME Menu transitions, POWER Button presses, and sleep are all unsupported
486     nn::applet::Enable();
487 
488     /* initialization */
489     if (Initialize() >= 0)
490     {
491         /* Enter loop */
492         while (1)
493         {
494             DrawFrame();
495         }
496     }
497 
498     /* shutdown_display */
499     s_RenderSystem.Finalize();
500     s_AppHeap.Free(reinterpret_cast<void*>(s_AddrForGxHeap));
501     s_AppHeap.Finalize();
502 }
503