private void setProjection(Matrix4f projMatrix) {
    GL gl = GLContext.getCurrentGL();
    if (context.matrixMode != GLMatrixFunc.GL_PROJECTION) {
      gl.getGL2ES1().glMatrixMode(GLMatrixFunc.GL_PROJECTION);
      context.matrixMode = GLMatrixFunc.GL_PROJECTION;
    }

    gl.getGL2ES1().glLoadMatrixf(storeMatrix(projMatrix, fb16));
  }
  private void setModelView(Matrix4f modelMatrix, Matrix4f viewMatrix) {
    GL gl = GLContext.getCurrentGL();
    if (context.matrixMode != GLMatrixFunc.GL_MODELVIEW) {
      gl.getGL2ES1().glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
      context.matrixMode = GLMatrixFunc.GL_MODELVIEW;
    }

    gl.getGL2ES1().glLoadMatrixf(storeMatrix(viewMatrix, fb16));
    gl.getGL2ES1().glMultMatrixf(storeMatrix(modelMatrix, fb16));
  }
  /** Applies fixed function bindings from the context to OpenGL */
  private void applyFixedFuncBindings(boolean forLighting) {
    GL gl = GLContext.getCurrentGL();
    if (forLighting) {
      gl.getGL2().glMaterialf(GL.GL_FRONT_AND_BACK, GLLightingFunc.GL_SHININESS, context.shininess);
      setMaterialColor(GLLightingFunc.GL_AMBIENT, context.ambient, ColorRGBA.DarkGray);
      setMaterialColor(GLLightingFunc.GL_DIFFUSE, context.diffuse, ColorRGBA.White);
      setMaterialColor(GLLightingFunc.GL_SPECULAR, context.specular, ColorRGBA.Black);

      if (context.useVertexColor) {
        gl.glEnable(GLLightingFunc.GL_COLOR_MATERIAL);
      } else {
        gl.glDisable(GLLightingFunc.GL_COLOR_MATERIAL);
      }
    } else {
      // Ignore other values as they have no effect when
      // GL_LIGHTING is disabled.
      ColorRGBA color = context.color;
      if (color != null) {
        gl.getGL2().glColor4f(color.r, color.g, color.b, color.a);
      } else {
        gl.getGL2().glColor4f(1, 1, 1, 1);
      }
    }
    if (context.alphaTestFallOff > 0f) {
      gl.glEnable(GL2ES1.GL_ALPHA_TEST);
      gl.getGL2ES1().glAlphaFunc(GL.GL_GREATER, context.alphaTestFallOff);
    } else {
      gl.glDisable(GL2ES1.GL_ALPHA_TEST);
    }
  }
  public void initialize() {
    GL gl = GLContext.getCurrentGL();
    if (gl.isExtensionAvailable("GL_VERSION_1_2")) {
      gl12 = true;
    }

    // workaround, always assume we support GLSL100
    // some cards just don't report this correctly
    caps.add(Caps.GLSL100);

    // Default values for certain GL state.
    gl.getGL2ES1().glShadeModel(GLLightingFunc.GL_SMOOTH);
    gl.getGL2().glColorMaterial(GL.GL_FRONT_AND_BACK, GLLightingFunc.GL_DIFFUSE);
    gl.glHint(GL2ES1.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);

    // Enable rescaling/normaling of normal vectors.
    // Fixes lighting issues with scaled models.
    if (gl12) {
      gl.glEnable(GL2ES1.GL_RESCALE_NORMAL);
    } else {
      gl.glEnable(GLLightingFunc.GL_NORMALIZE);
    }

    if (gl.isExtensionAvailable("GL_ARB_texture_non_power_of_two")) {
      caps.add(Caps.NonPowerOfTwoTextures);
    } else {
      logger.log(
          Level.WARNING,
          "Your graphics card does not "
              + "support non-power-of-2 textures. "
              + "Some features might not work.");
    }

    gl.glGetIntegerv(GL2ES1.GL_MAX_LIGHTS, ib1);
    maxLights = ib1.get(0);

    gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, ib1);
    maxTexSize = ib1.get(0);
  }
  public void setLighting(LightList list) {
    GL gl = GLContext.getCurrentGL();
    // XXX: This is abuse of setLighting() to
    // apply fixed function bindings
    // and do other book keeping.
    if (list == null || list.size() == 0) {
      gl.glDisable(GLLightingFunc.GL_LIGHTING);
      applyFixedFuncBindings(false);
      setModelView(worldMatrix, viewMatrix);
      return;
    }

    // Number of lights set previously
    int numLightsSetPrev = lightList.size();

    // If more than maxLights are defined, they will be ignored.
    // The GL1 renderer is not permitted to crash due to a
    // GL1 limitation. It must render anything that the GL2 renderer
    // can render (even incorrectly).
    lightList.clear();
    materialAmbientColor.set(0, 0, 0, 0);

    for (int i = 0; i < list.size(); i++) {
      Light l = list.get(i);
      if (l.getType() == Light.Type.Ambient) {
        // Gather
        materialAmbientColor.addLocal(l.getColor());
      } else {
        // Add to list
        lightList.add(l);

        // Once maximum lights reached, exit loop.
        if (lightList.size() >= maxLights) {
          break;
        }
      }
    }

    applyFixedFuncBindings(true);

    gl.glEnable(GLLightingFunc.GL_LIGHTING);

    fb16.clear();
    fb16.put(materialAmbientColor.r)
        .put(materialAmbientColor.g)
        .put(materialAmbientColor.b)
        .put(1)
        .flip();

    gl.getGL2ES1().glLightModelfv(GL2ES1.GL_LIGHT_MODEL_AMBIENT, fb16);

    if (context.matrixMode != GLMatrixFunc.GL_MODELVIEW) {
      gl.getGL2ES1().glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
      context.matrixMode = GLMatrixFunc.GL_MODELVIEW;
    }
    // Lights are already in world space, so just convert
    // them to view space.
    gl.getGL2ES1().glLoadMatrixf(storeMatrix(viewMatrix, fb16));

    for (int i = 0; i < lightList.size(); i++) {
      int glLightIndex = GLLightingFunc.GL_LIGHT0 + i;
      Light light = lightList.get(i);
      Light.Type lightType = light.getType();
      ColorRGBA col = light.getColor();
      Vector3f pos;

      // Enable the light
      gl.glEnable(glLightIndex);

      // OGL spec states default value for light ambient is black
      switch (lightType) {
        case Directional:
          DirectionalLight dLight = (DirectionalLight) light;

          fb16.clear();
          fb16.put(col.r).put(col.g).put(col.b).put(col.a).flip();
          gl.getGL2ES1().glLightfv(glLightIndex, GLLightingFunc.GL_DIFFUSE, fb16);
          gl.getGL2ES1().glLightfv(glLightIndex, GLLightingFunc.GL_SPECULAR, fb16);

          pos = tempVec.set(dLight.getDirection()).negateLocal().normalizeLocal();
          fb16.clear();
          fb16.put(pos.x).put(pos.y).put(pos.z).put(0.0f).flip();
          gl.getGL2ES1().glLightfv(glLightIndex, GLLightingFunc.GL_POSITION, fb16);
          gl.getGL2ES1().glLightf(glLightIndex, GLLightingFunc.GL_SPOT_CUTOFF, 180);
          break;
        case Point:
          PointLight pLight = (PointLight) light;

          fb16.clear();
          fb16.put(col.r).put(col.g).put(col.b).put(col.a).flip();
          gl.getGL2ES1().glLightfv(glLightIndex, GLLightingFunc.GL_DIFFUSE, fb16);
          gl.getGL2ES1().glLightfv(glLightIndex, GLLightingFunc.GL_SPECULAR, fb16);

          pos = pLight.getPosition();
          fb16.clear();
          fb16.put(pos.x).put(pos.y).put(pos.z).put(1.0f).flip();
          gl.getGL2ES1().glLightfv(glLightIndex, GLLightingFunc.GL_POSITION, fb16);
          gl.getGL2ES1().glLightf(glLightIndex, GLLightingFunc.GL_SPOT_CUTOFF, 180);

          if (pLight.getRadius() > 0) {
            // Note: this doesn't follow the same attenuation model
            // as the one used in the lighting shader.
            gl.getGL2ES1().glLightf(glLightIndex, GLLightingFunc.GL_CONSTANT_ATTENUATION, 1);
            gl.getGL2ES1()
                .glLightf(
                    glLightIndex, GLLightingFunc.GL_LINEAR_ATTENUATION, pLight.getInvRadius() * 2);
            gl.getGL2ES1()
                .glLightf(
                    glLightIndex,
                    GLLightingFunc.GL_QUADRATIC_ATTENUATION,
                    pLight.getInvRadius() * pLight.getInvRadius());
          } else {
            gl.getGL2ES1().glLightf(glLightIndex, GLLightingFunc.GL_CONSTANT_ATTENUATION, 1);
            gl.getGL2ES1().glLightf(glLightIndex, GLLightingFunc.GL_LINEAR_ATTENUATION, 0);
            gl.getGL2ES1().glLightf(glLightIndex, GLLightingFunc.GL_QUADRATIC_ATTENUATION, 0);
          }

          break;
        case Spot:
          SpotLight sLight = (SpotLight) light;

          fb16.clear();
          fb16.put(col.r).put(col.g).put(col.b).put(col.a).flip();
          gl.getGL2ES1().glLightfv(glLightIndex, GLLightingFunc.GL_DIFFUSE, fb16);
          gl.getGL2ES1().glLightfv(glLightIndex, GLLightingFunc.GL_SPECULAR, fb16);

          pos = sLight.getPosition();
          fb16.clear();
          fb16.put(pos.x).put(pos.y).put(pos.z).put(1.0f).flip();
          gl.getGL2().glLightfv(glLightIndex, GLLightingFunc.GL_POSITION, fb16);

          Vector3f dir = sLight.getDirection();
          fb16.clear();
          fb16.put(dir.x).put(dir.y).put(dir.z).put(1.0f).flip();
          gl.getGL2ES1().glLightfv(glLightIndex, GLLightingFunc.GL_SPOT_DIRECTION, fb16);

          float outerAngleRad = sLight.getSpotOuterAngle();
          float innerAngleRad = sLight.getSpotInnerAngle();
          float spotCut = outerAngleRad * FastMath.RAD_TO_DEG;
          float spotExpo = 0.0f;
          if (outerAngleRad > 0) {
            spotExpo = (1.0f - (innerAngleRad / outerAngleRad)) * 128.0f;
          }

          gl.getGL2ES1().glLightf(glLightIndex, GLLightingFunc.GL_SPOT_CUTOFF, spotCut);
          gl.getGL2ES1().glLightf(glLightIndex, GLLightingFunc.GL_SPOT_EXPONENT, spotExpo);

          if (sLight.getSpotRange() > 0) {
            gl.getGL2ES1()
                .glLightf(
                    glLightIndex, GLLightingFunc.GL_LINEAR_ATTENUATION, sLight.getInvSpotRange());
          } else {
            gl.getGL2ES1().glLightf(glLightIndex, GLLightingFunc.GL_LINEAR_ATTENUATION, 0);
          }

          break;
        default:
          throw new UnsupportedOperationException("Unrecognized light type: " + lightType);
      }
    }

    // Disable lights after the index
    for (int i = lightList.size(); i < numLightsSetPrev; i++) {
      gl.glDisable(GLLightingFunc.GL_LIGHT0 + i);
    }

    // This will set view matrix as well.
    setModelView(worldMatrix, viewMatrix);
  }