27
27
public class ModelRenderer implements GLSurfaceView .Renderer {
28
28
29
29
private final static String TAG = ModelRenderer .class .getName ();
30
+ /**
31
+ * Add 0.5f to the alpha component to the global shader so we can see through the skin
32
+ */
33
+ private static final float [] BLENDING_FORCED_MASK_COLOR = {1.0f , 1.0f , 1.0f , 0.5f };
30
34
// frustrum - nearest pixel
31
35
private static final float near = 1f ;
32
36
// frustrum - fartest pixel
@@ -67,7 +71,8 @@ public class ModelRenderer implements GLSurfaceView.Renderer {
67
71
private final float [] modelViewMatrix = new float [16 ];
68
72
private final float [] projectionMatrix = new float [16 ];
69
73
private final float [] viewProjectionMatrix = new float [16 ];
70
- private final float [] lightPosInEyeSpace = new float [4 ];
74
+ private final float [] lightPosInWorldSpace = new float [4 ];
75
+ private final float [] cameraPosInWorldSpace = new float [3 ];
71
76
72
77
// 3D stereoscopic matrix (left & right camera)
73
78
private final float [] viewMatrixLeft = new float [16 ];
@@ -169,10 +174,14 @@ public void onDrawFrame(GL10 unused) {
169
174
return ;
170
175
}
171
176
177
+ float [] colorMask = null ;
172
178
if (scene .isBlendingEnabled ()) {
173
179
// Enable blending for combining colors when there is transparency
174
180
GLES20 .glEnable (GLES20 .GL_BLEND );
175
181
GLES20 .glBlendFunc (GLES20 .GL_ONE , GLES20 .GL_ONE_MINUS_SRC_ALPHA );
182
+ if (scene .isBlendingForced ()){
183
+ colorMask = BLENDING_FORCED_MASK_COLOR ;
184
+ }
176
185
} else {
177
186
GLES20 .glDisable (GLES20 .GL_BLEND );
178
187
}
@@ -182,6 +191,9 @@ public void onDrawFrame(GL10 unused) {
182
191
183
192
// recalculate mvp matrix according to where we are looking at now
184
193
Camera camera = scene .getCamera ();
194
+ cameraPosInWorldSpace [0 ]=camera .xPos ;
195
+ cameraPosInWorldSpace [1 ]=camera .yPos ;
196
+ cameraPosInWorldSpace [2 ]=camera .zPos ;
185
197
if (camera .hasChanged ()) {
186
198
// INFO: Set the camera position (View matrix)
187
199
// The camera has 3 vectors (the position, the vector where we are looking at, and the up position (sky)
@@ -228,19 +240,19 @@ public void onDrawFrame(GL10 unused) {
228
240
229
241
230
242
if (!scene .isStereoscopic ()) {
231
- this .onDrawFrame (viewMatrix , projectionMatrix , viewProjectionMatrix , lightPosInEyeSpace , null );
243
+ this .onDrawFrame (viewMatrix , projectionMatrix , viewProjectionMatrix , lightPosInWorldSpace , colorMask , cameraPosInWorldSpace );
232
244
return ;
233
245
}
234
246
235
247
236
248
if (scene .isAnaglyph ()) {
237
249
// INFO: switch because blending algorithm doesn't mix colors
238
250
if (anaglyphSwitch ) {
239
- this .onDrawFrame (viewMatrixLeft , projectionMatrixLeft , viewProjectionMatrixLeft , lightPosInEyeSpace ,
240
- COLOR_RED );
251
+ this .onDrawFrame (viewMatrixLeft , projectionMatrixLeft , viewProjectionMatrixLeft , lightPosInWorldSpace ,
252
+ COLOR_RED , cameraPosInWorldSpace );
241
253
} else {
242
- this .onDrawFrame (viewMatrixRight , projectionMatrixRight , viewProjectionMatrixRight , lightPosInEyeSpace ,
243
- COLOR_BLUE );
254
+ this .onDrawFrame (viewMatrixRight , projectionMatrixRight , viewProjectionMatrixRight , lightPosInWorldSpace ,
255
+ COLOR_BLUE , cameraPosInWorldSpace );
244
256
}
245
257
anaglyphSwitch = !anaglyphSwitch ;
246
258
return ;
@@ -251,14 +263,14 @@ public void onDrawFrame(GL10 unused) {
251
263
// draw left eye image
252
264
GLES20 .glViewport (0 , 0 , width / 2 , height );
253
265
GLES20 .glScissor (0 , 0 , width / 2 , height );
254
- this .onDrawFrame (viewMatrixLeft , projectionMatrixLeft , viewProjectionMatrixLeft , lightPosInEyeSpace ,
255
- null );
266
+ this .onDrawFrame (viewMatrixLeft , projectionMatrixLeft , viewProjectionMatrixLeft , lightPosInWorldSpace ,
267
+ null , cameraPosInWorldSpace );
256
268
257
269
// draw right eye image
258
270
GLES20 .glViewport (width / 2 , 0 , width / 2 , height );
259
271
GLES20 .glScissor (width / 2 , 0 , width / 2 , height );
260
- this .onDrawFrame (viewMatrixRight , projectionMatrixRight , viewProjectionMatrixRight , lightPosInEyeSpace ,
261
- null );
272
+ this .onDrawFrame (viewMatrixRight , projectionMatrixRight , viewProjectionMatrixRight , lightPosInWorldSpace ,
273
+ null , cameraPosInWorldSpace );
262
274
}
263
275
}catch (Exception ex ){
264
276
Log .e ("ModelRenderer" , "Fatal exception: " +ex .getMessage (), ex );
@@ -267,7 +279,7 @@ public void onDrawFrame(GL10 unused) {
267
279
}
268
280
269
281
private void onDrawFrame (float [] viewMatrix , float [] projectionMatrix , float [] viewProjectionMatrix ,
270
- float [] lightPosInEyeSpace , float [] colorMask ) {
282
+ float [] lightPosInWorldSpace , float [] colorMask , float [] cameraPosInWorldSpace ) {
271
283
272
284
273
285
SceneLoader scene = main .getModelActivity ().getScene ();
@@ -279,31 +291,32 @@ private void onDrawFrame(float[] viewMatrix, float[] projectionMatrix, float[] v
279
291
280
292
// Calculate position of the light in world space to support lighting
281
293
if (scene .isRotatingLight ()) {
282
- Matrix .multiplyMV (lightPosInEyeSpace , 0 , scene .getLightBulb ().getModelMatrix (), 0 , scene .getLightPosition (), 0 );
294
+ Matrix .multiplyMV (lightPosInWorldSpace , 0 , scene .getLightBulb ().getModelMatrix (), 0 , scene .getLightPosition (), 0 );
283
295
// Draw a point that represents the light bulb
284
- lightBulbDrawer .draw (scene .getLightBulb (), projectionMatrix , viewMatrix , -1 , lightPosInEyeSpace ,
285
- colorMask );
296
+ lightBulbDrawer .draw (scene .getLightBulb (), projectionMatrix , viewMatrix , -1 , lightPosInWorldSpace ,
297
+ colorMask , cameraPosInWorldSpace );
286
298
} else {
287
- // FIXME: memory leak
288
- lightPosInEyeSpace = new float []{scene .getCamera ().xPos , scene .getCamera ().yPos ,
289
- scene .getCamera ().zPos , 0f };
299
+ lightPosInWorldSpace [0 ] = scene .getCamera ().xPos ;
300
+ lightPosInWorldSpace [1 ] = scene .getCamera ().yPos ;
301
+ lightPosInWorldSpace [2 ] = scene .getCamera ().zPos ;
302
+ lightPosInWorldSpace [3 ] = 0 ;
290
303
}
291
304
292
305
// FIXME: memory leak
293
306
if (scene .isDrawNormals ()) {
294
- lightBulbDrawer .draw (Object3DBuilder .buildLine (new float []{lightPosInEyeSpace [0 ],
295
- lightPosInEyeSpace [1 ], lightPosInEyeSpace [2 ], 0 , 0 , 0 }), projectionMatrix ,
307
+ lightBulbDrawer .draw (Object3DBuilder .buildLine (new float []{lightPosInWorldSpace [0 ],
308
+ lightPosInWorldSpace [1 ], lightPosInWorldSpace [2 ], 0 , 0 , 0 }), projectionMatrix ,
296
309
viewMatrix , -1 ,
297
- lightPosInEyeSpace ,
298
- colorMask );
310
+ lightPosInWorldSpace ,
311
+ colorMask , cameraPosInWorldSpace );
299
312
}
300
313
}
301
314
302
315
// draw axis
303
316
if (scene .isDrawAxis ()){
304
317
Object3D basicDrawer = drawer .getPointDrawer ();
305
318
basicDrawer .draw (axis , projectionMatrix , viewMatrix , axis .getDrawMode (), axis
306
- .getDrawSize (),-1 , lightPosInEyeSpace , colorMask );
319
+ .getDrawSize (),-1 , lightPosInWorldSpace , colorMask , cameraPosInWorldSpace );
307
320
}
308
321
309
322
@@ -337,12 +350,12 @@ private void onDrawFrame(float[] viewMatrix, float[] projectionMatrix, float[] v
337
350
// load model texture
338
351
Integer textureId = textures .get (objData .getTextureData ());
339
352
if (textureId == null && objData .getTextureData () != null ) {
340
- // Log.i("ModelRenderer","Loading texture '"+objData.getTextureFile()+"'...");
353
+ Log .i ("ModelRenderer" ,"Loading texture '" +objData .getTextureFile ()+"'..." );
341
354
ByteArrayInputStream textureIs = new ByteArrayInputStream (objData .getTextureData ());
342
355
textureId = GLUtil .loadTexture (textureIs );
343
356
textureIs .close ();
344
357
textures .put (objData .getTextureData (), textureId );
345
- // Log.i("GLUtil", "Loaded texture ok" );
358
+ Log .i ("GLUtil" , "Loaded texture ok. id: " + textureId );
346
359
}
347
360
if (textureId == null ){
348
361
textureId = -1 ;
@@ -351,7 +364,7 @@ private void onDrawFrame(float[] viewMatrix, float[] projectionMatrix, float[] v
351
364
// draw points
352
365
if (objData .getDrawMode () == GLES20 .GL_POINTS ){
353
366
Object3D basicDrawer = drawer .getPointDrawer ();
354
- basicDrawer .draw (objData , projectionMatrix , viewMatrix , GLES20 .GL_POINTS ,lightPosInEyeSpace );
367
+ basicDrawer .draw (objData , projectionMatrix , viewMatrix , GLES20 .GL_POINTS , lightPosInWorldSpace , cameraPosInWorldSpace );
355
368
}
356
369
357
370
// draw wireframe
@@ -368,8 +381,8 @@ else if (scene.isDrawWireframe() && objData.getDrawMode() != GLES20.GL_POINTS
368
381
wireframes .put (objData , wireframe );
369
382
}
370
383
drawerObject .draw (wireframe , projectionMatrix , viewMatrix , wireframe .getDrawMode (),
371
- wireframe .getDrawSize (), textureId , lightPosInEyeSpace ,
372
- colorMask );
384
+ wireframe .getDrawSize (), textureId , lightPosInWorldSpace ,
385
+ colorMask , cameraPosInWorldSpace );
373
386
animator .update (wireframe , scene .isShowBindPose ());
374
387
}catch (Error e ){
375
388
Log .e ("ModelRenderer" ,e .getMessage (),e );
@@ -380,7 +393,7 @@ else if (scene.isDrawWireframe() && objData.getDrawMode() != GLES20.GL_POINTS
380
393
else if (scene .isDrawPoints () || objData .getFaces () == null || !objData .getFaces ().loaded ()){
381
394
drawerObject .draw (objData , projectionMatrix , viewMatrix
382
395
, GLES20 .GL_POINTS , objData .getDrawSize (),
383
- textureId , lightPosInEyeSpace , colorMask );
396
+ textureId , lightPosInWorldSpace , colorMask , cameraPosInWorldSpace );
384
397
}
385
398
386
399
// draw skeleton
@@ -394,13 +407,13 @@ else if (scene.isDrawSkeleton() && objData instanceof AnimatedModel && ((Animate
394
407
animator .update (skeleton , scene .isShowBindPose ());
395
408
drawerObject = drawer .getDrawer (skeleton , false , scene .isDrawLighting (), scene
396
409
.isDoAnimation (), scene .isDrawColors ());
397
- drawerObject .draw (skeleton , projectionMatrix , viewMatrix ,-1 , lightPosInEyeSpace , colorMask );
410
+ drawerObject .draw (skeleton , projectionMatrix , viewMatrix ,-1 , lightPosInWorldSpace , colorMask , cameraPosInWorldSpace );
398
411
}
399
412
400
413
// draw solids
401
414
else {
402
415
drawerObject .draw (objData , projectionMatrix , viewMatrix ,
403
- textureId , lightPosInEyeSpace , colorMask );
416
+ textureId , lightPosInWorldSpace , colorMask , cameraPosInWorldSpace );
404
417
}
405
418
406
419
// Draw bounding box
@@ -412,7 +425,7 @@ else if (scene.isDrawSkeleton() && objData instanceof AnimatedModel && ((Animate
412
425
}
413
426
Object3D boundingBoxDrawer = drawer .getBoundingBoxDrawer ();
414
427
boundingBoxDrawer .draw (boundingBoxData , projectionMatrix , viewMatrix , -1 ,
415
- lightPosInEyeSpace , colorMask );
428
+ lightPosInWorldSpace , colorMask , cameraPosInWorldSpace );
416
429
}
417
430
418
431
// Draw normals
@@ -429,7 +442,8 @@ else if (scene.isDrawSkeleton() && objData instanceof AnimatedModel && ((Animate
429
442
Object3D normalsDrawer = drawer .getDrawer (normalData ,false ,false ,scene .isDoAnimation (),
430
443
false );
431
444
animator .update (normalData , scene .isShowBindPose ());
432
- normalsDrawer .draw (normalData , projectionMatrix , viewMatrix , -1 , null );
445
+ normalsDrawer .draw (normalData , projectionMatrix , viewMatrix , -1 , null ,
446
+ lightPosInWorldSpace , cameraPosInWorldSpace );
433
447
}
434
448
}
435
449
0 commit comments