private void applyFogHint(Quality quality, FogStateRecord record) {
    final GL gl = GLU.getCurrentGL();

    int glHint = 0;
    switch (quality) {
      case PerVertex:
        glHint = GL.GL_FASTEST;
        break;
      case PerPixel:
        glHint = GL.GL_NICEST;
        break;
    }

    if (!record.isValid() || record.fogHint != glHint) {
      gl.glHint(GL.GL_FOG_HINT, glHint);
      record.fogHint = glHint;
    }
  }
  /**
   * <code>set</code> sets the OpenGL fog values if the state is enabled.
   *
   * @see com.jme.scene.state.RenderState#apply()
   */
  public void apply() {
    final GL gl = GLU.getCurrentGL();

    // ask for the current state record
    RenderContext<?> context = DisplaySystem.getDisplaySystem().getCurrentContext();
    FogStateRecord record = (FogStateRecord) context.getStateRecord(RS_FOG);
    context.currentStates[RS_FOG] = this;

    if (isEnabled()) {
      enableFog(true, record);

      if (record.isValid()) {
        if (record.fogStart != start) {
          gl.glFogf(GL.GL_FOG_START, start);
          record.fogStart = start;
        }
        if (record.fogEnd != end) {
          gl.glFogf(GL.GL_FOG_END, end);
          record.fogEnd = end;
        }
        if (record.density != density) {
          gl.glFogf(GL.GL_FOG_DENSITY, density);
          record.density = density;
        }
      } else {
        gl.glFogf(GL.GL_FOG_START, start);
        record.fogStart = start;
        gl.glFogf(GL.GL_FOG_END, end);
        record.fogEnd = end;
        gl.glFogf(GL.GL_FOG_DENSITY, density);
        record.density = density;
      }

      applyFogColor(getColor(), record);
      applyFogMode(densityFunction, record);
      applyFogHint(quality, record);
      applyFogSource(source, record);
    } else {
      enableFog(false, record);
    }

    if (!record.isValid()) record.validate();
  }
  private void enableFog(boolean enable, FogStateRecord record) {
    final GL gl = GLU.getCurrentGL();

    if (record.isValid()) {
      if (enable && !record.enabled) {
        gl.glEnable(GL.GL_FOG);
        record.enabled = true;
      } else if (!enable && record.enabled) {
        gl.glDisable(GL.GL_FOG);
        record.enabled = false;
      }
    } else {
      if (enable) {
        gl.glEnable(GL.GL_FOG);
      } else {
        gl.glDisable(GL.GL_FOG);
      }
      record.enabled = enable;
    }
  }
  private void applyFogMode(DensityFunction densityFunction, FogStateRecord record) {
    final GL gl = GLU.getCurrentGL();

    int glMode = 0;
    switch (densityFunction) {
      case Exponential:
        glMode = GL.GL_EXP;
        break;
      case Linear:
        glMode = GL.GL_LINEAR;
        break;
      case ExponentialSquared:
        glMode = GL.GL_EXP2;
        break;
    }

    if (!record.isValid() || record.fogMode != glMode) {
      gl.glFogi(GL.GL_FOG_MODE, glMode);
      record.fogMode = glMode;
    }
  }
  private void applyFogSource(CoordinateSource source, FogStateRecord record) {
    final GL gl = GLU.getCurrentGL();

    if (supportsFogCoords) {
      if (!record.isValid() || !source.equals(record.source)) {
        if (source == CoordinateSource.Depth) {
          gl.glFogi(GL.GL_FOG_COORDINATE_SOURCE_EXT, GL.GL_FRAGMENT_DEPTH_EXT);
        } else {
          gl.glFogi(GL.GL_FOG_COORDINATE_SOURCE_EXT, GL.GL_FOG_COORDINATE_EXT);
        }
      }
    }
  }
  private void applyFogColor(ColorRGBA color, FogStateRecord record) {
    final GL gl = GLU.getCurrentGL();

    if (!record.isValid() || !color.equals(record.fogColor)) {
      record.fogColor.set(color);
      record.colorBuff.clear();
      record
          .colorBuff
          .put(record.fogColor.r)
          .put(record.fogColor.g)
          .put(record.fogColor.b)
          .put(record.fogColor.a);
      record.colorBuff.flip();
      gl.glFogfv(GL.GL_FOG_COLOR, record.colorBuff); // TODO Check for float
    }
  }