1 /* 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include <jni.h> 27 #include <stdlib.h> 28 #include <assert.h> 29 #include <stdio.h> 30 #include <string.h> 31 #include <math.h> 32 33 #include "PrismES2Defs.h" 34 35 extern char *strJavaToC(JNIEnv *env, jstring str); 36 37 void printGLError(GLenum errCode) { 38 char const glCString[] = "*** GLError Code = "; 39 switch (errCode) { 40 case GL_NO_ERROR: 41 //fprintf(stderr, "%sGL_NO_ERROR\n", glCString); 42 break; 43 case GL_INVALID_ENUM: 44 fprintf(stderr, "%sGL_INVALID_ENUM\n", glCString); 45 break; 46 case GL_INVALID_VALUE: 47 fprintf(stderr, "%sGL_INVALID_VALUE\n", glCString); 48 break; 49 case GL_INVALID_OPERATION: 50 fprintf(stderr, "%sGL_INVALID_OPERATION\n", glCString); 51 break; 52 case GL_STACK_OVERFLOW: 53 fprintf(stderr, "%sGL_STACK_OVERFLOW\n", glCString); 54 break; 55 case GL_STACK_UNDERFLOW: 56 fprintf(stderr, "%sGL_STACK_UNDERFLOW\n", glCString); 57 break; 58 case GL_OUT_OF_MEMORY: 59 fprintf(stderr, "%sGL_OUT_OF_MEMORY\n", glCString); 60 break; 61 default: 62 fprintf(stderr, "%s*** UNKNOWN ERROR CODE ***\n", glCString); 63 } 64 } 65 66 void initializeCtxInfo(ContextInfo *ctxInfo) { 67 if (ctxInfo == NULL) { 68 return; 69 } 70 // Initialize structure to all zeros 71 memset(ctxInfo, 0, sizeof (ContextInfo)); 72 } 73 74 void deleteCtxInfo(ContextInfo *ctxInfo) { 75 if (ctxInfo == NULL) { 76 return; 77 } 78 79 if (ctxInfo->versionStr != NULL) { 80 free(ctxInfo->versionStr); 81 } 82 if (ctxInfo->vendorStr != NULL) { 83 free(ctxInfo->vendorStr); 84 } 85 if (ctxInfo->rendererStr != NULL) { 86 free(ctxInfo->rendererStr); 87 } 88 if (ctxInfo->glExtensionStr != NULL) { 89 free(ctxInfo->glExtensionStr); 90 } 91 92 #ifdef WIN32 /* WIN32 */ 93 if (ctxInfo->wglExtensionStr != NULL) { 94 free(ctxInfo->wglExtensionStr); 95 } 96 if (ctxInfo->hglrc != NULL) { 97 wglDeleteContext(ctxInfo->hglrc); 98 ctxInfo->hglrc = NULL; 99 } 100 #endif 101 102 #ifdef UNIX 103 if (ctxInfo->glxExtensionStr != NULL) { 104 free(ctxInfo->glxExtensionStr); 105 } 106 if (ctxInfo->context != NULL) { 107 #if defined(IS_GLX) 108 glXDestroyContext(ctxInfo->display, ctxInfo->context); 109 #endif 110 #ifdef IS_EGL 111 eglDestroyContext(ctxInfo->display, ctxInfo->context); 112 #endif 113 } 114 #endif 115 // Initialize structure to all zeros 116 memset(ctxInfo, 0, sizeof (ContextInfo)); 117 } 118 119 void initState(ContextInfo *ctxInfo) { 120 if (ctxInfo == NULL) { 121 return; 122 } 123 124 glEnable(GL_BLEND); 125 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 126 127 // initialize states and properties to 128 // match cached states and properties 129 130 // depthtest is set to false 131 // Note: This state is cached in GLContext.java 132 ctxInfo->state.depthWritesEnabled = JNI_FALSE; 133 glDepthMask(ctxInfo->state.depthWritesEnabled); 134 glDisable(GL_DEPTH_TEST); 135 #ifndef IS_EGL 136 glDisable(GL_ALPHA_TEST); 137 #endif 138 139 if (ctxInfo->state.scissorEnabled) { 140 ctxInfo->state.scissorEnabled = JNI_FALSE; 141 glDisable(GL_SCISSOR_TEST); 142 } 143 144 ctxInfo->state.clearColor[0] = 0.0; 145 ctxInfo->state.clearColor[1] = 0.0; 146 ctxInfo->state.clearColor[2] = 0.0; 147 ctxInfo->state.clearColor[3] = 0.0; 148 glClearColor(ctxInfo->state.clearColor[0], ctxInfo->state.clearColor[1], 149 ctxInfo->state.clearColor[2], ctxInfo->state.clearColor[3]); 150 151 ctxInfo->vbFloatData = NULL; 152 ctxInfo->vbByteData = NULL; 153 ctxInfo->state.fillMode = GL_FILL; 154 ctxInfo->state.cullEnable = JNI_FALSE; 155 ctxInfo->state.cullMode = GL_BACK; 156 ctxInfo->state.fbo = 0; 157 } 158 159 void clearBuffers(ContextInfo *ctxInfo, 160 GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha, 161 jboolean clearColor, jboolean clearDepth, jboolean ignoreScissor) { 162 GLbitfield clearBIT = 0; 163 164 if (ctxInfo == NULL) { 165 return; 166 } 167 168 if (ignoreScissor && ctxInfo->state.scissorEnabled) { 169 // glClear() honors the current scissor, so disable it 170 // temporarily if ignoreScissor is true 171 glDisable(GL_SCISSOR_TEST); 172 } 173 174 if (clearColor) { 175 clearBIT = GL_COLOR_BUFFER_BIT; 176 if ((ctxInfo->state.clearColor[0] != red) 177 || (ctxInfo->state.clearColor[1] != green) 178 || (ctxInfo->state.clearColor[2] != blue) 179 || (ctxInfo->state.clearColor[3] != alpha)) { 180 glClearColor(red, green, blue, alpha); 181 ctxInfo->state.clearColor[0] = red; 182 ctxInfo->state.clearColor[1] = green; 183 ctxInfo->state.clearColor[2] = blue; 184 ctxInfo->state.clearColor[3] = alpha; 185 } 186 } 187 188 if (clearDepth) { 189 clearBIT |= GL_DEPTH_BUFFER_BIT; 190 // also make sure depth writes are enabled for the clear operation 191 if (!ctxInfo->state.depthWritesEnabled) { 192 glDepthMask(GL_TRUE); 193 } 194 glClear(clearBIT); 195 if (!ctxInfo->state.depthWritesEnabled) { 196 glDepthMask(GL_FALSE); 197 } 198 } else { 199 glClear(clearBIT); 200 } 201 202 // restore previous state 203 if (ignoreScissor && ctxInfo->state.scissorEnabled) { 204 glEnable(GL_SCISSOR_TEST); 205 } 206 } 207 208 void bindFBO(ContextInfo *ctxInfo, GLuint fboId) { 209 if ((ctxInfo == NULL) || (ctxInfo->glBindFramebuffer == NULL)) { 210 return; 211 } 212 ctxInfo->glBindFramebuffer(GL_FRAMEBUFFER, fboId); 213 ctxInfo->state.fbo = fboId; 214 } 215 216 /* 217 * Class: com_sun_prism_es2_GLContext 218 * Method: nActiveTexture 219 * Signature: (JI)V 220 */ 221 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nActiveTexture 222 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint texUnit) { 223 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 224 if ((ctxInfo == NULL) || (ctxInfo->glActiveTexture == NULL)) { 225 return; 226 } 227 ctxInfo->glActiveTexture(GL_TEXTURE0 + texUnit); 228 } 229 230 /* 231 * Class: com_sun_prism_es2_GLContext 232 * Method: nBindFBO 233 * Signature: (JI)V 234 */ 235 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nBindFBO 236 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint fboId) { 237 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 238 bindFBO(ctxInfo, (GLuint)fboId); 239 } 240 241 /* 242 * Class: com_sun_prism_es2_GLContext 243 * Method: nBindTexture 244 * Signature: (JI)V 245 */ 246 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nBindTexture 247 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint texID) { 248 glBindTexture(GL_TEXTURE_2D, texID); 249 } 250 251 GLenum translateScaleFactor(jint scaleFactor) { 252 switch (scaleFactor) { 253 case com_sun_prism_es2_GLContext_GL_ZERO: 254 return GL_ZERO; 255 case com_sun_prism_es2_GLContext_GL_ONE: 256 return GL_ONE; 257 case com_sun_prism_es2_GLContext_GL_SRC_COLOR: 258 return GL_SRC_COLOR; 259 case com_sun_prism_es2_GLContext_GL_ONE_MINUS_SRC_COLOR: 260 return GL_ONE_MINUS_SRC_COLOR; 261 case com_sun_prism_es2_GLContext_GL_DST_COLOR: 262 return GL_DST_COLOR; 263 case com_sun_prism_es2_GLContext_GL_ONE_MINUS_DST_COLOR: 264 return GL_ONE_MINUS_DST_COLOR; 265 case com_sun_prism_es2_GLContext_GL_SRC_ALPHA: 266 return GL_SRC_ALPHA; 267 case com_sun_prism_es2_GLContext_GL_ONE_MINUS_SRC_ALPHA: 268 return GL_ONE_MINUS_SRC_ALPHA; 269 case com_sun_prism_es2_GLContext_GL_DST_ALPHA: 270 return GL_DST_ALPHA; 271 case com_sun_prism_es2_GLContext_GL_ONE_MINUS_DST_ALPHA: 272 return GL_ONE_MINUS_DST_ALPHA; 273 case com_sun_prism_es2_GLContext_GL_CONSTANT_COLOR: 274 return GL_CONSTANT_COLOR; 275 case com_sun_prism_es2_GLContext_GL_ONE_MINUS_CONSTANT_COLOR: 276 return GL_ONE_MINUS_CONSTANT_COLOR; 277 case com_sun_prism_es2_GLContext_GL_CONSTANT_ALPHA: 278 return GL_CONSTANT_ALPHA; 279 case com_sun_prism_es2_GLContext_GL_ONE_MINUS_CONSTANT_ALPHA: 280 return GL_ONE_MINUS_CONSTANT_ALPHA; 281 case com_sun_prism_es2_GLContext_GL_SRC_ALPHA_SATURATE: 282 return GL_SRC_ALPHA_SATURATE; 283 default: 284 fprintf(stderr, "Error: Unknown scale factor. Returning GL_ZERO (default)"); 285 } 286 return GL_ZERO; 287 } 288 289 /* 290 * Class: com_sun_prism_es2_GLContext 291 * Method: nBlendFunc 292 * Signature: (II)V 293 */ 294 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nBlendFunc 295 (JNIEnv *env, jclass class, jint sFactor, jint dFactor) { 296 glBlendFunc(translateScaleFactor(sFactor), translateScaleFactor(dFactor)); 297 } 298 299 /* 300 * Class: com_sun_prism_es2_GLContext 301 * Method: nClearBuffers 302 * Signature: (JFFFFZZZ)V 303 */ 304 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nClearBuffers 305 (JNIEnv *env, jclass class, jlong nativeCtxInfo, 306 jfloat red, jfloat green, jfloat blue, jfloat alpha, 307 jboolean clearColor, jboolean clearDepth, jboolean ignoreScissor) { 308 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 309 if (ctxInfo == NULL) { 310 return; 311 } 312 313 clearBuffers(ctxInfo, 314 (GLclampf) red, (GLclampf) green, (GLclampf) blue, (GLclampf) alpha, 315 clearColor, clearDepth, ignoreScissor); 316 } 317 318 int checkFramebufferStatus(ContextInfo *ctxInfo) { 319 GLenum status; 320 status = ctxInfo->glCheckFramebufferStatus(GL_FRAMEBUFFER); 321 if (status != GL_FRAMEBUFFER_COMPLETE) { 322 switch(status) { 323 case GL_FRAMEBUFFER_COMPLETE: 324 return GL_FALSE; 325 break; 326 case GL_FRAMEBUFFER_UNSUPPORTED: 327 //Choose different formats 328 fprintf(stderr, "Framebuffer object format is unsupported by the video hardware. (GL_FRAMEBUFFER_UNSUPPORTED)(FBO - 820)\n"); 329 break; 330 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 331 fprintf(stderr, "Incomplete attachment. (GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)(FBO - 820)\n"); 332 break; 333 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 334 fprintf(stderr, "Incomplete missing attachment. (GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)(FBO - 820)\n"); 335 break; 336 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: 337 fprintf(stderr, "Incomplete dimensions. (GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT)(FBO - 820)\n"); 338 break; 339 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: 340 fprintf(stderr, "Incomplete formats. (GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT)(FBO - 820)\n"); 341 break; 342 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: 343 fprintf(stderr, "Incomplete draw buffer. (GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER)(FBO - 820)\n"); 344 break; 345 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: 346 fprintf(stderr, "Incomplete read buffer. (GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER)(FBO - 820)\n"); 347 break; 348 case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: 349 fprintf(stderr, "Incomplete multisample buffer. (GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)(FBO - 820)\n"); 350 break; 351 default: 352 //Programming error; will fail on all hardware 353 fprintf(stderr, "Some video driver error or programming error occurred. Framebuffer object status is invalid. (FBO - 823)\n"); 354 break; 355 } 356 return GL_TRUE; 357 } 358 return GL_FALSE; 359 } 360 361 /* 362 * Class: com_sun_prism_es2_GLContext 363 * Method: nBlit 364 * Signature: (JIIIIIIIIII)V 365 */ 366 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nBlit 367 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint srcFBO, jint dstFBO, 368 jint jsrcX0, jint jsrcY0, jint srcX1, jint srcY1, 369 jint jdstX0, jint jdstY0, jint dstX1, jint dstY1) { 370 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 371 if ((ctxInfo == NULL) || (ctxInfo->glGenFramebuffers == NULL) 372 || (ctxInfo->glBindFramebuffer == NULL) 373 || (ctxInfo->glBlitFramebuffer == NULL)) { 374 return; 375 } 376 377 if (dstFBO == 0) { 378 dstFBO = ctxInfo->state.fbo; 379 } 380 //Bind the FBOs 381 ctxInfo->glBindFramebuffer(GL_READ_FRAMEBUFFER, (GLuint)srcFBO); 382 ctxInfo->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint)dstFBO); 383 ctxInfo->glBlitFramebuffer(jsrcX0, jsrcY0, srcX1, srcY1, 384 jdstX0, jdstY0, dstX1, dstY1, 385 GL_COLOR_BUFFER_BIT, GL_NEAREST); 386 /* TODO: iOS MSAA support: 387 * We are using glBlitFramebuffer to "resolve" the mutlisample buffer, 388 * to a color destination. iOS does things differently, it uses 389 * glResolveMultisampleFramebufferAPPLE() in place of glBlit... 390 * Problem is glResolve.. does not take arguments so we can't flip 391 * coordinate system. 392 */ 393 394 // Restore previous FBO 395 ctxInfo->glBindFramebuffer(GL_FRAMEBUFFER, ctxInfo->state.fbo); 396 } 397 398 GLuint attachRenderbuffer(ContextInfo *ctxInfo, GLuint rbID, GLenum attachment) { 399 //GLenum status; 400 ctxInfo->glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, 401 GL_RENDERBUFFER, rbID); 402 ctxInfo->glBindRenderbuffer(GL_RENDERBUFFER, 0); 403 //status = ctxInfo->glCheckFramebufferStatus(GL_FRAMEBUFFER); 404 if (checkFramebufferStatus(ctxInfo)) { 405 ctxInfo->glDeleteRenderbuffers(1, &rbID); 406 rbID = 0; 407 fprintf(stderr, "Error creating render buffer object %d\n", rbID); 408 } else { 409 // explicitly clear the render buffers, since it may contain 410 // garbage after initialization 411 clearBuffers(ctxInfo, 0, 0, 0, 0, JNI_FALSE, JNI_TRUE, JNI_TRUE); 412 } 413 return rbID; 414 } 415 416 GLuint createAndAttachRenderBuffer(ContextInfo *ctxInfo, GLsizei width, GLsizei height, GLsizei msaa, GLenum attachment) { 417 GLuint rbID; 418 GLenum internalFormat; 419 420 if ((ctxInfo == NULL) || (ctxInfo->glGenRenderbuffers == NULL) 421 || (ctxInfo->glBindRenderbuffer == NULL) 422 || (ctxInfo->glRenderbufferStorage == NULL) 423 || (ctxInfo->glFramebufferRenderbuffer == NULL) 424 #ifndef IS_EGL 425 || (ctxInfo->glRenderbufferStorageMultisample == NULL) 426 #endif 427 || (ctxInfo->glCheckFramebufferStatus == NULL) 428 || (ctxInfo->glDeleteRenderbuffers == NULL)) { 429 return 0; 430 } 431 432 if (attachment == GL_DEPTH_ATTACHMENT) { 433 #ifdef IS_EGL 434 internalFormat = GL_DEPTH_COMPONENT16; 435 #else 436 internalFormat = GL_DEPTH_COMPONENT; 437 #endif 438 } else { 439 internalFormat = GL_RGBA8; //TODO verify format on RGBA or RGBA8 440 } 441 // create a depth buffer 442 ctxInfo->glGenRenderbuffers(1, &rbID); 443 ctxInfo->glBindRenderbuffer(GL_RENDERBUFFER, rbID); 444 #ifdef IS_EGL 445 ctxInfo->glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, width, height); 446 #else 447 if (msaa) { 448 ctxInfo->glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, internalFormat, width, height); 449 } else { 450 ctxInfo->glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, width, height); 451 } 452 #endif 453 return attachRenderbuffer(ctxInfo, rbID, attachment); 454 } 455 456 /* 457 * Class: com_sun_prism_es2_GLContext 458 * Method: nCreateDepthBuffer 459 * Signature: (JIII)I 460 */ 461 JNIEXPORT jint JNICALL Java_com_sun_prism_es2_GLContext_nCreateDepthBuffer 462 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint width, jint height, jint msaa) { 463 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 464 return createAndAttachRenderBuffer(ctxInfo, width, height, msaa, GL_DEPTH_ATTACHMENT); 465 } 466 467 /* 468 * Class: com_sun_prism_es2_GLContext 469 * Method: nCreateRenderBuffer 470 * Signature: (JIII)I 471 */ 472 JNIEXPORT jint JNICALL Java_com_sun_prism_es2_GLContext_nCreateRenderBuffer 473 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint width, jint height, jint msaa) { 474 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 475 return createAndAttachRenderBuffer(ctxInfo, width, height, msaa, GL_COLOR_ATTACHMENT0); 476 } 477 478 /* 479 * Class: com_sun_prism_es2_GLContext 480 * Method: nCreateFBO 481 * Signature: (JI)I 482 */ 483 JNIEXPORT jint JNICALL Java_com_sun_prism_es2_GLContext_nCreateFBO 484 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint texID) { 485 GLuint fboID; 486 487 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 488 if ((ctxInfo == NULL) || (ctxInfo->glGenFramebuffers == NULL) 489 || (ctxInfo->glFramebufferTexture2D == NULL) 490 || (ctxInfo->glCheckFramebufferStatus == NULL) 491 || (ctxInfo->glDeleteFramebuffers == NULL)) { 492 return 0; 493 } 494 495 // initialize framebuffer object 496 ctxInfo->glGenFramebuffers(1, &fboID); 497 bindFBO(ctxInfo, fboID); 498 499 if (texID) { 500 // Attach color texture to framebuffer object 501 ctxInfo->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 502 GL_TEXTURE_2D, (GLuint)texID, 0); 503 // Can't check status of FBO until after a buffer is attached to it 504 if (checkFramebufferStatus(ctxInfo)) { 505 ctxInfo->glDeleteFramebuffers(1, &fboID); 506 fprintf(stderr, 507 "Error creating framebuffer object with TexID %d)\n", (int) texID); 508 return 0; 509 } 510 // explicitly clear the color buffer, since it may contain garbage 511 // after initialization 512 clearBuffers(ctxInfo, 0, 0, 0, 0, JNI_TRUE, JNI_FALSE, JNI_TRUE); 513 } 514 515 return (jint)fboID; 516 } 517 518 /* 519 * Class: com_sun_prism_es2_GLContext 520 * Method: nCreateProgram 521 * Signature: (JI[II[Ljava/lang/String;[I)I 522 */ 523 JNIEXPORT jint JNICALL Java_com_sun_prism_es2_GLContext_nCreateProgram 524 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint vertID, jintArray fragIDArr, 525 jint numAttrs, jobjectArray attrs, jintArray indexs) { 526 GLuint shaderProgram; 527 int success, status, i; 528 jstring attrName; 529 jint *indexsPtr; 530 char *attrNameString; 531 jboolean valid; 532 jint *fragIDs; 533 jsize length; 534 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 535 if ((ctxInfo == NULL) || (attrs == NULL) || (indexs == NULL) 536 || (ctxInfo->glCreateProgram == NULL) 537 || (ctxInfo->glAttachShader == NULL) 538 || (ctxInfo->glBindAttribLocation == NULL) 539 || (ctxInfo->glLinkProgram == NULL) 540 || (ctxInfo->glGetProgramiv == NULL) 541 || (ctxInfo->glValidateProgram == NULL) 542 || (ctxInfo->glDetachShader == NULL) 543 || (ctxInfo->glDeleteShader == NULL) 544 || (ctxInfo->glDeleteProgram == NULL)) { 545 return 0; 546 } 547 548 if (fragIDArr != NULL) { 549 length = (*env)->GetArrayLength(env, fragIDArr); 550 fragIDs = (*env)->GetIntArrayElements(env, fragIDArr, NULL); 551 } else { 552 return 0; 553 } 554 // create the program object and attach it to the shader 555 shaderProgram = ctxInfo->glCreateProgram(); 556 ctxInfo->glAttachShader(shaderProgram, vertID); 557 for (i = 0; i < length; i++) { 558 ctxInfo->glAttachShader(shaderProgram, fragIDs[i]); 559 } 560 561 // bind any user-defined index values to their corresponding names 562 indexsPtr = (*env)->GetIntArrayElements(env, indexs, NULL); 563 for (i = 0; i < numAttrs; i++) { 564 attrName = (*env)->GetObjectArrayElement(env, attrs, i); 565 attrNameString = strJavaToC(env, attrName); 566 ctxInfo->glBindAttribLocation(shaderProgram, indexsPtr[i], attrNameString); 567 free(attrNameString); 568 } 569 570 // link the program 571 ctxInfo->glLinkProgram(shaderProgram); 572 ctxInfo->glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); 573 574 if (success == GL_FALSE) { 575 GLint length; 576 577 valid = JNI_FALSE; 578 ctxInfo->glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH , &length ); 579 if (length) { 580 char* msg = (char *) malloc((length * sizeof(char))); 581 ctxInfo->glGetProgramInfoLog ( shaderProgram , length , NULL , msg ); 582 printf("Program link log: %s\n",msg); 583 free(msg); 584 } 585 } else { 586 ctxInfo->glValidateProgram(shaderProgram); 587 ctxInfo->glGetProgramiv(shaderProgram, GL_VALIDATE_STATUS, &status); 588 if (status == GL_FALSE) { 589 GLint length; 590 valid = JNI_FALSE; 591 fprintf(stderr, "Program validation failed\n"); 592 ctxInfo->glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH , &length ); 593 if (length) { 594 char* msg = (char *) malloc((length * sizeof(char))); 595 ctxInfo->glGetProgramInfoLog ( shaderProgram , length , NULL , msg ); 596 fprintf(stderr, "Program validation log: %s\n", msg); 597 fflush(stderr); 598 free(msg); 599 } 600 } else { 601 valid = JNI_TRUE; 602 } 603 } 604 #ifdef ANDROID_NDK 605 valid = JNI_TRUE; 606 #endif 607 if (!valid) { 608 ctxInfo->glDetachShader(shaderProgram, vertID); 609 ctxInfo->glDeleteShader(vertID); 610 for(i = 0; i < length; i++) { 611 ctxInfo->glDetachShader(shaderProgram, fragIDs[i]); 612 ctxInfo->glDeleteShader(fragIDs[i]); 613 } 614 ctxInfo->glDeleteProgram(shaderProgram); 615 return 0; 616 } 617 618 (*env)->ReleaseIntArrayElements(env, fragIDArr, fragIDs, JNI_ABORT); 619 620 return shaderProgram; 621 } 622 623 /* 624 * Class: com_sun_prism_es2_GLContext 625 * Method: nCompileShader 626 * Signature: (JLjava/lang/String;Z)I 627 */ 628 JNIEXPORT jint JNICALL Java_com_sun_prism_es2_GLContext_nCompileShader 629 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jstring src, jboolean vertex) { 630 GLenum shaderType; 631 GLuint shaderID; 632 GLint success; 633 634 /* Null-terminated "C" strings */ 635 GLchar *shaderString = NULL; 636 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 637 if ((ctxInfo == NULL) || (src == NULL) 638 || (ctxInfo->glCreateShader == NULL) 639 || (ctxInfo->glShaderSource == NULL) 640 || (ctxInfo->glCompileShader == NULL) 641 || (ctxInfo->glGetShaderiv == NULL) 642 || (ctxInfo->glDeleteShader == NULL)) { 643 return 0; 644 } 645 646 // create the shader object and compile the shader source code 647 shaderType = vertex ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER; 648 shaderID = ctxInfo->glCreateShader(shaderType); 649 shaderString = (GLchar *) strJavaToC(env, src); 650 if (shaderString == NULL) { 651 /* Just return, since strJavaToC will throw OOM if it returns NULL */ 652 return 0; 653 } 654 ctxInfo->glShaderSource(shaderID, 1, (const GLchar **) &shaderString, (GLint *) NULL); 655 ctxInfo->glCompileShader(shaderID); 656 ctxInfo->glGetShaderiv(shaderID, GL_COMPILE_STATUS, &success); 657 658 free(shaderString); 659 660 if (success == GL_FALSE) { 661 GLint length; 662 ctxInfo->glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH , &length ); 663 if (length) { 664 char* msg = (char *) malloc((length * sizeof(char)) + 1); 665 ctxInfo->glGetShaderInfoLog ( shaderID , length , NULL , msg ); 666 printf("Shader compile log: %s\n",msg); 667 free(msg); 668 } 669 } 670 671 if (success == GL_FALSE) { 672 ctxInfo->glDeleteShader(shaderID); 673 return 0; 674 } 675 676 return shaderID; 677 } 678 679 /* 680 * Class: com_sun_prism_es2_GLContext 681 * Method: nCreateTexture 682 * Signature: (JII)I 683 */ 684 JNIEXPORT jint JNICALL Java_com_sun_prism_es2_GLContext_nCreateTexture 685 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint width, jint height) { 686 GLuint texID = 0; 687 GLenum err; 688 689 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 690 if ((ctxInfo == NULL) || (ctxInfo->glActiveTexture == NULL)) { 691 return 0; 692 } 693 694 glGenTextures(1, &texID); 695 if (texID == 0) { 696 // fprintf(stderr, "nCreateTexture: Failed to generate texture.\n"); 697 return (jint) texID; 698 } 699 700 glBindTexture(GL_TEXTURE_2D, texID); 701 702 // Reset Error 703 glGetError(); 704 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 705 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 706 707 err = glGetError(); 708 // printGLError(err); 709 710 if (err != GL_NO_ERROR) { 711 glDeleteTextures(1, &texID); 712 texID = 0; 713 } else { 714 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 715 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 716 } 717 return (jint) texID; 718 } 719 720 /* 721 * Class: com_sun_prism_es2_GLContext 722 * Method: nDisposeShaders 723 * Signature: (JII[I)V 724 */ 725 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nDisposeShaders 726 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint shaderProgram, 727 jint vertID, jintArray fragIDArr) { 728 jsize length; 729 jint* fragIDs; 730 int i; 731 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 732 if ((ctxInfo == NULL) || (ctxInfo->glDetachShader == NULL) 733 || (ctxInfo->glDeleteShader == NULL) 734 || (ctxInfo->glDeleteProgram == NULL)) { 735 return; 736 } 737 738 if (vertID != 0) { 739 ctxInfo->glDetachShader(shaderProgram, vertID); 740 ctxInfo->glDeleteShader(vertID); 741 } 742 743 if (fragIDArr == NULL) { 744 return; 745 } 746 747 length = (*env)->GetArrayLength(env, fragIDArr); 748 fragIDs = (*env)->GetIntArrayElements(env, fragIDArr, NULL); 749 750 for (i = 0; i < length; i++) { 751 if (fragIDs[i] != 0) { 752 ctxInfo->glDetachShader(shaderProgram, fragIDs[i]); 753 ctxInfo->glDeleteShader(fragIDs[i]); 754 } 755 } 756 757 (*env)->ReleaseIntArrayElements(env, fragIDArr, fragIDs, JNI_ABORT); 758 759 ctxInfo->glDeleteProgram(shaderProgram); 760 } 761 762 /* 763 * Class: com_sun_prism_es2_GLContext 764 * Method: nDeleteFBO 765 * Signature: (JI)V 766 */ 767 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nDeleteFBO 768 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint fboID) { 769 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 770 if ((ctxInfo == NULL) || (ctxInfo->glDeleteFramebuffers == NULL)) { 771 return; 772 } 773 if (fboID != 0) { 774 ctxInfo->glDeleteFramebuffers(1, (GLuint *) &fboID); 775 } 776 } 777 778 /* 779 * Class: com_sun_prism_es2_GLContext 780 * Method: nDeleteRenderBuffer 781 * Signature: (JI)V 782 */ 783 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nDeleteRenderBuffer 784 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint rbID) { 785 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 786 if ((ctxInfo == NULL) || (ctxInfo->glDeleteRenderbuffers == NULL)) { 787 return; 788 } 789 if (rbID != 0) { 790 ctxInfo->glDeleteRenderbuffers(1, (GLuint *) &rbID); 791 } 792 } 793 794 /* 795 * Class: com_sun_prism_es2_GLContext 796 * Method: nDeleteShader 797 * Signature: (JI)V 798 */ 799 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nDeleteShader 800 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint shaderID) { 801 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 802 if ((ctxInfo == NULL) || (ctxInfo->glDeleteShader == NULL)) { 803 return; 804 } 805 if (shaderID != 0) { 806 ctxInfo->glDeleteShader(shaderID); 807 } 808 } 809 810 /* 811 * Class: com_sun_prism_es2_GLContext 812 * Method: nDeleteTexture 813 * Signature: (JI)V 814 */ 815 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nDeleteTexture 816 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint texID) { 817 GLuint tID = (GLuint) texID; 818 if (tID != 0) { 819 glDeleteTextures(1, &tID); 820 } 821 } 822 823 /* 824 * Class: com_sun_prism_es2_GLContext 825 * Method: nFinish 826 * Signature: ()V 827 */ 828 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nFinish 829 (JNIEnv *env, jclass class) { 830 glFinish(); 831 } 832 833 /* 834 * Class: com_sun_prism_es2_GLContext 835 * Method: nGenAndBindTexture 836 * Signature: ()I 837 */ 838 JNIEXPORT jint JNICALL Java_com_sun_prism_es2_GLContext_nGenAndBindTexture 839 (JNIEnv *env, jclass class) { 840 GLuint texID; 841 glGenTextures(1, &texID); 842 glBindTexture(GL_TEXTURE_2D, texID); 843 return texID; 844 } 845 846 /* 847 * Class: com_sun_prism_es2_GLContext 848 * Method: nGetFBO 849 * Signature: ()I 850 */ 851 JNIEXPORT jint JNICALL Java_com_sun_prism_es2_GLContext_nGetFBO 852 (JNIEnv *env, jclass class) { 853 GLint param; 854 /* The caching logic has been done on Java side if 855 * platform isn't MAC or IOS. On these platforms Glass 856 * can change the FBO under us. We should be able to simplify the 857 * logic in Java and remove this method once once Glass stop doing it. 858 */ 859 glGetIntegerv(GL_FRAMEBUFFER_BINDING, ¶m); 860 return (jint) param; 861 } 862 863 /* 864 * Class: com_sun_prism_es2_GLContext 865 * Method: nGetMaxSampleSize 866 * Signature: ()I 867 */ 868 JNIEXPORT jint JNICALL Java_com_sun_prism_es2_GLContext_nGetMaxSampleSize 869 (JNIEnv *env, jclass class) { 870 GLint samples; 871 glGetIntegerv(GL_MAX_SAMPLES, &samples); 872 return (jint)samples; 873 } 874 875 /* 876 * Class: com_sun_prism_es2_GLContext 877 * Method: nGetMaxTextureSize 878 * Signature: ()I 879 */ 880 JNIEXPORT jint JNICALL Java_com_sun_prism_es2_GLContext_nGetMaxTextureSize 881 (JNIEnv *env, jclass class) { 882 GLint param; 883 glGetIntegerv(GL_MAX_TEXTURE_SIZE, ¶m); 884 return (jint) param; 885 } 886 887 /* 888 * Class: com_sun_prism_es2_GLContext 889 * Method: nGetUniformLocation 890 * Signature: (JILjava/lang/String;)I 891 */ 892 JNIEXPORT jint JNICALL Java_com_sun_prism_es2_GLContext_nGetUniformLocation 893 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint programID, jstring name) { 894 GLint result; 895 char *nameString; 896 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 897 898 if ((ctxInfo == NULL) || (name == NULL) 899 || (ctxInfo->glGetUniformLocation == NULL)) { 900 return 0; 901 } 902 903 nameString = strJavaToC(env, name); 904 result = ctxInfo->glGetUniformLocation(programID, nameString); 905 free(nameString); 906 return result; 907 } 908 909 int translatePrismToGL(int value) { 910 switch (value) { 911 case com_sun_prism_es2_GLContext_GL_FLOAT: 912 return GL_FLOAT; 913 case com_sun_prism_es2_GLContext_GL_UNSIGNED_BYTE: 914 return GL_UNSIGNED_BYTE; 915 case com_sun_prism_es2_GLContext_GL_UNSIGNED_INT_8_8_8_8_REV: 916 return GL_UNSIGNED_INT_8_8_8_8_REV; 917 case com_sun_prism_es2_GLContext_GL_UNSIGNED_INT_8_8_8_8: 918 return GL_UNSIGNED_INT_8_8_8_8; 919 case com_sun_prism_es2_GLContext_GL_UNSIGNED_SHORT_8_8_APPLE: 920 /* not using symbolic name may not be available on all platform - DrD*/ 921 return 0x85BA; 922 923 case com_sun_prism_es2_GLContext_GL_RGBA: 924 return GL_RGBA; 925 case com_sun_prism_es2_GLContext_GL_BGRA: 926 return GL_BGRA; 927 case com_sun_prism_es2_GLContext_GL_RGB: 928 return GL_RGB; 929 case com_sun_prism_es2_GLContext_GL_LUMINANCE: 930 return GL_LUMINANCE; 931 case com_sun_prism_es2_GLContext_GL_ALPHA: 932 return GL_ALPHA; 933 case com_sun_prism_es2_GLContext_GL_RGBA32F: 934 return GL_RGBA32F; 935 case com_sun_prism_es2_GLContext_GL_YCBCR_422_APPLE: 936 /* not using symbolic name may not be available on all platform - DrD*/ 937 return 0x85B9; 938 939 case com_sun_prism_es2_GLContext_GL_TEXTURE_2D: 940 return GL_TEXTURE_2D; 941 case com_sun_prism_es2_GLContext_GL_TEXTURE_BINDING_2D: 942 return GL_TEXTURE_BINDING_2D; 943 case com_sun_prism_es2_GLContext_GL_LINEAR: 944 return GL_LINEAR; 945 946 case com_sun_prism_es2_GLContext_WRAPMODE_REPEAT: 947 return GL_REPEAT; 948 case com_sun_prism_es2_GLContext_WRAPMODE_CLAMP_TO_EDGE: 949 return GL_CLAMP_TO_EDGE; 950 case com_sun_prism_es2_GLContext_WRAPMODE_CLAMP_TO_BORDER: 951 return GL_CLAMP_TO_BORDER; 952 default: 953 fprintf(stderr, "warning: Unknown value. Returning value = %d\n", value); 954 } 955 return value; 956 } 957 958 GLint translatePixelStore(int pname) { 959 switch (pname) { 960 // Use by glPixelStorei 961 case com_sun_prism_es2_GLContext_GL_UNPACK_ALIGNMENT: 962 return GL_UNPACK_ALIGNMENT; 963 case com_sun_prism_es2_GLContext_GL_UNPACK_ROW_LENGTH: 964 return GL_UNPACK_ROW_LENGTH; 965 case com_sun_prism_es2_GLContext_GL_UNPACK_SKIP_PIXELS: 966 return GL_UNPACK_SKIP_PIXELS; 967 case com_sun_prism_es2_GLContext_GL_UNPACK_SKIP_ROWS: 968 return GL_UNPACK_SKIP_ROWS; 969 970 default: 971 fprintf(stderr, "warning: Unknown pname. Returning pname = %d\n", pname); 972 } 973 return (GLint) pname; 974 } 975 976 /* 977 * Class: com_sun_prism_es2_GLContext 978 * Method: nPixelStorei 979 * Signature: (II)V 980 */ 981 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nPixelStorei 982 (JNIEnv *env, jclass class, jint pname, jint value) { 983 glPixelStorei((GLenum) translatePixelStore(pname), (GLint) value); 984 } 985 986 jboolean doReadPixels(JNIEnv *env, jlong nativeCtxInfo, jint length, jobject buffer, 987 jarray pixelArr, jint x, jint y, jint width, jint height) { 988 GLvoid *ptr = NULL; 989 990 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 991 if (ctxInfo == NULL) { 992 fprintf(stderr, "doReadPixels: ctxInfo is NULL\n"); 993 return JNI_FALSE; 994 } 995 996 // sanity check, do we have enough memory 997 // length, width and height are non-negative 998 if ((length / 4 / width) < height) { 999 fprintf(stderr, "doReadPixels: pixel buffer too small - length = %d\n", 1000 (int) length); 1001 return JNI_FALSE; 1002 } 1003 1004 ptr = (GLvoid *) (pixelArr ? 1005 ((char *) (*env)->GetPrimitiveArrayCritical(env, pixelArr, NULL)) : 1006 ((char *) (*env)->GetDirectBufferAddress(env, buffer))); 1007 1008 if (ptr == NULL) { 1009 fprintf(stderr, "doReadPixels: pixel buffer is NULL\n"); 1010 return JNI_FALSE; 1011 } 1012 1013 if (ctxInfo->gl2) { 1014 glReadPixels((GLint) x, (GLint) y, (GLsizei) width, (GLsizei) height, 1015 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, ptr); 1016 } else { 1017 jint i; 1018 GLubyte* c = (GLubyte*) ptr; 1019 GLubyte temp; 1020 glReadPixels((GLint) x, (GLint) y, (GLsizei) width, (GLsizei) height, 1021 GL_RGBA, GL_UNSIGNED_BYTE, ptr); 1022 1023 for (i = 0; i < width * height; i++) { 1024 temp = c[0]; 1025 c[0] = c[2]; 1026 c[2] = temp; 1027 c += 4; 1028 } 1029 } 1030 1031 if (pixelArr != NULL) { 1032 (*env)->ReleasePrimitiveArrayCritical(env, pixelArr, ptr, 0); 1033 } 1034 return JNI_TRUE; 1035 } 1036 1037 /* 1038 * Class: com_sun_prism_es2_GLContext 1039 * Method: nReadPixelsByte 1040 * Signature: (JILjava/nio/Buffer;[BIIII)Z 1041 */ 1042 JNIEXPORT jboolean JNICALL Java_com_sun_prism_es2_GLContext_nReadPixelsByte 1043 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint length, jobject buffer, 1044 jbyteArray pixelArr, jint x, jint y, jint w, jint h) { 1045 return doReadPixels(env, nativeCtxInfo, length, buffer, pixelArr, x, y, w, h); 1046 } 1047 1048 /* 1049 * Class: com_sun_prism_es2_GLContext 1050 * Method: nReadPixelsInt 1051 * Signature: (JILjava/nio/Buffer;[IIIII)Z 1052 */ 1053 JNIEXPORT jboolean JNICALL Java_com_sun_prism_es2_GLContext_nReadPixelsInt 1054 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint length, jobject buffer, 1055 jintArray pixelArr, jint x, jint y, jint w, jint h) { 1056 return doReadPixels(env, nativeCtxInfo, length, buffer, pixelArr, x, y, w, h); 1057 } 1058 1059 /* 1060 * Class: com_sun_prism_es2_GLContext 1061 * Method: nScissorTest 1062 * Signature: (JZIIII)V 1063 */ 1064 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nScissorTest 1065 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jboolean enable, 1066 jint x, jint y, jint w, jint h) { 1067 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1068 if (ctxInfo == NULL) { 1069 return; 1070 } 1071 1072 if (enable) { 1073 if (!ctxInfo->state.scissorEnabled) { 1074 glEnable(GL_SCISSOR_TEST); 1075 ctxInfo->state.scissorEnabled = JNI_TRUE; 1076 } 1077 glScissor(x, y, w, h); 1078 } else if (ctxInfo->state.scissorEnabled) { 1079 glDisable(GL_SCISSOR_TEST); 1080 ctxInfo->state.scissorEnabled = JNI_FALSE; 1081 } 1082 } 1083 1084 /* 1085 * Class: com_sun_prism_es2_GLContext 1086 * Method: nTexParamsMinMax 1087 * Signature: (I)V 1088 */ 1089 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nTexParamsMinMax 1090 (JNIEnv *env, jclass class, jint pname) { 1091 GLenum param = translatePrismToGL(pname); 1092 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, param); 1093 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, param); 1094 } 1095 1096 /* 1097 * Class: com_sun_prism_es2_GLContext 1098 * Method: nTexImage2D0 1099 * Signature: (IIIIIIIILjava/lang/Object;I)Z 1100 */ 1101 JNIEXPORT jboolean JNICALL Java_com_sun_prism_es2_GLContext_nTexImage2D0 1102 (JNIEnv *env, jclass class, jint target, jint level, jint internalFormat, 1103 jint width, jint height, jint border, jint format, jint type, 1104 jobject pixels, jint pixelsByteOffset) { 1105 GLvoid *ptr = NULL; 1106 GLenum err; 1107 1108 if (pixels != NULL) { 1109 ptr = (GLvoid *) (((char *) (*env)->GetDirectBufferAddress(env, pixels)) 1110 + pixelsByteOffset); 1111 } 1112 1113 glGetError(); 1114 glTexImage2D((GLenum) translatePrismToGL(target), (GLint) level, 1115 (GLint) translatePrismToGL(internalFormat), 1116 (GLsizei) width, (GLsizei) height, (GLint) border, 1117 (GLenum) translatePrismToGL(format), 1118 (GLenum) translatePrismToGL(type), (GLvoid *) ptr); 1119 err = glGetError(); 1120 1121 // printGLError(err); 1122 return err == GL_NO_ERROR ? JNI_TRUE : JNI_FALSE; 1123 } 1124 1125 /* 1126 * Class: com_sun_prism_es2_GLContext 1127 * Method: nTexImage2D1 1128 * Signature: (IIIIIIIILjava/lang/Object;I)Z 1129 */ 1130 JNIEXPORT jboolean JNICALL Java_com_sun_prism_es2_GLContext_nTexImage2D1 1131 (JNIEnv *env, jclass class, jint target, jint level, jint internalFormat, 1132 jint width, jint height, jint border, jint format, jint type, 1133 jobject pixels, jint pixelsByteOffset) { 1134 GLvoid *ptr = NULL; 1135 GLenum err; 1136 1137 if (pixels != NULL) { 1138 ptr = (GLvoid *) (((char *) (*env)->GetPrimitiveArrayCritical(env, pixels, NULL)) 1139 + pixelsByteOffset); 1140 } 1141 1142 glGetError(); 1143 glTexImage2D((GLenum) translatePrismToGL(target), (GLint) level, 1144 (GLint) translatePrismToGL(internalFormat), 1145 (GLsizei) width, (GLsizei) height, (GLint) border, 1146 (GLenum) translatePrismToGL(format), 1147 (GLenum) translatePrismToGL(type), (GLvoid *) ptr); 1148 1149 err = glGetError(); 1150 1151 if (pixels != NULL) { 1152 (*env)->ReleasePrimitiveArrayCritical(env, pixels, ptr, 0); 1153 } 1154 1155 // printGLError(err); 1156 return err == GL_NO_ERROR ? JNI_TRUE : JNI_FALSE; 1157 } 1158 1159 /* 1160 * Class: com_sun_prism_es2_GLContext 1161 * Method: nTexSubImage2D0 1162 * Signature: (IIIIIIIILjava/lang/Object;I)V 1163 */ 1164 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nTexSubImage2D0 1165 (JNIEnv *env, jclass class, jint target, jint level, 1166 jint xoffset, jint yoffset, jint width, jint height, jint format, 1167 jint type, jobject pixels, jint pixelsByteOffset) { 1168 GLvoid *ptr = NULL; 1169 if (pixels != NULL) { 1170 ptr = (GLvoid *) (((char *) (*env)->GetDirectBufferAddress(env, pixels)) 1171 + pixelsByteOffset); 1172 } 1173 glTexSubImage2D((GLenum) translatePrismToGL(target), (GLint) level, 1174 (GLint) xoffset, (GLint) yoffset, 1175 (GLsizei) width, (GLsizei) height, (GLenum) translatePrismToGL(format), 1176 (GLenum) translatePrismToGL(type), (GLvoid *) ptr); 1177 } 1178 1179 /* 1180 * Class: com_sun_prism_es2_GLContext 1181 * Method: nTexSubImage2D1 1182 * Signature: (IIIIIIIILjava/lang/Object;I)V 1183 */ 1184 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nTexSubImage2D1 1185 (JNIEnv *env, jclass class, jint target, jint level, 1186 jint xoffset, jint yoffset, jint width, jint height, jint format, 1187 jint type, jobject pixels, jint pixelsByteOffset) { 1188 GLvoid *ptr = NULL; 1189 if (pixels != NULL) { 1190 ptr = (GLvoid *) (((char *) (*env)->GetPrimitiveArrayCritical(env, pixels, NULL)) 1191 + pixelsByteOffset); 1192 } 1193 glTexSubImage2D((GLenum) translatePrismToGL(target), (GLint) level, 1194 (GLint) xoffset, (GLint) yoffset, 1195 (GLsizei) width, (GLsizei) height, (GLenum) translatePrismToGL(format), 1196 (GLenum) translatePrismToGL(type), (GLvoid *) ptr); 1197 if (pixels != NULL) { 1198 (*env)->ReleasePrimitiveArrayCritical(env, pixels, ptr, 0); 1199 } 1200 } 1201 1202 /* 1203 * Class: com_sun_prism_es2_GLContext 1204 * Method: nUpdateViewport 1205 * Signature: (JIIII)V 1206 */ 1207 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUpdateViewport 1208 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint x, jint y, 1209 jint w, jint h) { 1210 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1211 if (ctxInfo == NULL) { 1212 return; 1213 } 1214 1215 glViewport((GLint) x, (GLint) y, (GLsizei) w, (GLsizei) h); 1216 } 1217 1218 /* 1219 * Class: com_sun_prism_es2_GLContext 1220 * Method: nSetMSAA 1221 * Signature: (JZ)V 1222 */ 1223 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nSetMSAA 1224 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jboolean msaa) { 1225 #ifndef IS_EGL 1226 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1227 if (ctxInfo == NULL) { 1228 return; 1229 } 1230 1231 if (msaa) { 1232 glEnable(GL_MULTISAMPLE); 1233 } else { 1234 glDisable(GL_MULTISAMPLE); 1235 } 1236 #endif 1237 } 1238 1239 /* 1240 * Class: com_sun_prism_es2_GLContext 1241 * Method: nSetDepthTest 1242 * Signature: (JZ)V 1243 */ 1244 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nSetDepthTest 1245 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jboolean depthTest) { 1246 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1247 if (ctxInfo == NULL) { 1248 return; 1249 } 1250 1251 if (depthTest) { 1252 glEnable(GL_DEPTH_TEST); 1253 glDepthFunc(GL_LEQUAL); 1254 glDepthMask(GL_TRUE); 1255 ctxInfo->state.depthWritesEnabled = JNI_TRUE; 1256 #ifndef IS_EGL /* RT-25058 */ 1257 glEnable(GL_ALPHA_TEST); 1258 #ifndef ANDROID_NDK 1259 glAlphaFunc(GL_NOTEQUAL, 0.0); 1260 #endif 1261 #endif 1262 } else { 1263 glDisable(GL_DEPTH_TEST); 1264 glDepthMask(GL_FALSE); 1265 ctxInfo->state.depthWritesEnabled = JNI_FALSE; 1266 #ifndef IS_EGL 1267 glDisable(GL_ALPHA_TEST); 1268 #endif 1269 } 1270 } 1271 1272 /* 1273 * Class: com_sun_prism_es2_GLContext 1274 * Method: nUniform1f 1275 * Signature: (JIF)V 1276 */ 1277 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUniform1f 1278 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint location, jfloat v0) { 1279 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1280 if (ctxInfo == NULL) { 1281 return; 1282 } 1283 ctxInfo->glUniform1f(location, v0); 1284 } 1285 1286 /* 1287 * Class: com_sun_prism_es2_GLContext 1288 * Method: nUniform2f 1289 * Signature: (JIFF)V 1290 */ 1291 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUniform2f 1292 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint location, 1293 jfloat v0, jfloat v1) { 1294 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1295 if (ctxInfo == NULL) { 1296 return; 1297 } 1298 ctxInfo->glUniform2f(location, v0, v1); 1299 } 1300 1301 /* 1302 * Class: com_sun_prism_es2_GLContext 1303 * Method: nUniform3f 1304 * Signature: (JIFFF)V 1305 */ 1306 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUniform3f 1307 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint location, 1308 jfloat v0, jfloat v1, jfloat v2) { 1309 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1310 if (ctxInfo == NULL) { 1311 return; 1312 } 1313 ctxInfo->glUniform3f(location, v0, v1, v2); 1314 } 1315 1316 /* 1317 * Class: com_sun_prism_es2_GLContext 1318 * Method: nUniform4f 1319 * Signature: (JIFFFF)V 1320 */ 1321 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUniform4f 1322 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint location, 1323 jfloat v0, jfloat v1, jfloat v2, jfloat v3) { 1324 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1325 if (ctxInfo == NULL) { 1326 return; 1327 } 1328 ctxInfo->glUniform4f(location, v0, v1, v2, v3); 1329 } 1330 1331 /* 1332 * Class: com_sun_prism_es2_GLContext 1333 * Method: nUniform4fv0 1334 * Signature: (JIILjava/lang/Object;I)V 1335 */ 1336 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUniform4fv0 1337 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint location, jint count, 1338 jobject value, jint valueByteOffset) { 1339 GLfloat *_ptr2 = NULL; 1340 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1341 if ((env == NULL) || (ctxInfo == NULL)) { 1342 return; 1343 } 1344 if (value != NULL) { 1345 _ptr2 = (GLfloat *) (((char *) (*env)->GetDirectBufferAddress(env, value)) 1346 + valueByteOffset); 1347 } 1348 ctxInfo->glUniform4fv((GLint) location, (GLsizei) count, (GLfloat *) _ptr2); 1349 } 1350 1351 /* 1352 * Class: com_sun_prism_es2_GLContext 1353 * Method: nUniform4fv1 1354 * Signature: (JIILjava/lang/Object;I)V 1355 */ 1356 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUniform4fv1 1357 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint location, jint count, 1358 jobject value, jint valueByteOffset) { 1359 GLfloat *_ptr2 = NULL; 1360 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1361 if ((env == NULL) || (ctxInfo == NULL)) { 1362 return; 1363 } 1364 if (value != NULL) { 1365 _ptr2 = (GLfloat *) (((char *) (*env)->GetPrimitiveArrayCritical(env, value, NULL)) 1366 + valueByteOffset); 1367 } 1368 ctxInfo->glUniform4fv((GLint) location, (GLsizei) count, (GLfloat *) _ptr2); 1369 if (value != NULL) { 1370 (*env)->ReleasePrimitiveArrayCritical(env, value, _ptr2, 0); 1371 } 1372 } 1373 1374 /* 1375 * Class: com_sun_prism_es2_GLContext 1376 * Method: nUniform1i 1377 * Signature: (JII)V 1378 */ 1379 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUniform1i 1380 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint location, jint v0) { 1381 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1382 if ((ctxInfo == NULL) || (ctxInfo->glUniform1i == NULL)) { 1383 return; 1384 } 1385 ctxInfo->glUniform1i(location, v0); 1386 } 1387 1388 /* 1389 * Class: com_sun_prism_es2_GLContext 1390 * Method: nUniform2i 1391 * Signature: (JIII)V 1392 */ 1393 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUniform2i 1394 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint location, jint v0, jint v1) { 1395 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1396 if ((ctxInfo == NULL) || (ctxInfo->glUniform2i == NULL)) { 1397 return; 1398 } 1399 ctxInfo->glUniform2i(location, v0, v1); 1400 } 1401 1402 /* 1403 * Class: com_sun_prism_es2_GLContext 1404 * Method: nUniform3i 1405 * Signature: (JIIII)V 1406 */ 1407 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUniform3i 1408 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint location, 1409 jint v0, jint v1, jint v2) { 1410 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1411 if ((ctxInfo == NULL) || (ctxInfo->glUniform3i == NULL)) { 1412 return; 1413 } 1414 ctxInfo->glUniform3i(location, v0, v1, v2); 1415 } 1416 1417 /* 1418 * Class: com_sun_prism_es2_GLContext 1419 * Method: nUniform4i 1420 * Signature: (JIIIII)V 1421 */ 1422 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUniform4i 1423 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint location, 1424 jint v0, jint v1, jint v2, jint v3) { 1425 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1426 if ((ctxInfo == NULL) || (ctxInfo->glUniform4i == NULL)) { 1427 return; 1428 } 1429 ctxInfo->glUniform4i(location, v0, v1, v2, v3); 1430 } 1431 1432 /* 1433 * Class: com_sun_prism_es2_GLContext 1434 * Method: nUniform4iv0 1435 * Signature: (JIILjava/lang/Object;I)V 1436 */ 1437 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUniform4iv0 1438 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint location, jint count, 1439 jobject value, jint valueByteOffset) { 1440 GLint *_ptr2 = NULL; 1441 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1442 if ((ctxInfo == NULL) || (ctxInfo->glUniform4iv == NULL)) { 1443 return; 1444 } 1445 1446 if (value != NULL) { 1447 _ptr2 = (GLint *) (((char *) (*env)->GetDirectBufferAddress(env, value)) 1448 + valueByteOffset); 1449 } 1450 ctxInfo->glUniform4iv((GLint) location, (GLsizei) count, (GLint *) _ptr2); 1451 } 1452 1453 /* 1454 * Class: com_sun_prism_es2_GLContext 1455 * Method: nUniform4iv1 1456 * Signature: (JIILjava/lang/Object;I)V 1457 */ 1458 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUniform4iv1 1459 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint location, jint count, 1460 jobject value, jint valueByteOffset) { 1461 GLint *_ptr2 = NULL; 1462 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1463 if ((ctxInfo == NULL) || (ctxInfo->glUniform4iv == NULL)) { 1464 return; 1465 } 1466 1467 if (value != NULL) { 1468 _ptr2 = (GLint *) (((char *) (*env)->GetPrimitiveArrayCritical(env, value, NULL)) 1469 + valueByteOffset); 1470 } 1471 ctxInfo->glUniform4iv((GLint) location, (GLsizei) count, (GLint *) _ptr2); 1472 if (value != NULL) { 1473 (*env)->ReleasePrimitiveArrayCritical(env, value, _ptr2, 0); 1474 } 1475 } 1476 1477 /* 1478 * Class: com_sun_prism_es2_GLContext 1479 * Method: nUniformMatrix4fv0 1480 * Signature: (JIIZLjava/lang/Object;I)V 1481 */ 1482 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUniformMatrix4fv 1483 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint location, 1484 jboolean transpose, jfloatArray values) { 1485 GLfloat *_ptr = NULL; 1486 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1487 if ((ctxInfo == NULL) || (ctxInfo->glUniformMatrix4fv == NULL)) { 1488 return; 1489 } 1490 1491 if (values != NULL) { 1492 _ptr = (float *)(*env)->GetPrimitiveArrayCritical(env, values, NULL); 1493 } 1494 ctxInfo->glUniformMatrix4fv((GLint) location, 1, (GLboolean) transpose, _ptr); 1495 1496 if (_ptr) (*env)->ReleasePrimitiveArrayCritical(env, values, _ptr, JNI_ABORT); 1497 } 1498 1499 /* 1500 * Class: com_sun_prism_es2_GLContext 1501 * Method: nUpdateFilterState 1502 * Signature: (JIZ)V 1503 */ 1504 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUpdateFilterState 1505 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint texID, jboolean linearFiler) { 1506 int glFilter; 1507 1508 glFilter = linearFiler ? GL_LINEAR : GL_NEAREST; 1509 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glFilter); 1510 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glFilter); 1511 } 1512 1513 /* 1514 * Class: com_sun_prism_es2_GLContext 1515 * Method: nUpdateWrapState 1516 * Signature: (JII)V 1517 */ 1518 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUpdateWrapState 1519 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint texID, jint wrapMode) { 1520 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 1521 (GLenum) translatePrismToGL(wrapMode)); 1522 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 1523 (GLenum) translatePrismToGL(wrapMode)); 1524 } 1525 1526 /* 1527 * Class: com_sun_prism_es2_GLContext 1528 * Method: nUseProgram 1529 * Signature: (JI)V 1530 */ 1531 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nUseProgram 1532 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint pID) { 1533 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1534 if ((ctxInfo == NULL) || (ctxInfo->glUseProgram == NULL)) { 1535 return; 1536 } 1537 ctxInfo->glUseProgram(pID); 1538 } 1539 1540 /* 1541 * Class: com_sun_prism_es2_GLContext 1542 * Method: nDisableVertexAttributes 1543 * Signature: (J)V 1544 */ 1545 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nDisableVertexAttributes 1546 (JNIEnv *env, jclass class, jlong nativeCtxInfo) { 1547 int i; 1548 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1549 if ((ctxInfo == NULL) || (ctxInfo->glDisableVertexAttribArray == NULL)) { 1550 return; 1551 } 1552 1553 for (i = 0; i != 4; ++i) { 1554 ctxInfo->glDisableVertexAttribArray(i); 1555 } 1556 } 1557 1558 /* 1559 * Class: com_sun_prism_es2_GLContext 1560 * Method: nEnableVertexAttributes 1561 * Signature: (J)V 1562 */ 1563 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nEnableVertexAttributes 1564 (JNIEnv *env, jclass class, jlong nativeCtxInfo) { 1565 int i; 1566 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1567 if ((ctxInfo == NULL) || (ctxInfo->glEnableVertexAttribArray == NULL)) { 1568 return; 1569 } 1570 1571 for (i = 0; i != 4; ++i) { 1572 ctxInfo->glEnableVertexAttribArray(i); 1573 } 1574 } 1575 1576 #define FLOATS_PER_TC 2 1577 #define FLOATS_PER_VC 3 1578 #define FLOATS_PER_VERT (FLOATS_PER_TC * 2 + FLOATS_PER_VC) 1579 1580 #define coordStride (sizeof(float) * FLOATS_PER_VERT) 1581 #define colorStride 4 1582 1583 /* NOTE: the ctx->vbFloatData and ctx->vbByteData pointers must be updated 1584 * whenever calling glVertexAttribPointer. Failing to do this could leave 1585 * the pointers in an inconsistent state. 1586 */ 1587 1588 static void setVertexAttributePointers(ContextInfo *ctx, float *pFloat, char *pByte) { 1589 if (pFloat != ctx->vbFloatData) { 1590 ctx->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, coordStride, pFloat); 1591 ctx->glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, coordStride, 1592 pFloat + FLOATS_PER_VC); 1593 ctx->glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, coordStride, 1594 pFloat + FLOATS_PER_VC + FLOATS_PER_TC); 1595 ctx->vbFloatData = pFloat; 1596 } 1597 1598 if (pByte != ctx->vbByteData) { 1599 ctx->glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, colorStride, pByte); 1600 ctx->vbByteData = pByte; 1601 } 1602 } 1603 /* 1604 * Class: com_sun_prism_es2_GLContext 1605 * Method: nDrawIndexedQuads 1606 * Signature: (JI[F[B)V 1607 */ 1608 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nDrawIndexedQuads 1609 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint numVertices, 1610 jfloatArray dataf, jbyteArray datab) 1611 { 1612 float *pFloat; 1613 char *pByte; 1614 int numQuads = numVertices / 4; 1615 1616 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1617 if ((ctxInfo == NULL) || (ctxInfo->glVertexAttribPointer == NULL)) { 1618 return; 1619 } 1620 1621 pFloat = (float *)(*env)->GetPrimitiveArrayCritical(env, dataf, NULL); 1622 pByte = (char *)(*env)->GetPrimitiveArrayCritical(env, datab, NULL); 1623 1624 if (pFloat && pByte) { 1625 setVertexAttributePointers(ctxInfo, pFloat, pByte); 1626 glDrawElements(GL_TRIANGLES, numQuads * 2 * 3, GL_UNSIGNED_SHORT, 0); 1627 } 1628 1629 if (pByte) (*env)->ReleasePrimitiveArrayCritical(env, datab, pByte, JNI_ABORT); 1630 if (pFloat) (*env)->ReleasePrimitiveArrayCritical(env, dataf, pFloat, JNI_ABORT); 1631 } 1632 1633 /* 1634 * Class: com_sun_prism_es2_GLContext 1635 * Method: nDrawTriangleList 1636 * Signature: (JI[F[B)V 1637 */ 1638 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nDrawTriangleList 1639 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint numTriangles, 1640 jfloatArray dataf, jbyteArray datab) 1641 { 1642 float *pFloat; 1643 char *pByte; 1644 1645 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1646 if ((ctxInfo == NULL) || (ctxInfo->glVertexAttribPointer == NULL)) { 1647 return; 1648 } 1649 1650 pFloat = (float *)(*env)->GetPrimitiveArrayCritical(env, dataf, NULL); 1651 pByte = (char *)(*env)->GetPrimitiveArrayCritical(env, datab, NULL); 1652 1653 if (pFloat && pByte) { 1654 setVertexAttributePointers(ctxInfo, pFloat, pByte); 1655 glDrawArrays(GL_TRIANGLES, 0, numTriangles * 3); 1656 } 1657 1658 if (pByte) (*env)->ReleasePrimitiveArrayCritical(env, datab, pByte, JNI_ABORT); 1659 if (pFloat) (*env)->ReleasePrimitiveArrayCritical(env, dataf, pFloat, JNI_ABORT); 1660 } 1661 1662 /* 1663 * Class: com_sun_prism_es2_GLContext 1664 * Method: nCreateIndexBuffer16 1665 * Signature: (J[SI)I 1666 */ 1667 JNIEXPORT jint JNICALL Java_com_sun_prism_es2_GLContext_nCreateIndexBuffer16 1668 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jshortArray array, jint n) 1669 { 1670 GLuint id = 0; 1671 void *pData; 1672 1673 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1674 if ((ctxInfo == NULL) || (ctxInfo->glBindBuffer == NULL) || 1675 (ctxInfo->glBufferData == NULL) || (ctxInfo->glGenBuffers == NULL)) { 1676 return 0; 1677 } 1678 1679 pData = (*env)->GetPrimitiveArrayCritical(env, array, NULL); 1680 if (pData) { 1681 ctxInfo->glGenBuffers(1, &id); 1682 if (id) { 1683 ctxInfo->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); 1684 ctxInfo->glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(short) * n, pData, GL_STATIC_DRAW); 1685 } 1686 } 1687 if (pData) (*env)->ReleasePrimitiveArrayCritical(env, array, pData, JNI_ABORT); 1688 return id; 1689 } 1690 1691 /* 1692 * Class: com_sun_prism_es2_GLContext 1693 * Method: nSetIndexBuffer 1694 * Signature: (JI)V 1695 */ 1696 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nSetIndexBuffer 1697 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jint buffer) 1698 { 1699 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1700 if ((ctxInfo == NULL) || (ctxInfo->glBindBuffer == NULL)) { 1701 return; 1702 } 1703 ctxInfo->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); 1704 } 1705 1706 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nSetDeviceParametersFor2D 1707 (JNIEnv *env, jclass class, jlong nativeCtxInfo) 1708 { 1709 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1710 if ((ctxInfo == NULL) || (ctxInfo->glBindBuffer == NULL) || 1711 (ctxInfo->glBufferData == NULL) || 1712 (ctxInfo->glDisableVertexAttribArray == NULL)) { 1713 return; 1714 } 1715 1716 // Disable 3D states 1717 ctxInfo->glBindBuffer(GL_ARRAY_BUFFER, 0); 1718 ctxInfo->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 1719 ctxInfo->glDisableVertexAttribArray(VC_3D_INDEX); 1720 ctxInfo->glDisableVertexAttribArray(NC_3D_INDEX); 1721 ctxInfo->glDisableVertexAttribArray(TC_3D_INDEX); 1722 1723 ctxInfo->vbFloatData = NULL; 1724 ctxInfo->vbByteData = NULL; 1725 1726 glEnable(GL_BLEND); 1727 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 1728 1729 if (ctxInfo->state.scissorEnabled) { 1730 ctxInfo->state.scissorEnabled = JNI_FALSE; 1731 glDisable(GL_SCISSOR_TEST); 1732 } 1733 1734 glCullFace(GL_BACK); 1735 ctxInfo->state.cullMode = GL_BACK; 1736 glDisable(GL_CULL_FACE); 1737 ctxInfo->state.cullEnable = JNI_FALSE; 1738 #ifndef IS_EGL 1739 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 1740 #endif 1741 ctxInfo->state.fillMode = GL_FILL; 1742 } 1743 1744 /* 1745 * Class: com_sun_prism_es2_GLContext 1746 * Method: nSetDeviceParametersFor3D 1747 * Signature: (J)V 1748 */ 1749 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nSetDeviceParametersFor3D 1750 (JNIEnv *env, jclass class, jlong nativeCtxInfo) 1751 { 1752 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1753 if (ctxInfo == NULL) { 1754 return; 1755 } 1756 // Note: projViewTx and camPos are handled above in the Java layer 1757 1758 glDisable(GL_BLEND); 1759 glBlendFunc(GL_ONE, GL_ZERO); 1760 1761 if (ctxInfo->state.scissorEnabled) { 1762 ctxInfo->state.scissorEnabled = JNI_FALSE; 1763 glDisable(GL_SCISSOR_TEST); 1764 } 1765 1766 glEnable(GL_CULL_FACE); 1767 ctxInfo->state.cullEnable = GL_TRUE; 1768 glCullFace(GL_BACK); 1769 ctxInfo->state.cullMode = GL_BACK; 1770 glFrontFace(GL_CW); // set clockwise order as front-facing 1771 #ifndef IS_EGL 1772 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 1773 #endif 1774 ctxInfo->state.fillMode = GL_FILL; 1775 1776 } 1777 1778 /* 1779 * Class: com_sun_prism_es2_GLContext 1780 * Method: nCreateES2Mesh 1781 * Signature: (J)J 1782 */ 1783 JNIEXPORT jlong JNICALL Java_com_sun_prism_es2_GLContext_nCreateES2Mesh 1784 (JNIEnv *env, jclass class, jlong nativeCtxInfo) 1785 { 1786 MeshInfo *meshInfo = NULL; 1787 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1788 if ((ctxInfo == NULL) || (ctxInfo->glGenBuffers == NULL)) { 1789 return 0; 1790 } 1791 1792 /* allocate the structure */ 1793 meshInfo = (MeshInfo *) malloc(sizeof (MeshInfo)); 1794 if (meshInfo == NULL) { 1795 fprintf(stderr, "nCreateES2Mesh: Failed in malloc\n"); 1796 return 0; 1797 } 1798 1799 /* initialize the structure */ 1800 meshInfo->vboIDArray[MESH_VERTEXBUFFER] = 0; 1801 meshInfo->vboIDArray[MESH_INDEXBUFFER] = 0; 1802 meshInfo->indexBufferSize = 0; 1803 meshInfo->indexBufferType = 0; 1804 1805 /* create vbo ids */ 1806 ctxInfo->glGenBuffers(MESH_MAX_BUFFERS, (meshInfo->vboIDArray)); 1807 1808 return ptr_to_jlong(meshInfo); 1809 } 1810 1811 /* 1812 * Class: com_sun_prism_es2_GLContext 1813 * Method: nReleaseES2Mesh 1814 * Signature: (JJ)V 1815 */ 1816 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nReleaseES2Mesh 1817 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativeMeshInfo) 1818 { 1819 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1820 MeshInfo *meshInfo = (MeshInfo *) jlong_to_ptr(nativeMeshInfo); 1821 if ((ctxInfo == NULL) || (meshInfo == NULL) || 1822 (ctxInfo->glDeleteBuffers == NULL)) { 1823 return; 1824 } 1825 1826 // TODO: 3D - Native clean up. Need to determine do we have to free what 1827 // is held by ES2MeshInfo. 1828 ctxInfo->glDeleteBuffers(MESH_MAX_BUFFERS, (GLuint *) (meshInfo->vboIDArray)); 1829 free(meshInfo); 1830 } 1831 1832 /* 1833 * Class: com_sun_prism_es2_GLContext 1834 * Method: nBuildNativeGeometryShort 1835 * Signature: (JJ[FI[SI)Z 1836 */ 1837 JNIEXPORT jboolean JNICALL Java_com_sun_prism_es2_GLContext_nBuildNativeGeometryShort 1838 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativeMeshInfo, 1839 jfloatArray vbArray, jint vbSize, jshortArray ibArray, jint ibSize) 1840 { 1841 GLuint vertexBufferSize; 1842 GLuint indexBufferSize; 1843 GLushort *indexBuffer; 1844 GLfloat *vertexBuffer; 1845 jboolean status = JNI_TRUE; 1846 GLuint uvbSize; 1847 GLuint uibSize; 1848 1849 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1850 MeshInfo *meshInfo = (MeshInfo *) jlong_to_ptr(nativeMeshInfo); 1851 if ((ctxInfo == NULL) || (meshInfo == NULL) || 1852 (vbArray == NULL) || (ibArray == NULL) || 1853 (ctxInfo->glBindBuffer == NULL) || 1854 (ctxInfo->glBufferData == NULL) || 1855 (meshInfo->vboIDArray[MESH_VERTEXBUFFER] == 0)|| 1856 (meshInfo->vboIDArray[MESH_INDEXBUFFER] == 0) || 1857 vbSize < 0 || ibSize < 0) { 1858 return JNI_FALSE; 1859 } 1860 1861 vertexBufferSize = (*env)->GetArrayLength(env, vbArray); 1862 vertexBuffer = (GLfloat *) ((*env)->GetPrimitiveArrayCritical(env, vbArray, NULL)); 1863 1864 indexBufferSize = (*env)->GetArrayLength(env, ibArray); 1865 indexBuffer = (GLushort *) ((*env)->GetPrimitiveArrayCritical(env, ibArray, NULL)); 1866 1867 uvbSize = (GLuint) vbSize; 1868 uibSize = (GLuint) ibSize; 1869 if (vertexBuffer == NULL || indexBuffer == NULL 1870 || uvbSize > vertexBufferSize || uibSize > indexBufferSize) { 1871 status = JNI_FALSE; 1872 } 1873 1874 if (status) { 1875 // Initialize vertex buffer 1876 ctxInfo->glBindBuffer(GL_ARRAY_BUFFER, meshInfo->vboIDArray[MESH_VERTEXBUFFER]); 1877 ctxInfo->glBufferData(GL_ARRAY_BUFFER, uvbSize * sizeof (GLfloat), 1878 vertexBuffer, GL_STATIC_DRAW); 1879 1880 // Initialize index buffer 1881 ctxInfo->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshInfo->vboIDArray[MESH_INDEXBUFFER]); 1882 ctxInfo->glBufferData(GL_ELEMENT_ARRAY_BUFFER, uibSize * sizeof (GLushort), 1883 indexBuffer, GL_STATIC_DRAW); 1884 meshInfo->indexBufferSize = uibSize; 1885 meshInfo->indexBufferType = GL_UNSIGNED_SHORT; 1886 1887 // Unbind VBOs 1888 ctxInfo->glBindBuffer(GL_ARRAY_BUFFER, 0); 1889 ctxInfo->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 1890 } 1891 1892 if (indexBuffer) { 1893 (*env)->ReleasePrimitiveArrayCritical(env, ibArray, indexBuffer, JNI_ABORT); 1894 } 1895 if (vertexBuffer) { 1896 (*env)->ReleasePrimitiveArrayCritical(env, vbArray, vertexBuffer, JNI_ABORT); 1897 } 1898 1899 return status; 1900 } 1901 1902 /* 1903 * Class: com_sun_prism_es2_GLContext 1904 * Method: nBuildNativeGeometryInt 1905 * Signature: (JJ[FI[II)Z 1906 */ 1907 JNIEXPORT jboolean JNICALL Java_com_sun_prism_es2_GLContext_nBuildNativeGeometryInt 1908 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativeMeshInfo, 1909 jfloatArray vbArray, jint vbSize, jintArray ibArray, jint ibSize) 1910 { 1911 GLuint vertexBufferSize; 1912 GLuint indexBufferSize; 1913 GLuint *indexBuffer; 1914 GLfloat *vertexBuffer; 1915 jboolean status = JNI_TRUE; 1916 GLuint uvbSize; 1917 GLuint uibSize; 1918 1919 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1920 MeshInfo *meshInfo = (MeshInfo *) jlong_to_ptr(nativeMeshInfo); 1921 if ((ctxInfo == NULL) || (meshInfo == NULL) || 1922 (vbArray == NULL) || (ibArray == NULL) || 1923 (ctxInfo->glBindBuffer == NULL) || 1924 (ctxInfo->glBufferData == NULL) || 1925 (meshInfo->vboIDArray[MESH_VERTEXBUFFER] == 0)|| 1926 (meshInfo->vboIDArray[MESH_INDEXBUFFER] == 0) || 1927 vbSize < 0 || ibSize < 0) { 1928 return JNI_FALSE; 1929 } 1930 1931 vertexBufferSize = (*env)->GetArrayLength(env, vbArray); 1932 vertexBuffer = (GLfloat *) ((*env)->GetPrimitiveArrayCritical(env, vbArray, NULL)); 1933 1934 indexBufferSize = (*env)->GetArrayLength(env, ibArray); 1935 indexBuffer = (GLuint *) ((*env)->GetPrimitiveArrayCritical(env, ibArray, NULL)); 1936 1937 uvbSize = (GLuint) vbSize; 1938 uibSize = (GLuint) ibSize; 1939 if (vertexBuffer == NULL || indexBuffer == NULL 1940 || uvbSize > vertexBufferSize || uibSize > indexBufferSize) { 1941 status = JNI_FALSE; 1942 } 1943 1944 if (status) { 1945 // Initialize vertex buffer 1946 ctxInfo->glBindBuffer(GL_ARRAY_BUFFER, meshInfo->vboIDArray[MESH_VERTEXBUFFER]); 1947 ctxInfo->glBufferData(GL_ARRAY_BUFFER, uvbSize * sizeof (GLfloat), 1948 vertexBuffer, GL_STATIC_DRAW); 1949 1950 // Initialize index buffer 1951 ctxInfo->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshInfo->vboIDArray[MESH_INDEXBUFFER]); 1952 ctxInfo->glBufferData(GL_ELEMENT_ARRAY_BUFFER, uibSize * sizeof (GLuint), 1953 indexBuffer, GL_STATIC_DRAW); 1954 meshInfo->indexBufferSize = uibSize; 1955 meshInfo->indexBufferType = GL_UNSIGNED_INT; 1956 1957 // Unbind VBOs 1958 ctxInfo->glBindBuffer(GL_ARRAY_BUFFER, 0); 1959 ctxInfo->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 1960 } 1961 1962 if (indexBuffer) { 1963 (*env)->ReleasePrimitiveArrayCritical(env, ibArray, indexBuffer, JNI_ABORT); 1964 } 1965 if (vertexBuffer) { 1966 (*env)->ReleasePrimitiveArrayCritical(env, vbArray, vertexBuffer, JNI_ABORT); 1967 } 1968 1969 return status; 1970 } 1971 1972 /* 1973 * Class: com_sun_prism_es2_GLContext 1974 * Method: nCreateES2PhongMaterial 1975 * Signature: (J)J 1976 */ 1977 JNIEXPORT jlong JNICALL Java_com_sun_prism_es2_GLContext_nCreateES2PhongMaterial 1978 (JNIEnv *env, jclass class, jlong nativeCtxInfo) 1979 { 1980 PhongMaterialInfo *pmInfo = NULL; 1981 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 1982 if (ctxInfo == NULL) { 1983 return 0; 1984 } 1985 1986 /* allocate the structure */ 1987 pmInfo = (PhongMaterialInfo *) malloc(sizeof (PhongMaterialInfo)); 1988 if (pmInfo == NULL) { 1989 fprintf(stderr, "nCreateES2PhongMaterial: Failed in malloc\n"); 1990 return 0; 1991 } 1992 1993 /* initialize the structure */ 1994 pmInfo->diffuseColor[0] = 0.0f; 1995 pmInfo->diffuseColor[1] = 0.0f; 1996 pmInfo->diffuseColor[2] = 0.0f; 1997 pmInfo->diffuseColor[3] = 0.0f; 1998 pmInfo->maps[0] = 0; 1999 pmInfo->maps[1] = 0; 2000 pmInfo->maps[2] = 0; 2001 pmInfo->maps[3] = 0; 2002 return ptr_to_jlong(pmInfo); 2003 } 2004 2005 /* 2006 * Class: com_sun_prism_es2_GLContext 2007 * Method: nReleaseES2PhongMaterial 2008 * Signature: (JJ)V 2009 */ 2010 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nReleaseES2PhongMaterial 2011 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativePhongMaterialInfo) 2012 { 2013 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 2014 PhongMaterialInfo *pmInfo = (PhongMaterialInfo *) jlong_to_ptr(nativePhongMaterialInfo); 2015 if ((ctxInfo == NULL) || (pmInfo == NULL)) { 2016 return; 2017 } 2018 2019 // We shouldn't free maps (texture) here. This freeing should be handled higher 2020 // in the Java layer in dealing with Texture object. 2021 2022 free(pmInfo); 2023 } 2024 2025 /* 2026 * Class: com_sun_prism_es2_GLContext 2027 * Method: nSetSolidColor 2028 * Signature: (JJFFFF)V 2029 */ 2030 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nSetSolidColor 2031 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativePhongMaterialInfo, 2032 jfloat r, jfloat g, jfloat b, jfloat a) 2033 { 2034 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 2035 PhongMaterialInfo *pmInfo = (PhongMaterialInfo *) jlong_to_ptr(nativePhongMaterialInfo); 2036 if ((ctxInfo == NULL) || (pmInfo == NULL)) { 2037 return; 2038 } 2039 2040 pmInfo->diffuseColor[0] = r; 2041 pmInfo->diffuseColor[1] = g; 2042 pmInfo->diffuseColor[2] = b; 2043 pmInfo->diffuseColor[3] = a; 2044 } 2045 2046 /* 2047 * Class: com_sun_prism_es2_GLContext 2048 * Method: nSetMap 2049 * Signature: (JJII)V 2050 */ 2051 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nSetMap 2052 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativePhongMaterialInfo, 2053 jint mapType, jint texID) 2054 { 2055 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 2056 PhongMaterialInfo *pmInfo = (PhongMaterialInfo *) jlong_to_ptr(nativePhongMaterialInfo); 2057 if ((ctxInfo == NULL) || (pmInfo == NULL)) { 2058 return; 2059 } 2060 2061 // Must within the range of DIFFUSE, SPECULAR, BUMP, SELFILLUMINATION 2062 if ((mapType < 0) || (mapType > 3)) { 2063 fprintf(stderr, "nSetMap: mapType is out of bounds\n"); 2064 return; 2065 } 2066 2067 pmInfo->maps[mapType] = texID; 2068 } 2069 2070 /* 2071 * Class: com_sun_prism_es2_GLContext 2072 * Method: nCreateES2MeshView 2073 * Signature: (JJ)J 2074 */ 2075 JNIEXPORT jlong JNICALL Java_com_sun_prism_es2_GLContext_nCreateES2MeshView 2076 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativeMeshInfo) 2077 { 2078 MeshViewInfo *meshViewInfo; 2079 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 2080 MeshInfo *meshInfo = (MeshInfo *) jlong_to_ptr(nativeMeshInfo); 2081 if ((ctxInfo == NULL) || (meshInfo == NULL)) { 2082 return 0; 2083 } 2084 2085 /* allocate the structure */ 2086 meshViewInfo = (MeshViewInfo *) malloc(sizeof (MeshViewInfo)); 2087 if (meshViewInfo == NULL) { 2088 fprintf(stderr, "nCreateES2MeshView: Failed in malloc\n"); 2089 return 0; 2090 } 2091 2092 /* initialize the structure */ 2093 meshViewInfo->meshInfo = meshInfo; 2094 meshViewInfo->phongMaterialInfo = NULL; 2095 meshViewInfo->cullEnable = GL_TRUE; 2096 meshViewInfo->cullMode = GL_BACK; 2097 meshViewInfo->fillMode = GL_FILL; 2098 meshViewInfo->ambientLightColor[0] = 0; 2099 meshViewInfo->ambientLightColor[1] = 0; 2100 meshViewInfo->ambientLightColor[2] = 0; 2101 meshViewInfo->pointLightIndex = 0; 2102 meshViewInfo->pointLightColor[0] = 0; 2103 meshViewInfo->pointLightColor[1] = 0; 2104 meshViewInfo->pointLightColor[2] = 0; 2105 meshViewInfo->pointLightPosition[0] = 0; 2106 meshViewInfo->pointLightPosition[1] = 0; 2107 meshViewInfo->pointLightPosition[2] = 0; 2108 meshViewInfo->pointLightWeight = 0; 2109 2110 return ptr_to_jlong(meshViewInfo); 2111 } 2112 2113 /* 2114 * Class: com_sun_prism_es2_GLContext 2115 * Method: nReleaseES2MeshView 2116 * Signature: (JJ)V 2117 */ 2118 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nReleaseES2MeshView 2119 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativeMeshInfo) 2120 { 2121 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 2122 MeshViewInfo *mvInfo = (MeshViewInfo *) jlong_to_ptr(nativeMeshInfo); 2123 if ((ctxInfo == NULL) || (mvInfo == NULL)) { 2124 return; 2125 } 2126 2127 // TODO: 3D - Native clean up. Need to determine do we have to free what 2128 // is held by ES2MeshViewInfo. 2129 free(mvInfo); 2130 } 2131 2132 void setCullMode(ContextInfo *ctxInfo, MeshViewInfo *mvInfo) { 2133 if (mvInfo->cullEnable != ctxInfo->state.cullEnable) { 2134 if (mvInfo->cullEnable) { 2135 glEnable(GL_CULL_FACE); 2136 } else { 2137 glDisable(GL_CULL_FACE); 2138 } 2139 ctxInfo->state.cullEnable = mvInfo->cullEnable; 2140 } 2141 2142 if (mvInfo->cullMode != ctxInfo->state.cullMode) { 2143 glCullFace(mvInfo->cullMode); 2144 ctxInfo->state.cullMode = mvInfo->cullMode; 2145 } 2146 } 2147 2148 /* 2149 * Class: com_sun_prism_es2_GLContext 2150 * Method: nSetCullingMode 2151 * Signature: (JJI)V 2152 */ 2153 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nSetCullingMode 2154 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativeMeshViewInfo, 2155 jint cullMode) 2156 { 2157 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 2158 MeshViewInfo *meshViewInfo = (MeshViewInfo *) jlong_to_ptr(nativeMeshViewInfo); 2159 if ((ctxInfo == NULL) || (meshViewInfo == NULL)) { 2160 return; 2161 } 2162 switch (cullMode) { 2163 case com_sun_prism_es2_GLContext_GL_BACK: 2164 meshViewInfo->cullEnable = GL_TRUE; 2165 meshViewInfo->cullMode = GL_BACK; 2166 break; 2167 case com_sun_prism_es2_GLContext_GL_FRONT: 2168 meshViewInfo->cullEnable = GL_TRUE; 2169 meshViewInfo->cullMode = GL_FRONT; 2170 break; 2171 case com_sun_prism_es2_GLContext_GL_NONE: 2172 meshViewInfo->cullEnable = GL_FALSE; 2173 meshViewInfo->cullMode = GL_BACK; 2174 break; 2175 } 2176 } 2177 2178 /* 2179 * Class: com_sun_prism_es2_GLContext 2180 * Method: nSetMaterial 2181 * Signature: (JJJ)V 2182 */ 2183 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nSetMaterial 2184 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativeMeshViewInfo, 2185 jlong nativePhongMaterialInfo) 2186 { 2187 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 2188 MeshViewInfo *mvInfo = (MeshViewInfo *) jlong_to_ptr(nativeMeshViewInfo); 2189 PhongMaterialInfo *pmInfo = (PhongMaterialInfo *) jlong_to_ptr(nativePhongMaterialInfo); 2190 if ((ctxInfo == NULL) || (mvInfo == NULL) || (pmInfo == NULL)) { 2191 return; 2192 } 2193 mvInfo->phongMaterialInfo = pmInfo; 2194 } 2195 2196 void setPolyonMode(ContextInfo *ctxInfo, MeshViewInfo *mvInfo) { 2197 #ifndef IS_EGL 2198 if (mvInfo->fillMode != ctxInfo->state.fillMode) { 2199 glPolygonMode(GL_FRONT_AND_BACK, mvInfo->fillMode); 2200 ctxInfo->state.fillMode = mvInfo->fillMode; 2201 } 2202 #endif 2203 } 2204 2205 /* 2206 * Class: com_sun_prism_es2_GLContext 2207 * Method: nSetWireframe 2208 * Signature: (JJZ)V 2209 */ 2210 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nSetWireframe 2211 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativeMeshViewInfo, 2212 jboolean wireframe) 2213 { 2214 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 2215 MeshViewInfo *meshViewInfo = (MeshViewInfo *) jlong_to_ptr(nativeMeshViewInfo); 2216 if ((ctxInfo == NULL) || (meshViewInfo == NULL)) { 2217 return; 2218 } 2219 if (wireframe) { 2220 meshViewInfo->fillMode = GL_LINE; 2221 } else { 2222 meshViewInfo->fillMode = GL_FILL; 2223 } 2224 } 2225 2226 /* 2227 * Class: com_sun_prism_es2_GLContext 2228 * Method: nSetAmbientLight 2229 * Signature: (JJFFF)V 2230 */ 2231 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nSetAmbientLight 2232 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativeMeshViewInfo, 2233 jfloat r, jfloat g, jfloat b) 2234 { 2235 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 2236 MeshViewInfo *meshViewInfo = (MeshViewInfo *) jlong_to_ptr(nativeMeshViewInfo); 2237 if ((ctxInfo == NULL) || (meshViewInfo == NULL)) { 2238 return; 2239 } 2240 meshViewInfo->ambientLightColor[0] = r; 2241 meshViewInfo->ambientLightColor[1] = g; 2242 meshViewInfo->ambientLightColor[2] = b; 2243 } 2244 2245 /* 2246 * Class: com_sun_prism_es2_GLContext 2247 * Method: nSetPointLight 2248 * Signature: (JJIFFFFFFF)V 2249 */ 2250 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nSetPointLight 2251 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativeMeshViewInfo, 2252 jint index, jfloat x, jfloat y, jfloat z, jfloat r, jfloat g, jfloat b, jfloat w) 2253 { 2254 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 2255 MeshViewInfo *meshViewInfo = (MeshViewInfo *) jlong_to_ptr(nativeMeshViewInfo); 2256 // NOTE: We only support up to 3 point lights at the present 2257 if ((ctxInfo == NULL) || (meshViewInfo == NULL) || (index < 0) || (index > 2)) { 2258 return; 2259 } 2260 meshViewInfo->pointLightIndex = index; 2261 meshViewInfo->pointLightPosition[0] = x; 2262 meshViewInfo->pointLightPosition[1] = y; 2263 meshViewInfo->pointLightPosition[2] = z; 2264 meshViewInfo->pointLightColor[0] = r; 2265 meshViewInfo->pointLightColor[1] = g; 2266 meshViewInfo->pointLightColor[2] = b; 2267 meshViewInfo->pointLightWeight = w; 2268 } 2269 2270 /* 2271 * Class: com_sun_prism_es2_GLContext 2272 * Method: nRenderMeshView 2273 * Signature: (JJ)V 2274 */ 2275 JNIEXPORT void JNICALL Java_com_sun_prism_es2_GLContext_nRenderMeshView 2276 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativeMeshViewInfo) 2277 { 2278 GLuint offset = 0; 2279 MeshInfo *mInfo; 2280 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 2281 MeshViewInfo *mvInfo = (MeshViewInfo *) jlong_to_ptr(nativeMeshViewInfo); 2282 if ((ctxInfo == NULL) || (mvInfo == NULL) || 2283 (ctxInfo->glBindBuffer == NULL) || 2284 (ctxInfo->glBufferData == NULL) || 2285 (ctxInfo->glDisableVertexAttribArray == NULL) || 2286 (ctxInfo->glEnableVertexAttribArray == NULL) || 2287 (ctxInfo->glVertexAttribPointer == NULL)) { 2288 return; 2289 } 2290 2291 if ((mvInfo->phongMaterialInfo == NULL) || (mvInfo->meshInfo == NULL)) { 2292 return; 2293 } 2294 2295 setCullMode(ctxInfo, mvInfo); 2296 setPolyonMode(ctxInfo, mvInfo); 2297 2298 // Draw triangles ... 2299 mInfo = mvInfo->meshInfo; 2300 ctxInfo->glBindBuffer(GL_ARRAY_BUFFER, mInfo->vboIDArray[MESH_VERTEXBUFFER]); 2301 ctxInfo->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mInfo->vboIDArray[MESH_INDEXBUFFER]); 2302 2303 ctxInfo->glEnableVertexAttribArray(VC_3D_INDEX); 2304 ctxInfo->glEnableVertexAttribArray(TC_3D_INDEX); 2305 ctxInfo->glEnableVertexAttribArray(NC_3D_INDEX); 2306 2307 ctxInfo->glVertexAttribPointer(VC_3D_INDEX, VC_3D_SIZE, GL_FLOAT, GL_FALSE, 2308 VERT_3D_STRIDE, (const void*) offset); 2309 offset += VC_3D_SIZE * sizeof(GLfloat); 2310 ctxInfo->glVertexAttribPointer(TC_3D_INDEX, TC_3D_SIZE, GL_FLOAT, GL_FALSE, 2311 VERT_3D_STRIDE, (const void*) offset); 2312 offset += TC_3D_SIZE * sizeof(GLfloat); 2313 ctxInfo->glVertexAttribPointer(NC_3D_INDEX, NC_3D_SIZE, GL_FLOAT, GL_FALSE, 2314 VERT_3D_STRIDE, (const void*) offset); 2315 2316 glDrawElements(GL_TRIANGLES, mvInfo->meshInfo->indexBufferSize, 2317 mvInfo->meshInfo->indexBufferType, 0); 2318 2319 // Reset states 2320 ctxInfo->glDisableVertexAttribArray(VC_3D_INDEX); 2321 ctxInfo->glDisableVertexAttribArray(NC_3D_INDEX); 2322 ctxInfo->glDisableVertexAttribArray(TC_3D_INDEX); 2323 ctxInfo->glBindBuffer(GL_ARRAY_BUFFER, 0); 2324 ctxInfo->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 2325 } 2326