1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     ClipEquation.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 /*
17  *------------------------------------------------------------
18  * Copyright(c) 2009-2010 by Digital Media Professionals Inc.
19  * All rights reserved.
20  *------------------------------------------------------------
21  * This source code is the confidential and proprietary
22  * of Digital Media Professionals Inc.
23  *------------------------------------------------------------
24  */
25 
26 /*
27  * Comments
28  * --------
29  *
30  * User clipping plane (fragment).
31  * This sample displays a cube with lower left vertex (-10,-10,-10) and upper right at (10,10,10)
32  * The clipping plane is enabled and rotates around the z axis
33  * The clipping plane is defined by the equation -1.x + 0.y + 0.z + 5 = 0
34  */
35 
36 #include <nn/gx.h>
37 #include <nn/math.h>
38 #include <nn/fs.h>
39 #include <nn/os.h>
40 #include <nn/init.h>
41 #include <nn/applet.h>
42 #include <nn/fnd/fnd_ExpHeap.h>
43 
44 #include "demo.h"
45 
46 /* program id */
47 GLuint s_PgID;
48 
49 /* shader id */
50 GLuint s_ShID;
51 
52 GLuint s_QuadindexID;
53 GLuint s_QuadvertID;
54 GLuint s_QuadcolID;
55 
56 /* ExpHeap for app. */
57 nn::fnd::ExpHeap s_AppHeap;
58 uptr s_HeapForGx;
59 const u32 s_GxHeapSize = 0x400000;
60 
61 demo::RenderSystem s_RenderSystem;
62 
63 /* load objects */
LoadObjects(void)64 static void LoadObjects(void)
65 {
66     const float vertex[24] =
67     {
68         -10.0f, -10.0f, -10.0f,
69         -10.0f,  10.0f, -10.0f,
70          10.0f,  10.0f, -10.0f,
71          10.0f, -10.0f, -10.0f,
72         -10.0f, -10.0f, 10.0f,
73         -10.0f,  10.0f, 10.0f,
74          10.0f,  10.0f, 10.0f,
75          10.0f, -10.0f, 10.0f
76     };
77 
78     const float color[32] =
79     {
80         1.0f, 0.0f, 0.0f, 1.0f,
81         0.0f, 1.0f, 0.0f, 1.0f,
82         0.0f, 0.0f, 1.0f, 1.0f,
83         1.0f, 1.0f, 1.0f, 1.0f,
84         1.0f, 0.0f, 0.0f, 1.0f,
85         0.0f, 1.0f, 0.0f, 1.0f,
86         0.0f, 0.0f, 1.0f, 1.0f,
87         1.0f, 1.0f, 1.0f, 1.0f
88     };
89 
90     const GLushort s_QuadIndex[36] =
91     {
92         0, 1, 2,    /* back face 1 */
93         0, 2, 3,    /* back face 2 */
94         4, 5, 6,    /* front face 1 */
95         4, 6, 7,    /* front face 2 */
96         4, 0, 3,    /* bottom face 1 */
97         4, 3, 7,    /* bottom face 2 */
98         5, 1, 2,    /* top face 1 */
99         5, 2, 6,    /* top face 2 */
100         4, 5, 1,    /* left face 1 */
101         4, 1, 0,    /* left face 2 */
102         7, 6, 2,    /* right face 1 */
103         7, 2, 3,    /* right face 2 */
104     };
105 
106     glGenBuffers(1, &s_QuadindexID) ;
107     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_QuadindexID);
108     glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36 * sizeof(GLushort), &s_QuadIndex, GL_STATIC_DRAW);
109 
110     glGenBuffers(1, &s_QuadvertID);
111     glBindBuffer(GL_ARRAY_BUFFER, s_QuadvertID);
112     glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), &vertex, GL_STATIC_DRAW);
113 
114     glGenBuffers(1, &s_QuadcolID);
115     glBindBuffer(GL_ARRAY_BUFFER, s_QuadcolID);
116     glBufferData(GL_ARRAY_BUFFER, 32 * sizeof(GLfloat), &color, GL_STATIC_DRAW);
117 }
118 
DrawFrame(void)119 int DrawFrame(void)
120 {
121     static int f = 0;
122 
123     s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
124     s_RenderSystem.Clear();
125 
126     /* simple disable culling to see properly clipped and non clipped faces clipped by clipping plane */
127     glDisable(GL_CULL_FACE);
128 
129     nn::math::Matrix44 proj;
130     nn::math::MTX44Perspective(&proj, 50.0f, static_cast<f32>(nn::gx::DISPLAY0_WIDTH) / static_cast<f32>(nn::gx::DISPLAY0_HEIGHT), 1.0f, 2000.0f);
131     glUniformMatrix4fv(glGetUniformLocation(s_PgID, "uProjection"), 1, GL_TRUE, static_cast<f32*>(proj));
132 
133     nn::math::Matrix34 eye;
134     nn::math::Vector3 camPos(0.0f, 0.0f, 50.0f);
135     nn::math::Vector3 camUp(0.0f, 1.0f, 0.0f);
136     nn::math::Vector3 target(0.0f, 0.0f, 0.0f);
137 
138     nn::math::MTX34Identity(&eye);
139     nn::math::MTX34LookAt(&eye, &camPos, &camUp, &target);
140     nn::math::Matrix44 mv(eye);
141     glUniformMatrix4fv(glGetUniformLocation(s_PgID, "uModelView"), 1, GL_TRUE, static_cast<f32*>(mv));
142 
143     /* rotation of the clipping plane */
144     nn::math::Matrix34 rot;
145     nn::math::MTX34RotXYZDeg(&rot, 0.f, 0.f, static_cast<f32>(f));
146     nn::math::MTX34Mult(&eye, &eye, &rot);
147 
148     nn::math::Vector4  eq(1.0f, 0.0f, 0.0f, -5.0f);
149     nn::math::Matrix44 mmp(proj);
150 
151     nn::math::Matrix44 eye44(eye);
152     nn::math::MTX44Mult(&mmp, &mmp, &eye44);
153     nn::math::MTX44Inverse(&mmp, &mmp);
154     nn::math::MTX44Transpose(&mmp, &mmp);
155 
156     nn::math::Vector4 mmpVec0(mmp.m[0][0], mmp.m[0][1], mmp.m[0][2], mmp.m[0][3]);
157     nn::math::Vector4 mmpVec1(mmp.m[1][0], mmp.m[1][1], mmp.m[1][2], mmp.m[1][3]);
158     nn::math::Vector4 mmpVec2(mmp.m[2][0], mmp.m[2][1], mmp.m[2][2], mmp.m[2][3]);
159     nn::math::Vector4 mmpVec3(mmp.m[3][0], mmp.m[3][1], mmp.m[3][2], mmp.m[3][3]);
160     nn::math::Vector4 p = nn::math::Vector4( nn::math::VEC4Dot(&mmpVec0, &eq), nn::math::VEC4Dot(&mmpVec1, &eq), nn::math::VEC4Dot(&mmpVec2, &eq), nn::math::VEC4Dot(&mmpVec3, &eq) );
161 
162     glUniform4fv(glGetUniformLocation(s_PgID, "dmp_FragOperation.clippingPlane"), 1, static_cast<f32*>(p));
163     glUniform1i(glGetUniformLocation(s_PgID, "dmp_FragOperation.enableClippingPlane"), GL_TRUE);
164 
165     glBindBuffer(GL_ARRAY_BUFFER, s_QuadvertID);
166     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
167 
168     glBindBuffer(GL_ARRAY_BUFFER, s_QuadcolID);
169     glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
170 
171     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_QuadindexID);
172     glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0);
173 
174     s_RenderSystem.SwapBuffers();
175 
176     s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
177     s_RenderSystem.Clear();
178     s_RenderSystem.SwapBuffers();
179 
180     s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH);
181 
182     f++;
183 
184     return !glGetError();
185 }
186 
187 /* initialization */
Initialize(void)188 static int Initialize(void)
189 {
190     // fs initialization
191     nn::fs::Initialize();
192 
193     const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
194     static char buffer[ROMFS_BUFFER_SIZE];
195     NN_UTIL_PANIC_IF_FAILED(
196         nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE));
197 
198     s_AppHeap.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize() );
199     s_HeapForGx = reinterpret_cast<uptr>(s_AppHeap.Allocate(s_GxHeapSize));
200     /* Initialize display */
201     s_RenderSystem.Initialize(s_HeapForGx, s_GxHeapSize);
202 
203     glClearColor(0.2f, 0.4f, 0.6f, 1.0f);
204     glClearDepthf(1.f);
205 
206     glViewport(0, 0, nn::gx::DISPLAY0_WIDTH, nn::gx::DISPLAY0_HEIGHT);
207 
208     glEnable(GL_DEPTH_TEST);
209     glDepthFunc(GL_LESS);
210 
211     glEnable(GL_CULL_FACE);
212     glFrontFace(GL_CCW);
213     glCullFace(GL_BACK);
214 
215     /* create program and load & attach vertex shader */
216     s_PgID = glCreateProgram();
217     s_ShID = glCreateShader(GL_VERTEX_SHADER);
218 
219     nn::fs::FileReader file(L"rom:/shader.shbin");
220     size_t fileSize = file.GetSize();
221     void* buf = s_AppHeap.Allocate(fileSize);
222 
223     s32 read = file.Read(buf, fileSize);
224     glShaderBinary(1, &s_ShID, GL_PLATFORM_BINARY_DMP, buf, read);
225     file.Finalize();
226     s_AppHeap.Free(buf);
227 
228     glAttachShader(s_PgID, s_ShID);
229 
230     /* attach fixed-function fragment shader */
231     glAttachShader(s_PgID, GL_DMP_FRAGMENT_SHADER_DMP);
232 
233     glBindAttribLocation(s_PgID, 0, "aPosition");
234     glBindAttribLocation(s_PgID, 1, "aColor");
235 
236     glLinkProgram(s_PgID);
237     glValidateProgram(s_PgID);
238     /* set program as current one to enable setting its uniforms */
239     glUseProgram(s_PgID);
240 
241     LoadObjects();
242 
243     glEnableVertexAttribArray(0);
244     glEnableVertexAttribArray(1);
245 
246     glUniform3i(glGetUniformLocation(s_PgID, "dmp_TexEnv[0].srcRgb"), GL_PRIMARY_COLOR, GL_PRIMARY_COLOR, GL_PRIMARY_COLOR);
247     glUniform3i(glGetUniformLocation(s_PgID, "dmp_TexEnv[0].srcAlpha"), GL_PRIMARY_COLOR, GL_PRIMARY_COLOR, GL_PRIMARY_COLOR);
248 
249     return 0;
250 }
251 
nnMain(void)252 void nnMain(void)
253 {
254     // Call only nn::applet::Enable to also allow execution from the HOME Menu
255     // HOME Menu transitions, POWER Button presses, and sleep are all unsupported
256     nn::applet::Enable();
257 
258     /* initialization */
259     if (Initialize() >= 0)
260     {
261         /* Enter loop */
262         while (1)
263         {
264             DrawFrame();
265         }
266     }
267     /* shutdown_display */
268     s_RenderSystem.Finalize();
269     s_AppHeap.Free(reinterpret_cast<void*>(s_HeapForGx));
270     s_AppHeap.Finalize();
271 }
272 
273