07 Apr 2014, 00:33
Generic-user-small

Adam Gravois (3 posts)

Hi, We are enjoying the book, but having a bit of frustration with this issue. On Chapter 15, the avatar isn’t appearing, and we’re getting a whole lot of these warnings in the JavaScript console: ‘WebGL: INVALID_OPERATION: getUniformLocation: program not linked Three.js:33116’ ‘WebGL: INVALID_OPERATION: getAttribLocation: program not linked Three.js:33109’ etc.

We’re running Chrome on OSX 10.8.5, confirmed that WebGL works via get.webgl.org, and would appreciate any debugging tips.

07 Apr 2014, 01:30
Chris_strom_headshot_200_pragsmall

Chris Strom (78 posts)

The first thing I’d try is to quit Chrome (all open windows, all tabs) and restart. Every now and then the WebGL engine can simply come unhinged. This shouldn’t happen very often with more recent versions of Chrome, but I have found that I could produce similar errors when making a lot of changes to WebGL code.

If that doesn’t solve it, the next step is to switch the WebGlRenderer to a CanvasRenderer. That is change this like:

  var renderer = new THREE.WebGLRenderer();

To be:

  var renderer = new THREE.CanvasRenderer();

The CanvasRenderer in this game has two problems: the ground probably will not be visible and the avatar’s image might have an ugly rectangular background.

The ground can kinda/sorta work with the CanvasRenderer if you change the PlaneGeometry to:

    ground = new Physijs.PlaneMesh(
      new THREE.PlaneGeometry(1e4, 5e5, 100, 100),
      new THREE.MeshBasicMaterial({color: 0x7CFC00})
    );

It won’t look exactly like in the book, but it should be good enough.

If the avatar has a rectangular background, there is not much to be done, but this is the time to poke around to see if anything else might be broken in the rest of the code. If nothing else, you won’t see the WebGL errors anymore, so the real problem may be more obvious.

If none of that helps, paste the code in here (or share a link from the ICE menu) and I’d be happy to have a look.

Sorry for the trouble. Good luck!

-Chris

08 Apr 2014, 02:54
Generic-user-small

Adam Gravois (3 posts)

Thanks for the tips! My son was amazed you replied so quickly. Tried restarting; no improvement. Tried CanvasRenderer, no improvement either. Then I noticed that the ground doesn’t draw; not in WebGL, nor in Canvas with the alternate ground code you provided. (Although that doesn’t throw any errors that we can see.)

it’s almost like the camera isn’t looking in the right place.

Below is the code as far as p137. We’ve combed it for typos but blind spots do happen. You are a champ for responding to your readers’ questions.

<body></body>
<script src="http://gamingJS.com/Three.js"></script>
<script src="http://gamingJS.com/physi.js"></script>
<script src="http://gamingJS.com/Scoreboard.js"></script>
<script src="http://gamingJS.com/ChromeFixes.js"></script>
<script>
//This is where stuff in our game will happen:
Physijs.scripts.ammo = 'http://gamingJS.com/ammo.js';
Physijs.scripts.worker = 'http://gamingJS.com/physijs_worker.js';

var scene = new Physijs.Scene({ fixedTimeStep: 2 / 60 });
scene.setGravity(new THREE.Vector3( 0, -100, 0 ));

//This is what sees the stuff:
var aspect_ratio = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspect_ratio, 1, 10000);
camera.position.z = 200;
camera.position.y = 100;
scene.add(camera);

//This will draw what the camera sees on the screen:
var renderer = new THREE.CanvasRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

  //******** START CODING ON THE NEXT LINE********
  
var ground = addGround();
var avatar = addAvatar();
//var scoreboard = addScoreboard();
  //animate();
  //gameStep();
  
function addGround() {
  document.body.style.backgroundColor = '#87CEEB';
   ground = new Physijs.PlaneMesh(
     new THREE.PlaneGeometry(1e4, 5e5, 100, 100),
     new THREE.MeshBasicMaterial({color: 0x7CFC00})
  );
  ground.rotation.x = -Math.PI/2;
  scene.add(ground);
  return ground;
}

function addAvatar() {
  avatar = new Physijs.BoxMesh(
    new THREE.CubeGeometry(40, 50, 1),
    new THREE.MeshBasicMaterial({color: 0x800080})
  );
  avatar.position.set(-50, 50, 0);
  scene.add(avatar);
    
  avatar.setAngularFactor(new THREE.Vector3( 0, 0, 0 )); // no rotation
  avatar.setLinearFactor(new THREE.Vector3( 1, 1, 0 )); //  only move on X/Y axis
  avatar.setLinearVelocity(new THREE.Vector3(0, 150, 0));
  avatar.addEventListener('collision', function(object) {
    if (object.is_fruit) {
      scoreboard.addPoints(10);
      avatar.setLinearVelocity(new THREE.Vector3(0, 50, 0));
      scene.remove(object);
    }
    if (object == ground) {
      game_over = true;
      scoreboard.message("Game Over!");
    }
  });
  return avatar;
}

</script>
08 Apr 2014, 13:22
Chris_strom_headshot_200_pragsmall

Chris Strom (78 posts)

I think you’re missing just one line at the bottom (above the closing </script> tag):

renderer.render(scene, camera);

That should have been in the project when you created it from the “3D starter project” template. My guess is that you deleted it because I wasn’t clear in the book that it needed to stay (until the animate() function gets defined).

I’ll make a note that this ought to be explicitly stated in the next version of the book.

For now, if you add that line, it should work. It should even work if you switch back to the WebGLRendeder.

Let me know if it’s still not working for any reason or if you have any other questions!

10 Apr 2014, 02:09
Generic-user-small

Adam Gravois (3 posts)

Excellent, thanks! Yes, it would’ve been a long time before we caught that.

  You must be logged in to comment