Bitmap rendering is not always better

I’m still exploring 3d rendering in flash, and I’ve discovered that bitmap rendering is not always better. I was hoping using triangles to render textures would be faster than using the drawing API, but at least in the following example, it is almost twice as slow, and has more glitches.

Perhaps someone can point out an error I’ve made in the methods. Attached is an example, and here is the code used to render it, sorry for the hard coded values, they are mostly multiples of the Stage width/height :

MovieClip.prototype.createTerrain = function(){
  prevTimer = getTimer(); // for rendering rates

  // clear the previous rendering
  fieldMap.fillRect(new flashGeomRect(0, 0, Stage.width, Stage.height), 0x00000000);
  field.clear();

  ty = ca * _3dData.yoffset - sa * (_3dData.startz + _3dData.stepAmount); // adjust camera view angle
  tz = sa * _3dData.yoffset + ca * (_3dData.startz + _3dData.stepAmount); // adjust camera view angle
  scaleRatioB = _3dData.focalLength / (_3dData.focalLength + tz); // set initial scale ratio for perspective rendering

  for(z = _3dData.startz; z>=_3dData.startz - 650; z -= _3dData.stepAmount){  // loop through the rows, back to front rendering

    ty = ca * _3dData.yoffset - sa * z;  // adjust camera view angle
    tz = sa * _3dData.yoffset + ca * z;  // adjust camera view angle
    scaleRatioA = _3dData.focalLength / (_3dData.focalLength + tz); // set the new scale ratio for perspective rendering

    if(z == _3dData.startz){  // only need to grab these values at the very begining, subsequent segments can use previous values (point1)
      displace = -(parseInt(displaceMap.getPixel((750 - _3dData.stepAmount + _3dData.xoffset) / 8, (z + _3dData.zoffset) / 8), 16))*_3dData.hoffset;
      if(displace == undefined){ displace = 0; } 
      pixelArray[0].x = origin.x + (-250) * scaleRatioA;
      pixelArray[0].y = origin.y + (ty + displace) * scaleRatioA;
    }
    startx = pixelArray[0].x; // store for use on next row
    starty = pixelArray[0].y; // store for use on next row

    // grab these values at the begining of each row, subsequent segments can use previous values (point4)
    displace = -(parseInt(displaceMap.getPixel((750 - _3dData.stepAmount + _3dData.xoffset) / 8, (z + _3dData.zoffset + _3dData.stepAmount) / 8), 16))*_3dData.hoffset;
    if(displace==undefined){ displace = 0; } 
    BX = origin.x + (-250) * scaleRatioB;
    BY = origin.y + (ty + displace) * scaleRatioB;

    pixelCount = 0;

    for(x = -400; x<=400; x += _3dData.stepAmount){

      if(z == _3dData.startz){ // only need to grab these values on the first row, subsequent rows can use previous values (point2)
        displace = -(parseInt(displaceMap.getPixel((x + 1000 + _3dData.stepAmount + _3dData.xoffset) / 8, (z + _3dData.zoffset) / 8), 16))*_3dData.hoffset;
        if(displace==undefined){ displace = 0; } 
        pixelArray[pixelCount + _3dData.stepAmount].x = origin.x + (x + _3dData.stepAmount) * scaleRatioA;
        pixelArray[pixelCount + _3dData.stepAmount].y = origin.y + (ty + displace) * scaleRatioA;
      }
      nextX = pixelArray[pixelCount + _3dData.stepAmount].x; // store for use on next row
      nextY = pixelArray[pixelCount + _3dData.stepAmount].y; // store for use on next row

      // this is the only point that needs to be calculated for each segment every time (point3)
      displace = -(parseInt(displaceMap.getPixel((x + 1000 + _3dData.stepAmount + _3dData.xoffset) / 8, (z + _3dData.zoffset + _3dData.stepAmount) / 8), 16))*_3dData.hoffset;
      if(displace==undefined){ displace = 0; } 
      nextBx = origin.x + (x + _3dData.stepAmount) * scaleRatioB;
      nextBy = origin.y + (ty + displace) * scaleRatioB;

// triangle transform: theMatrix = new flashGeomMatrix( (pointB._x - pointA._x) / 100 , (pointB._y - pointA._y) / 100 , (pointC._x - pointA._x) / 100 , (pointC._y - pointA._y) / 100 , pointA._x , pointA._y );

      if(z < _3dData.startz){ // my first row is currently not using proper values, not sure why so I'll skip it till I figure it out
	if(useBitmaps){
          // grab the texture map color value, currently it's the same perlinNoise map as the displacemap, only green channel
          gcolor = greenMap.getPixel((x + 1000 + _3dData.xoffset + _3dData.stepAmount / 2) / 8, (z + _3dData.zoffset + _3dData.stepAmount / 2) / 8) >> 8 & 0xff;

          // draw the two triangles to make the segment
          theMatrix = new flashGeomMatrix( (nextX - startx) / 100 , (nextY - starty) / 100 , (BX - startx) / 100 , (BY - starty) / 100 , startx , starty );
          fieldMap.draw(triangles[gcolor], theMatrix);

          theMatrix = new flashGeomMatrix( (nextX - nextBx) / 100 , (nextY - nextBy) / 100 , (BX - nextBx) / 100 , (BY - nextBy) / 100 , nextBx , nextBy );
          fieldMap.draw(triangles[gcolor], theMatrix);
	}else{
	  // use the drawing API to render the quad (same number of points as the two triangles above)
	  with(field){
            gcolor = greenMap.getPixel((x + 1000 + _3dData.xoffset + _3dData.stepAmount / 2) / 8, (z + _3dData.zoffset + _3dData.stepAmount / 2) / 8);
	    lineStyle(1, 0x000000, 0);
	    beginFill(gcolor);
	    moveTo(startx, starty);
	    lineTo(nextX, nextY);
	    lineTo(nextBx, nextBy);
	    lineTo(BX, BY);
	    lineTo(startx, starty);
	    endFill();
	  }
	}
      }

      // store/transfer point data for next segment
      startx = nextX;
      starty = nextY;
      pixelArray[pixelCount].x = BX;
      BX = nextBx;
      pixelArray[pixelCount].y = BY;
      BY = nextBy;
      pixelCount += _3dData.stepAmount;

    } // end x loop

    // store remaining data for next row
    pixelArray[pixelCount].x = nextBx;
    pixelArray[pixelCount].y = nextBy;
    scaleRatioB = scaleRatioA;
  } // end z loop

  // position cutout indicator on top down view
  viewMap.mapBox._x = (750 + _3dData.xoffset) / 8;
  viewMap.mapBox._y = (z + _3dData.zoffset) / 8;

  renderRate.text = 'Rendered in ' + (getTimer() - prevTimer) + ' milliseconds';
  updateAfterEvent();

}; // end rendering function

Attached is an example that that lets you move a viewing box around the color map by holding the mouse over the arrows, or by clicking on the map. I’m curious to see the rendering rates different systems get for each method, please post your results.

Note to Adobe – Please give us a copyPixel routine using polygon shapes rather than rectangles!!!