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