public void clearBuffers(boolean color, boolean depth, boolean stencil) {
    int bits = 0;
    if (color) {
      // See explanations of the depth below, we must enable color write to be able to clear the
      // color buffer
      if (context.colorWriteEnabled == false) {
        glColorMask(true, true, true, true);
        context.colorWriteEnabled = true;
      }
      bits = GL_COLOR_BUFFER_BIT;
    }
    if (depth) {

      // glClear(GL_DEPTH_BUFFER_BIT) seems to not work when glDepthMask is false
      // here s some link on openl board
      // http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=257223
      // if depth clear is requested, we enable the depthMask
      if (context.depthWriteEnabled == false) {
        glDepthMask(true);
        context.depthWriteEnabled = true;
      }
      bits |= GL_DEPTH_BUFFER_BIT;
    }
    if (stencil) {
      bits |= GL_STENCIL_BUFFER_BIT;
    }
    if (bits != 0) {
      glClear(bits);
    }
  }
  private void setProjection(Matrix4f projMatrix) {
    if (context.matrixMode != GL_PROJECTION) {
      glMatrixMode(GL_PROJECTION);
      context.matrixMode = GL_PROJECTION;
    }

    glLoadMatrix(storeMatrix(projMatrix, fb16));
  }
 public void setFixedFuncBinding(FixedFuncBinding ffBinding, Object val) {
   switch (ffBinding) {
     case Color:
       context.color = (ColorRGBA) val;
       break;
     case MaterialAmbient:
       context.ambient = (ColorRGBA) val;
       break;
     case MaterialDiffuse:
       context.diffuse = (ColorRGBA) val;
       break;
     case MaterialSpecular:
       context.specular = (ColorRGBA) val;
       break;
     case MaterialShininess:
       context.shininess = (Float) val;
       break;
     case UseVertexColor:
       context.useVertexColor = (Boolean) val;
       break;
     case AlphaTestFallOff:
       context.alphaTestFallOff = (Float) val;
       break;
   }
 }
  private void setModelView(Matrix4f modelMatrix, Matrix4f viewMatrix) {
    if (context.matrixMode != GL_MODELVIEW) {
      glMatrixMode(GL_MODELVIEW);
      context.matrixMode = GL_MODELVIEW;
    }

    glLoadMatrix(storeMatrix(viewMatrix, fb16));
    glMultMatrix(storeMatrix(modelMatrix, fb16));
  }
  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));
  }
 /** Reset fixed function bindings to default values. */
 private void resetFixedFuncBindings() {
   context.alphaTestFallOff = 0f; // zero means disable alpha test!
   context.color = null;
   context.ambient = null;
   context.diffuse = null;
   context.specular = null;
   context.shininess = 0;
   context.useVertexColor = false;
 }
  public void clearClipRect() {
    if (context.clipRectEnabled) {
      glDisable(GL_SCISSOR_TEST);
      context.clipRectEnabled = false;

      clipX = 0;
      clipY = 0;
      clipW = 0;
      clipH = 0;
    }
  }
  public void clearClipRect() {
    GL gl = GLContext.getCurrentGL();
    if (context.clipRectEnabled) {
      gl.glDisable(GL.GL_SCISSOR_TEST);
      context.clipRectEnabled = false;

      clipX = 0;
      clipY = 0;
      clipW = 0;
      clipH = 0;
    }
  }
  public void renderMesh(Mesh mesh, int lod, int count) {
    if (mesh.getVertexCount() == 0) {
      return;
    }

    if (context.pointSize != mesh.getPointSize()) {
      glPointSize(mesh.getPointSize());
      context.pointSize = mesh.getPointSize();
    }
    if (context.lineWidth != mesh.getLineWidth()) {
      glLineWidth(mesh.getLineWidth());
      context.lineWidth = mesh.getLineWidth();
    }

    boolean dynamic = false;
    if (mesh.getBuffer(Type.InterleavedData) != null) {
      throw new UnsupportedOperationException("Interleaved meshes are not supported");
    }

    if (mesh.getNumLodLevels() == 0) {
      for (VertexBuffer vb : mesh.getBufferList().getArray()) {
        if (vb.getUsage() != VertexBuffer.Usage.Static) {
          dynamic = true;
          break;
        }
      }
    } else {
      dynamic = true;
    }

    statistics.onMeshDrawn(mesh, lod);

    //        if (!dynamic) {
    // dealing with a static object, generate display list
    //            renderMeshDisplayList(mesh);
    //        } else {
    renderMeshDefault(mesh, lod, count);
    //        }

  }
 public void setClipRect(int x, int y, int width, int height) {
   if (!context.clipRectEnabled) {
     glEnable(GL_SCISSOR_TEST);
     context.clipRectEnabled = true;
   }
   if (clipX != x || clipY != y || clipW != width || clipH != height) {
     glScissor(x, y, width, height);
     clipX = x;
     clipY = y;
     clipW = width;
     clipH = height;
   }
 }
  public void setVertexAttrib(VertexBuffer vb, VertexBuffer idb) {
    if (vb.getBufferType() == VertexBuffer.Type.Color && !context.useVertexColor) {
      // Ignore vertex color buffer if vertex color is disabled.
      return;
    }

    int arrayType = convertArrayType(vb.getBufferType());
    if (arrayType == -1) {
      return; // unsupported
    }
    glEnableClientState(arrayType);
    context.boundAttribs[vb.getBufferType().ordinal()] = vb;

    if (vb.getBufferType() == Type.Normal) {
      // normalize if requested
      if (vb.isNormalized() && !context.normalizeEnabled) {
        glEnable(GL_NORMALIZE);
        context.normalizeEnabled = true;
      } else if (!vb.isNormalized() && context.normalizeEnabled) {
        glDisable(GL_NORMALIZE);
        context.normalizeEnabled = false;
      }
    }

    // NOTE: Use data from interleaved buffer if specified
    Buffer data = idb != null ? idb.getData() : vb.getData();
    int comps = vb.getNumComponents();
    int type = convertVertexFormat(vb.getFormat());

    data.rewind();

    switch (vb.getBufferType()) {
      case Position:
        if (!(data instanceof FloatBuffer)) {
          throw new UnsupportedOperationException();
        }

        glVertexPointer(comps, vb.getStride(), (FloatBuffer) data);
        break;
      case Normal:
        if (!(data instanceof FloatBuffer)) {
          throw new UnsupportedOperationException();
        }

        glNormalPointer(vb.getStride(), (FloatBuffer) data);
        break;
      case Color:
        if (data instanceof FloatBuffer) {
          glColorPointer(comps, vb.getStride(), (FloatBuffer) data);
        } else if (data instanceof ByteBuffer) {
          glColorPointer(comps, true, vb.getStride(), (ByteBuffer) data);
        } else {
          throw new UnsupportedOperationException();
        }
        break;
      case TexCoord:
        if (!(data instanceof FloatBuffer)) {
          throw new UnsupportedOperationException();
        }

        glTexCoordPointer(comps, vb.getStride(), (FloatBuffer) data);
        break;
      default:
        // Ignore, this is an unsupported attribute for OpenGL1.
        break;
    }
  }
  public void setLighting(LightList list) {
    // XXX: This is abuse of setLighting() to
    // apply fixed function bindings
    // and do other book keeping.
    if (list == null || list.size() == 0) {
      glDisable(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);

    glEnable(GL_LIGHTING);

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

    glLightModel(GL_LIGHT_MODEL_AMBIENT, fb16);

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

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

      // Enable the light
      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();
          glLight(glLightIndex, GL_DIFFUSE, fb16);
          glLight(glLightIndex, 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();
          glLight(glLightIndex, GL_POSITION, fb16);
          glLightf(glLightIndex, 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();
          glLight(glLightIndex, GL_DIFFUSE, fb16);
          glLight(glLightIndex, GL_SPECULAR, fb16);

          pos = pLight.getPosition();
          fb16.clear();
          fb16.put(pos.x).put(pos.y).put(pos.z).put(1.0f).flip();
          glLight(glLightIndex, GL_POSITION, fb16);
          glLightf(glLightIndex, 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.
            glLightf(glLightIndex, GL_CONSTANT_ATTENUATION, 1);
            glLightf(glLightIndex, GL_LINEAR_ATTENUATION, pLight.getInvRadius() * 2);
            glLightf(
                glLightIndex,
                GL_QUADRATIC_ATTENUATION,
                pLight.getInvRadius() * pLight.getInvRadius());
          } else {
            glLightf(glLightIndex, GL_CONSTANT_ATTENUATION, 1);
            glLightf(glLightIndex, GL_LINEAR_ATTENUATION, 0);
            glLightf(glLightIndex, 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();
          glLight(glLightIndex, GL_DIFFUSE, fb16);
          glLight(glLightIndex, GL_SPECULAR, fb16);

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

          Vector3f dir = sLight.getDirection();
          fb16.clear();
          fb16.put(dir.x).put(dir.y).put(dir.z).put(1.0f).flip();
          glLight(glLightIndex, 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;
          }

          glLightf(glLightIndex, GL_SPOT_CUTOFF, spotCut);
          glLightf(glLightIndex, GL_SPOT_EXPONENT, spotExpo);

          if (sLight.getSpotRange() > 0) {
            glLightf(glLightIndex, GL_LINEAR_ATTENUATION, sLight.getInvSpotRange());
          } else {
            glLightf(glLightIndex, 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++) {
      glDisable(GL_LIGHT0 + i);
    }

    // This will set view matrix as well.
    setModelView(worldMatrix, viewMatrix);
  }
  public void applyRenderState(RenderState state) {
    if (state.isWireframe() && !context.wireframe) {
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
      context.wireframe = true;
    } else if (!state.isWireframe() && context.wireframe) {
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
      context.wireframe = false;
    }

    if (state.isDepthTest() && !context.depthTestEnabled) {
      glEnable(GL_DEPTH_TEST);
      glDepthFunc(GL_LEQUAL);
      context.depthTestEnabled = true;
    } else if (!state.isDepthTest() && context.depthTestEnabled) {
      glDisable(GL_DEPTH_TEST);
      context.depthTestEnabled = false;
    }

    if (state.isAlphaTest()) {
      setFixedFuncBinding(FixedFuncBinding.AlphaTestFallOff, state.getAlphaFallOff());
    } else {
      setFixedFuncBinding(FixedFuncBinding.AlphaTestFallOff, 0f); // disable it
    }

    if (state.isDepthWrite() && !context.depthWriteEnabled) {
      glDepthMask(true);
      context.depthWriteEnabled = true;
    } else if (!state.isDepthWrite() && context.depthWriteEnabled) {
      glDepthMask(false);
      context.depthWriteEnabled = false;
    }

    if (state.isColorWrite() && !context.colorWriteEnabled) {
      glColorMask(true, true, true, true);
      context.colorWriteEnabled = true;
    } else if (!state.isColorWrite() && context.colorWriteEnabled) {
      glColorMask(false, false, false, false);
      context.colorWriteEnabled = false;
    }

    if (state.isPointSprite()) {
      logger.log(Level.WARNING, "Point Sprite unsupported!");
    }

    if (state.isPolyOffset()) {
      if (!context.polyOffsetEnabled) {
        glEnable(GL_POLYGON_OFFSET_FILL);
        glPolygonOffset(state.getPolyOffsetFactor(), state.getPolyOffsetUnits());
        context.polyOffsetEnabled = true;
        context.polyOffsetFactor = state.getPolyOffsetFactor();
        context.polyOffsetUnits = state.getPolyOffsetUnits();
      } else {
        if (state.getPolyOffsetFactor() != context.polyOffsetFactor
            || state.getPolyOffsetUnits() != context.polyOffsetUnits) {
          glPolygonOffset(state.getPolyOffsetFactor(), state.getPolyOffsetUnits());
          context.polyOffsetFactor = state.getPolyOffsetFactor();
          context.polyOffsetUnits = state.getPolyOffsetUnits();
        }
      }
    } else {
      if (context.polyOffsetEnabled) {
        glDisable(GL_POLYGON_OFFSET_FILL);
        context.polyOffsetEnabled = false;
        context.polyOffsetFactor = 0;
        context.polyOffsetUnits = 0;
      }
    }
    if (state.getFaceCullMode() != context.cullMode) {
      if (state.getFaceCullMode() == RenderState.FaceCullMode.Off) {
        glDisable(GL_CULL_FACE);
      } else {
        glEnable(GL_CULL_FACE);
      }

      switch (state.getFaceCullMode()) {
        case Off:
          break;
        case Back:
          glCullFace(GL_BACK);
          break;
        case Front:
          glCullFace(GL_FRONT);
          break;
        case FrontAndBack:
          glCullFace(GL_FRONT_AND_BACK);
          break;
        default:
          throw new UnsupportedOperationException(
              "Unrecognized face cull mode: " + state.getFaceCullMode());
      }

      context.cullMode = state.getFaceCullMode();
    }

    if (state.getBlendMode() != context.blendMode) {
      if (state.getBlendMode() == RenderState.BlendMode.Off) {
        glDisable(GL_BLEND);
      } else {
        glEnable(GL_BLEND);
        switch (state.getBlendMode()) {
          case Off:
            break;
          case Additive:
            glBlendFunc(GL_ONE, GL_ONE);
            break;
          case AlphaAdditive:
            glBlendFunc(GL_SRC_ALPHA, GL_ONE);
            break;
          case Color:
            glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
            break;
          case Alpha:
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            break;
          case PremultAlpha:
            glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
            break;
          case Modulate:
            glBlendFunc(GL_DST_COLOR, GL_ZERO);
            break;
          case ModulateX2:
            glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
            break;
          default:
            throw new UnsupportedOperationException(
                "Unrecognized blend mode: " + state.getBlendMode());
        }
      }

      context.blendMode = state.getBlendMode();
    }

    if (state.isStencilTest()) {
      throw new UnsupportedOperationException(
          "OpenGL 1.1 doesn't support two sided stencil operations.");
    }
  }
 public void invalidateState() {
   context.reset();
 }