public void endShape(int mode) {
    shapeLast = vertexCount;
    shapeLastPlusClipped = shapeLast;

    // don't try to draw if there are no vertices
    // (fixes a bug in LINE_LOOP that re-adds a nonexistent vertex)
    if (vertexCount == 0) {
      shape = 0;
      return;
    }

    // convert points from model (X/Y/Z) to camera space (VX/VY/VZ).
    // Do this now because we will be clipping them on add_triangle.
    endShapeModelToCamera(shapeFirst, shapeLast);

    if (stroke) {
      endShapeStroke(mode);
    }

    if (fill) {
      endShapeFill();
    }

    // transform, light, and clip
    endShapeLighting(lightCount > 0 && fill);

    // convert points from camera space (VX, VY, VZ) to screen space (X, Y, Z)
    // (this appears to be wasted time with the OpenGL renderer)
    endShapeCameraToScreen(shapeFirst, shapeLastPlusClipped);

    // render shape and fill here if not saving the shapes for later
    // if true, the shapes will be rendered on endDraw
    if (!hints[ENABLE_DEPTH_SORT]) {
      if (fill) {
        if (triangleCount > 0) {
          renderTriangles(0, triangleCount);
          if (raw != null) {
            rawTriangles(0, triangleCount);
          }
          triangleCount = 0;
        }
      }
      if (stroke) {
        if (pointCount > 0) {
          renderPoints(0, pointCount);
          if (raw != null) {
            rawPoints(0, pointCount);
          }
          pointCount = 0;
        }

        if (lineCount > 0) {
          renderLines(0, lineCount);
          if (raw != null) {
            rawLines(0, lineCount);
          }
          lineCount = 0;
        }
      }
      pathCount = 0;
    }

    shape = 0;
  }