| OLD | NEW |
| (Empty) |
| 1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 * Use of this source code is governed by a BSD-style license that can be | |
| 3 * found in the LICENSE file. | |
| 4 */ | |
| 5 | |
| 6 /** @file hello_world_gles.cc | |
| 7 * This example demonstrates loading and running a simple 3D openGL ES 2.0 | |
| 8 * application. | |
| 9 */ | |
| 10 | |
| 11 //----------------------------------------------------------------------------- | |
| 12 // The spinning Cube | |
| 13 //----------------------------------------------------------------------------- | |
| 14 | |
| 15 #define _USE_MATH_DEFINES 1 | |
| 16 #include <limits.h> | |
| 17 #include <math.h> | |
| 18 #include <stdarg.h> | |
| 19 #include <stddef.h> | |
| 20 #include <stdio.h> | |
| 21 #include <stdlib.h> | |
| 22 #include <string.h> | |
| 23 | |
| 24 #include "ppapi/c/pp_stdint.h" | |
| 25 #include "ppapi/c/pp_completion_callback.h" | |
| 26 #include "ppapi/c/pp_errors.h" | |
| 27 #include "ppapi/c/pp_graphics_3d.h" | |
| 28 #include "ppapi/c/pp_module.h" | |
| 29 #include "ppapi/c/pp_var.h" | |
| 30 #include "ppapi/c/ppb.h" | |
| 31 #include "ppapi/c/ppb_core.h" | |
| 32 #include "ppapi/c/ppb_graphics_3d.h" | |
| 33 #include "ppapi/c/ppb_instance.h" | |
| 34 #include "ppapi/c/ppb_messaging.h" | |
| 35 #include "ppapi/c/ppb_opengles2.h" | |
| 36 #include "ppapi/c/ppb_var.h" | |
| 37 #include "ppapi/c/ppp.h" | |
| 38 #include "ppapi/c/ppp_instance.h" | |
| 39 #include "ppapi/c/ppp_messaging.h" | |
| 40 #include "ppapi/c/ppb_url_loader.h" | |
| 41 #include "ppapi/c/ppb_url_request_info.h" | |
| 42 | |
| 43 #include "ppapi/c/ppp_graphics_3d.h" | |
| 44 #include "ppapi/lib/gl/gles2/gl2ext_ppapi.h" | |
| 45 | |
| 46 #include <GLES2/gl2.h> | |
| 47 #include "matrix.h" | |
| 48 | |
| 49 static PPB_Messaging* ppb_messaging_interface = NULL; | |
| 50 static PPB_Var* ppb_var_interface = NULL; | |
| 51 static PPB_Core* ppb_core_interface = NULL; | |
| 52 static PPB_Graphics3D* ppb_g3d_interface = NULL; | |
| 53 static PPB_Instance* ppb_instance_interface = NULL; | |
| 54 static PPB_URLRequestInfo* ppb_urlrequestinfo_interface = NULL; | |
| 55 static PPB_URLLoader* ppb_urlloader_interface = NULL; | |
| 56 | |
| 57 static PP_Instance g_instance; | |
| 58 static PP_Resource g_context; | |
| 59 | |
| 60 GLuint g_positionLoc; | |
| 61 GLuint g_texCoordLoc; | |
| 62 GLuint g_colorLoc; | |
| 63 GLuint g_MVPLoc; | |
| 64 GLuint g_vboID; | |
| 65 GLuint g_ibID; | |
| 66 GLubyte g_Indices[36]; | |
| 67 | |
| 68 GLuint g_programObj; | |
| 69 GLuint g_vertexShader; | |
| 70 GLuint g_fragmentShader; | |
| 71 | |
| 72 GLuint g_textureLoc = 0; | |
| 73 GLuint g_textureID = 0; | |
| 74 | |
| 75 float g_fSpinX = 0.0f; | |
| 76 float g_fSpinY = 0.0f; | |
| 77 | |
| 78 //----------------------------------------------------------------------------- | |
| 79 // Rendering Assets | |
| 80 //----------------------------------------------------------------------------- | |
| 81 struct Vertex { | |
| 82 float tu, tv; | |
| 83 float color[3]; | |
| 84 float loc[3]; | |
| 85 }; | |
| 86 | |
| 87 Vertex* g_quadVertices = NULL; | |
| 88 const char* g_TextureData = NULL; | |
| 89 const char* g_VShaderData = NULL; | |
| 90 const char* g_FShaderData = NULL; | |
| 91 int g_LoadCnt = 0; | |
| 92 | |
| 93 //----------------------------------------------------------------------------- | |
| 94 // PROTOTYPES | |
| 95 //----------------------------------------------------------------------------- | |
| 96 void PostMessage(const char* fmt, ...); | |
| 97 char* LoadFile(const char* fileName); | |
| 98 | |
| 99 void BuildQuad(Vertex* verts, int axis[3], float depth, float color[3]); | |
| 100 Vertex* BuildCube(void); | |
| 101 | |
| 102 void InitGL(void); | |
| 103 void InitProgram(void); | |
| 104 void Render(void); | |
| 105 | |
| 106 static struct PP_Var CStrToVar(const char* str) { | |
| 107 if (ppb_var_interface != NULL) { | |
| 108 return ppb_var_interface->VarFromUtf8(str, strlen(str)); | |
| 109 } | |
| 110 return PP_MakeUndefined(); | |
| 111 } | |
| 112 | |
| 113 void PostMessage(const char* fmt, ...) { | |
| 114 va_list args; | |
| 115 va_start(args, fmt); | |
| 116 | |
| 117 char msg[4096]; | |
| 118 vsnprintf(msg, sizeof(msg), fmt, args); | |
| 119 | |
| 120 if (ppb_messaging_interface) | |
| 121 ppb_messaging_interface->PostMessage(g_instance, CStrToVar(msg)); | |
| 122 | |
| 123 va_end(args); | |
| 124 } | |
| 125 | |
| 126 void MainLoop(void* foo, int bar) { | |
| 127 if (g_LoadCnt == 3) { | |
| 128 InitProgram(); | |
| 129 g_LoadCnt++; | |
| 130 } | |
| 131 if (g_LoadCnt > 3) { | |
| 132 Render(); | |
| 133 PP_CompletionCallback cc = PP_MakeCompletionCallback(MainLoop, 0); | |
| 134 ppb_g3d_interface->SwapBuffers(g_context, cc); | |
| 135 } else { | |
| 136 PP_CompletionCallback cc = PP_MakeCompletionCallback(MainLoop, 0); | |
| 137 ppb_core_interface->CallOnMainThread(0, cc, 0); | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 void InitGL(void) { | |
| 142 int32_t attribs[] = { | |
| 143 PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8, | |
| 144 PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 24, | |
| 145 PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 8, | |
| 146 PP_GRAPHICS3DATTRIB_SAMPLES, 0, | |
| 147 PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0, | |
| 148 PP_GRAPHICS3DATTRIB_WIDTH, 640, | |
| 149 PP_GRAPHICS3DATTRIB_HEIGHT, 480, | |
| 150 PP_GRAPHICS3DATTRIB_NONE | |
| 151 }; | |
| 152 | |
| 153 g_context = ppb_g3d_interface->Create(g_instance, 0, attribs); | |
| 154 int32_t success = ppb_instance_interface->BindGraphics(g_instance, g_context); | |
| 155 if (success == PP_FALSE) { | |
| 156 glSetCurrentContextPPAPI(0); | |
| 157 printf("Failed to set context.\n"); | |
| 158 return; | |
| 159 } | |
| 160 glSetCurrentContextPPAPI(g_context); | |
| 161 | |
| 162 glViewport(0, 0, 640, 480); | |
| 163 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
| 164 } | |
| 165 | |
| 166 GLuint compileShader(GLenum type, const char* data) { | |
| 167 const char* shaderStrings[1]; | |
| 168 shaderStrings[0] = data; | |
| 169 | |
| 170 GLuint shader = glCreateShader(type); | |
| 171 glShaderSource(shader, 1, shaderStrings, NULL); | |
| 172 glCompileShader(shader); | |
| 173 return shader; | |
| 174 } | |
| 175 | |
| 176 void InitProgram(void) { | |
| 177 glSetCurrentContextPPAPI(g_context); | |
| 178 | |
| 179 g_vertexShader = compileShader(GL_VERTEX_SHADER, g_VShaderData); | |
| 180 g_fragmentShader = compileShader(GL_FRAGMENT_SHADER, g_FShaderData); | |
| 181 | |
| 182 g_programObj = glCreateProgram(); | |
| 183 glAttachShader(g_programObj, g_vertexShader); | |
| 184 glAttachShader(g_programObj, g_fragmentShader); | |
| 185 glLinkProgram(g_programObj); | |
| 186 | |
| 187 glGenBuffers(1, &g_vboID); | |
| 188 glBindBuffer(GL_ARRAY_BUFFER, g_vboID); | |
| 189 glBufferData(GL_ARRAY_BUFFER, | |
| 190 24 * sizeof(Vertex), | |
| 191 (void*)&g_quadVertices[0], | |
| 192 GL_STATIC_DRAW); | |
| 193 | |
| 194 glGenBuffers(1, &g_ibID); | |
| 195 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ibID); | |
| 196 glBufferData(GL_ELEMENT_ARRAY_BUFFER, | |
| 197 36 * sizeof(char), | |
| 198 (void*)&g_Indices[0], | |
| 199 GL_STATIC_DRAW); | |
| 200 | |
| 201 // | |
| 202 // Create a texture to test out our fragment shader... | |
| 203 // | |
| 204 glGenTextures(1, &g_textureID); | |
| 205 glBindTexture(GL_TEXTURE_2D, g_textureID); | |
| 206 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
| 207 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
| 208 glTexImage2D(GL_TEXTURE_2D, | |
| 209 0, | |
| 210 GL_RGB, | |
| 211 128, | |
| 212 128, | |
| 213 0, | |
| 214 GL_RGB, | |
| 215 GL_UNSIGNED_BYTE, | |
| 216 g_TextureData); | |
| 217 | |
| 218 // | |
| 219 // Locate some parameters by name so we can set them later... | |
| 220 // | |
| 221 g_textureLoc = glGetUniformLocation(g_programObj, "arrowTexture"); | |
| 222 g_positionLoc = glGetAttribLocation(g_programObj, "a_position"); | |
| 223 g_texCoordLoc = glGetAttribLocation(g_programObj, "a_texCoord"); | |
| 224 g_colorLoc = glGetAttribLocation(g_programObj, "a_color"); | |
| 225 g_MVPLoc = glGetUniformLocation(g_programObj, "a_MVP"); | |
| 226 } | |
| 227 | |
| 228 void BuildQuad(Vertex* verts, int axis[3], float depth, float color[3]) { | |
| 229 static float X[4] = { -1.0f, 1.0f, 1.0f, -1.0f }; | |
| 230 static float Y[4] = { -1.0f, -1.0f, 1.0f, 1.0f }; | |
| 231 | |
| 232 for (int i = 0; i < 4; i++) { | |
| 233 verts[i].tu = (1.0 - X[i]) / 2.0f; | |
| 234 verts[i].tv = (Y[i] + 1.0f) / -2.0f * depth; | |
| 235 verts[i].loc[axis[0]] = X[i] * depth; | |
| 236 verts[i].loc[axis[1]] = Y[i] * depth; | |
| 237 verts[i].loc[axis[2]] = depth; | |
| 238 for (int j = 0; j < 3; j++) | |
| 239 verts[i].color[j] = color[j] * (Y[i] + 1.0f) / 2.0f; | |
| 240 } | |
| 241 } | |
| 242 | |
| 243 Vertex* BuildCube() { | |
| 244 Vertex* verts = new Vertex[24]; | |
| 245 for (int i = 0; i < 3; i++) { | |
| 246 int Faxis[3]; | |
| 247 int Baxis[3]; | |
| 248 float Fcolor[3]; | |
| 249 float Bcolor[3]; | |
| 250 for (int j = 0; j < 3; j++) { | |
| 251 Faxis[j] = (j + i) % 3; | |
| 252 Baxis[j] = (j + i) % 3; | |
| 253 } | |
| 254 memset(Fcolor, 0, sizeof(float) * 3); | |
| 255 memset(Bcolor, 0, sizeof(float) * 3); | |
| 256 Fcolor[i] = 0.5f; | |
| 257 Bcolor[i] = 1.0f; | |
| 258 BuildQuad(&verts[0 + i * 4], Faxis, 1.0f, Fcolor); | |
| 259 BuildQuad(&verts[12 + i * 4], Baxis, -1.0f, Bcolor); | |
| 260 } | |
| 261 | |
| 262 for (int i = 0; i < 6; i++) { | |
| 263 g_Indices[i * 6 + 0] = 2 + i * 4; | |
| 264 g_Indices[i * 6 + 1] = 1 + i * 4; | |
| 265 g_Indices[i * 6 + 2] = 0 + i * 4; | |
| 266 g_Indices[i * 6 + 3] = 3 + i * 4; | |
| 267 g_Indices[i * 6 + 4] = 2 + i * 4; | |
| 268 g_Indices[i * 6 + 5] = 0 + i * 4; | |
| 269 } | |
| 270 return verts; | |
| 271 } | |
| 272 | |
| 273 void Render(void) { | |
| 274 static float xRot = 0.0; | |
| 275 static float yRot = 0.0; | |
| 276 | |
| 277 xRot += 2.0f; | |
| 278 yRot += 0.5f; | |
| 279 if (xRot >= 360.0f) | |
| 280 xRot = 0.0; | |
| 281 if (yRot >= 360.0f) | |
| 282 yRot = 0.0; | |
| 283 | |
| 284 glClearColor(0.5, 0.5, 0.5, 1); | |
| 285 glClearDepthf(1.0); | |
| 286 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
| 287 glEnable(GL_DEPTH_TEST); | |
| 288 | |
| 289 //set what program to use | |
| 290 glUseProgram(g_programObj); | |
| 291 glActiveTexture(GL_TEXTURE0); | |
| 292 glBindTexture(GL_TEXTURE_2D, g_textureID); | |
| 293 glUniform1i(g_textureLoc, 0); | |
| 294 | |
| 295 //create our perspective matrix | |
| 296 float mpv[16]; | |
| 297 float trs[16]; | |
| 298 float rot[16]; | |
| 299 | |
| 300 identity_matrix(mpv); | |
| 301 glhPerspectivef2(&mpv[0], 45.0f, 640.0f / 480.0f, 1, 10); | |
| 302 | |
| 303 translate_matrix(0, 0, -4.0, trs); | |
| 304 rotate_matrix(xRot, yRot, 0.0f, rot); | |
| 305 multiply_matrix(trs, rot, trs); | |
| 306 multiply_matrix(mpv, trs, mpv); | |
| 307 glUniformMatrix4fv(g_MVPLoc, 1, GL_FALSE, (GLfloat*)mpv); | |
| 308 | |
| 309 //define the attributes of the vertex | |
| 310 glBindBuffer(GL_ARRAY_BUFFER, g_vboID); | |
| 311 glVertexAttribPointer(g_positionLoc, | |
| 312 3, | |
| 313 GL_FLOAT, | |
| 314 GL_FALSE, | |
| 315 sizeof(Vertex), | |
| 316 (void*)offsetof(Vertex, loc)); | |
| 317 glEnableVertexAttribArray(g_positionLoc); | |
| 318 glVertexAttribPointer(g_texCoordLoc, | |
| 319 2, | |
| 320 GL_FLOAT, | |
| 321 GL_FALSE, | |
| 322 sizeof(Vertex), | |
| 323 (void*)offsetof(Vertex, tu)); | |
| 324 glEnableVertexAttribArray(g_texCoordLoc); | |
| 325 glVertexAttribPointer(g_colorLoc, | |
| 326 3, | |
| 327 GL_FLOAT, | |
| 328 GL_FALSE, | |
| 329 sizeof(Vertex), | |
| 330 (void*)offsetof(Vertex, color)); | |
| 331 glEnableVertexAttribArray(g_colorLoc); | |
| 332 | |
| 333 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ibID); | |
| 334 glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, 0); | |
| 335 } | |
| 336 | |
| 337 typedef void (*OpenCB)(void* dataPtr); | |
| 338 struct OpenRequest { | |
| 339 PP_Resource loader_; | |
| 340 PP_Resource request_; | |
| 341 char* buf_; | |
| 342 void* data_; | |
| 343 int64_t size_; | |
| 344 int64_t avail_; | |
| 345 OpenCB cb_; | |
| 346 }; | |
| 347 | |
| 348 void FreeRequest(OpenRequest* req) { | |
| 349 if (req) { | |
| 350 ppb_core_interface->ReleaseResource(req->request_); | |
| 351 ppb_core_interface->ReleaseResource(req->loader_); | |
| 352 free(req); | |
| 353 } | |
| 354 } | |
| 355 | |
| 356 static void URLPartialRead(void* user_data, int mode) { | |
| 357 OpenRequest* req = (OpenRequest*)user_data; | |
| 358 int64_t total; | |
| 359 int32_t cnt; | |
| 360 | |
| 361 if (mode < 0) { | |
| 362 free(req->buf_); | |
| 363 req->cb_(NULL); | |
| 364 FreeRequest(req); | |
| 365 return; | |
| 366 } | |
| 367 | |
| 368 req->avail_ += mode; | |
| 369 total = req->size_ - req->avail_; | |
| 370 | |
| 371 cnt = (total > LONG_MAX) ? LONG_MAX : (int32_t) total; | |
| 372 // If we still have more to do, re-issue the read. | |
| 373 if (cnt > 0) { | |
| 374 int32_t bytes = ppb_urlloader_interface->ReadResponseBody( | |
| 375 req->loader_, | |
| 376 (void*)&req->buf_[req->avail_], | |
| 377 cnt, | |
| 378 PP_MakeCompletionCallback(URLPartialRead, req)); | |
| 379 | |
| 380 // If the reissue completes immediately, then process it. | |
| 381 if (bytes != PP_OK_COMPLETIONPENDING) { | |
| 382 URLPartialRead(user_data, bytes); | |
| 383 } | |
| 384 return; | |
| 385 } | |
| 386 | |
| 387 // Nothing left, so signal complete. | |
| 388 req->cb_(req); | |
| 389 FreeRequest(req); | |
| 390 printf("Loaded\n"); | |
| 391 } | |
| 392 | |
| 393 static void URLOpened(void* user_data, int mode) { | |
| 394 OpenRequest* req = (OpenRequest*)user_data; | |
| 395 | |
| 396 int64_t cur, total; | |
| 397 int32_t cnt; | |
| 398 ppb_urlloader_interface->GetDownloadProgress(req->loader_, &cur, &total); | |
| 399 | |
| 400 // If we can't preallocate the buffer because the size is unknown, then | |
| 401 // fail the load. | |
| 402 if (total == -1) { | |
| 403 req->cb_(NULL); | |
| 404 FreeRequest(req); | |
| 405 return; | |
| 406 } | |
| 407 | |
| 408 // Otherwise allocate a buffer with enough space for a terminating | |
| 409 // NULL in case we need one. | |
| 410 cnt = (total > LONG_MAX) ? LONG_MAX : (int32_t) total; | |
| 411 req->buf_ = (char*)malloc(cnt + 1); | |
| 412 req->buf_[cnt] = 0; | |
| 413 req->size_ = cnt; | |
| 414 int32_t bytes = ppb_urlloader_interface->ReadResponseBody( | |
| 415 req->loader_, | |
| 416 req->buf_, | |
| 417 cnt, | |
| 418 PP_MakeCompletionCallback(URLPartialRead, req)); | |
| 419 | |
| 420 // Usually we are pending. | |
| 421 if (bytes == PP_OK_COMPLETIONPENDING) | |
| 422 return; | |
| 423 | |
| 424 // But if we did complete the read, then dispatch the handler. | |
| 425 URLPartialRead(req, bytes); | |
| 426 } | |
| 427 | |
| 428 void LoadURL(PP_Instance inst, const char* url, OpenCB cb, void* data) { | |
| 429 OpenRequest* req = (OpenRequest*)malloc(sizeof(OpenRequest)); | |
| 430 memset(req, 0, sizeof(OpenRequest)); | |
| 431 | |
| 432 req->loader_ = ppb_urlloader_interface->Create(inst); | |
| 433 req->request_ = ppb_urlrequestinfo_interface->Create(inst); | |
| 434 req->cb_ = cb; | |
| 435 req->data_ = data; | |
| 436 | |
| 437 if (!req->loader_ || !req->request_) { | |
| 438 cb(NULL); | |
| 439 FreeRequest(req); | |
| 440 return; | |
| 441 } | |
| 442 | |
| 443 ppb_urlrequestinfo_interface->SetProperty( | |
| 444 req->request_, PP_URLREQUESTPROPERTY_URL, CStrToVar(url)); | |
| 445 ppb_urlrequestinfo_interface->SetProperty( | |
| 446 req->request_, PP_URLREQUESTPROPERTY_METHOD, CStrToVar("GET")); | |
| 447 ppb_urlrequestinfo_interface->SetProperty( | |
| 448 req->request_, | |
| 449 PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS, | |
| 450 PP_MakeBool(PP_TRUE)); | |
| 451 | |
| 452 int val = ppb_urlloader_interface->Open( | |
| 453 req->loader_, req->request_, PP_MakeCompletionCallback(URLOpened, req)); | |
| 454 | |
| 455 if (val != PP_OK_COMPLETIONPENDING) { | |
| 456 cb(NULL); | |
| 457 free(req); | |
| 458 } | |
| 459 } | |
| 460 | |
| 461 void Loaded(void* data) { | |
| 462 OpenRequest* req = (OpenRequest*)data; | |
| 463 if (req && req->buf_) { | |
| 464 char** pptr = (char**)req->data_; | |
| 465 *pptr = req->buf_; | |
| 466 g_LoadCnt++; | |
| 467 return; | |
| 468 } | |
| 469 PostMessage("Failed to load asset.\n"); | |
| 470 } | |
| 471 | |
| 472 /** | |
| 473 * Called when the NaCl module is instantiated on the web page. The identifier | |
| 474 * of the new instance will be passed in as the first argument (this value is | |
| 475 * generated by the browser and is an opaque handle). This is called for each | |
| 476 * instantiation of the NaCl module, which is each time the <embed> tag for | |
| 477 * this module is encountered. | |
| 478 * | |
| 479 * If this function reports a failure (by returning @a PP_FALSE), the NaCl | |
| 480 * module will be deleted and DidDestroy will be called. | |
| 481 * @param[in] instance The identifier of the new instance representing this | |
| 482 * NaCl module. | |
| 483 * @param[in] argc The number of arguments contained in @a argn and @a argv. | |
| 484 * @param[in] argn An array of argument names. These argument names are | |
| 485 * supplied in the <embed> tag, for example: | |
| 486 * <embed id="nacl_module" dimensions="2"> | |
| 487 * will produce two arguments, one named "id" and one named "dimensions". | |
| 488 * @param[in] argv An array of argument values. These are the values of the | |
| 489 * arguments listed in the <embed> tag. In the above example, there will | |
| 490 * be two elements in this array, "nacl_module" and "2". The indices of | |
| 491 * these values match the indices of the corresponding names in @a argn. | |
| 492 * @return @a PP_TRUE on success. | |
| 493 */ | |
| 494 static PP_Bool Instance_DidCreate(PP_Instance instance, | |
| 495 uint32_t argc, | |
| 496 const char* argn[], | |
| 497 const char* argv[]) { | |
| 498 g_instance = instance; | |
| 499 LoadURL(instance, "hello.raw", Loaded, &g_TextureData); | |
| 500 LoadURL(instance, "vertex_shader_es2.vert", Loaded, &g_VShaderData); | |
| 501 LoadURL(instance, "fragment_shader_es2.frag", Loaded, &g_FShaderData); | |
| 502 g_quadVertices = BuildCube(); | |
| 503 return PP_TRUE; | |
| 504 } | |
| 505 | |
| 506 /** | |
| 507 * Called when the NaCl module is destroyed. This will always be called, | |
| 508 * even if DidCreate returned failure. This routine should deallocate any data | |
| 509 * associated with the instance. | |
| 510 * @param[in] instance The identifier of the instance representing this NaCl | |
| 511 * module. | |
| 512 */ | |
| 513 static void Instance_DidDestroy(PP_Instance instance) { | |
| 514 delete[] g_TextureData; | |
| 515 delete[] g_VShaderData; | |
| 516 delete[] g_FShaderData; | |
| 517 delete[] g_quadVertices; | |
| 518 } | |
| 519 | |
| 520 /** | |
| 521 * Called when the position, the size, or the clip rect of the element in the | |
| 522 * browser that corresponds to this NaCl module has changed. | |
| 523 * @param[in] instance The identifier of the instance representing this NaCl | |
| 524 * module. | |
| 525 * @param[in] position The location on the page of this NaCl module. This is | |
| 526 * relative to the top left corner of the viewport, which changes as the | |
| 527 * page is scrolled. | |
| 528 * @param[in] clip The visible region of the NaCl module. This is relative to | |
| 529 * the top left of the plugin's coordinate system (not the page). If the | |
| 530 * plugin is invisible, @a clip will be (0, 0, 0, 0). | |
| 531 */ | |
| 532 static void Instance_DidChangeView(PP_Instance instance, | |
| 533 PP_Resource view_resource) { | |
| 534 if (g_context == 0) { | |
| 535 InitGL(); | |
| 536 MainLoop(NULL, 0); | |
| 537 } | |
| 538 } | |
| 539 | |
| 540 /** | |
| 541 * Notification that the given NaCl module has gained or lost focus. | |
| 542 * Having focus means that keyboard events will be sent to the NaCl module | |
| 543 * represented by @a instance. A NaCl module's default condition is that it | |
| 544 * will not have focus. | |
| 545 * | |
| 546 * Note: clicks on NaCl modules will give focus only if you handle the | |
| 547 * click event. You signal if you handled it by returning @a true from | |
| 548 * HandleInputEvent. Otherwise the browser will bubble the event and give | |
| 549 * focus to the element on the page that actually did end up consuming it. | |
| 550 * If you're not getting focus, check to make sure you're returning true from | |
| 551 * the mouse click in HandleInputEvent. | |
| 552 * @param[in] instance The identifier of the instance representing this NaCl | |
| 553 * module. | |
| 554 * @param[in] has_focus Indicates whether this NaCl module gained or lost | |
| 555 * event focus. | |
| 556 */ | |
| 557 static void Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus) {} | |
| 558 | |
| 559 /** | |
| 560 * Handler that gets called after a full-frame module is instantiated based on | |
| 561 * registered MIME types. This function is not called on NaCl modules. This | |
| 562 * function is essentially a place-holder for the required function pointer in | |
| 563 * the PPP_Instance structure. | |
| 564 * @param[in] instance The identifier of the instance representing this NaCl | |
| 565 * module. | |
| 566 * @param[in] url_loader A PP_Resource an open PPB_URLLoader instance. | |
| 567 * @return PP_FALSE. | |
| 568 */ | |
| 569 static PP_Bool Instance_HandleDocumentLoad(PP_Instance instance, | |
| 570 PP_Resource url_loader) { | |
| 571 /* NaCl modules do not need to handle the document load function. */ | |
| 572 return PP_FALSE; | |
| 573 } | |
| 574 | |
| 575 /** | |
| 576 * Entry points for the module. | |
| 577 * Initialize needed interfaces: PPB_Core, PPB_Messaging and PPB_Var. | |
| 578 * @param[in] a_module_id module ID | |
| 579 * @param[in] get_browser pointer to PPB_GetInterface | |
| 580 * @return PP_OK on success, any other value on failure. | |
| 581 */ | |
| 582 PP_EXPORT int32_t PPP_InitializeModule(PP_Module a_module_id, | |
| 583 PPB_GetInterface get_browser) { | |
| 584 ppb_core_interface = (PPB_Core*)(get_browser(PPB_CORE_INTERFACE)); | |
| 585 ppb_instance_interface = (PPB_Instance*)get_browser(PPB_INSTANCE_INTERFACE); | |
| 586 ppb_messaging_interface = | |
| 587 (PPB_Messaging*)(get_browser(PPB_MESSAGING_INTERFACE)); | |
| 588 ppb_var_interface = (PPB_Var*)(get_browser(PPB_VAR_INTERFACE)); | |
| 589 ppb_urlloader_interface = | |
| 590 (PPB_URLLoader*)(get_browser(PPB_URLLOADER_INTERFACE)); | |
| 591 ppb_urlrequestinfo_interface = | |
| 592 (PPB_URLRequestInfo*)(get_browser(PPB_URLREQUESTINFO_INTERFACE)); | |
| 593 ppb_g3d_interface = (PPB_Graphics3D*)get_browser(PPB_GRAPHICS_3D_INTERFACE); | |
| 594 if (!glInitializePPAPI(get_browser)) | |
| 595 return PP_ERROR_FAILED; | |
| 596 return PP_OK; | |
| 597 } | |
| 598 | |
| 599 /** | |
| 600 * Returns an interface pointer for the interface of the given name, or NULL | |
| 601 * if the interface is not supported. | |
| 602 * @param[in] interface_name name of the interface | |
| 603 * @return pointer to the interface | |
| 604 */ | |
| 605 PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { | |
| 606 if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) { | |
| 607 static PPP_Instance instance_interface = { | |
| 608 &Instance_DidCreate, | |
| 609 &Instance_DidDestroy, | |
| 610 &Instance_DidChangeView, | |
| 611 &Instance_DidChangeFocus, | |
| 612 &Instance_HandleDocumentLoad, | |
| 613 }; | |
| 614 return &instance_interface; | |
| 615 } | |
| 616 return NULL; | |
| 617 } | |
| 618 | |
| 619 /** | |
| 620 * Called before the plugin module is unloaded. | |
| 621 */ | |
| 622 PP_EXPORT void PPP_ShutdownModule() {} | |
| OLD | NEW |