/**
   * Returns a ByteBuffer of BufferedImage data. Ensure BufferedImage is of 4BYTE_ABGR type. If
   * imageFormat is set to GL_RGBA, byte stream will be converted.
   */
  private ByteBuffer getByteBuffer(final BufferedImage _image) {
    final DataBuffer buffer = _image.getRaster().getDataBuffer();
    final int type = buffer.getDataType();

    if (type == DataBuffer.TYPE_BYTE) {
      final byte[] data = ((DataBufferByte) buffer).getData();
      if (imageFormat == GL3.GL_RGBA) {
        convertABGRtoRGBA(data);
      }

      return ByteBuffer.wrap(data);
    }

    System.out.println("Failed to determine DataBuffer type.");
    return null;
  }
  /**
   * Binds the BufferedImage byte-stream into video memory. BufferedImage must be in 4BYTE_ABGR.
   * 4BYTE_ABGR removes endinese problems.
   */
  public Texture bind(final BufferedImage _image, final InternalFormat _format) {
    final GL3 gl = GLRenderer.getCanvas().getContext().getCurrentGL().getGL3();
    if (gl == null) {
      System.out.println("GL context doesn't exist");
      return null;
    }

    gl.glEnable(GL.GL_TEXTURE_2D);

    final int textureID = glGenTextures(gl);
    gl.glBindTexture(GL3.GL_TEXTURE_2D, textureID);

    gl.glTexParameteri(GL3.GL_TEXTURE_2D, GL3.GL_TEXTURE_WRAP_S, GL3.GL_REPEAT);
    gl.glTexParameteri(GL3.GL_TEXTURE_2D, GL3.GL_TEXTURE_WRAP_T, GL3.GL_REPEAT);
    gl.glTexParameteri(GL3.GL_TEXTURE_2D, GL3.GL_TEXTURE_MAG_FILTER, GL3.GL_LINEAR);
    gl.glTexParameteri(GL3.GL_TEXTURE_2D, GL3.GL_TEXTURE_MIN_FILTER, GL3.GL_LINEAR_MIPMAP_LINEAR);

    final int width = _image.getWidth();
    final int height = _image.getHeight();
    final int channels = _image.getSampleModel().getNumBands();
    int internalFormat = GL3.GL_RGB;

    if (gl.isExtensionAvailable("GL_EXT_abgr") == true) {
      switch (channels) {
        case 4:
          imageFormat = GL2.GL_ABGR_EXT;
          break;
        case 3:
          imageFormat = GL3.GL_BGR;
          break;
        case 1:
          imageFormat = GL3.GL_RED;
          break;
      }
    } else {
      switch (channels) {
        case 4:
          imageFormat = GL3.GL_RGBA;
          break;
        case 3:
          imageFormat = GL3.GL_RGB;
          break;
        case 1:
          imageFormat = GL3.GL_RED;
          break;
      }
    }

    gl.glPixelStorei(GL3.GL_UNPACK_ALIGNMENT, 1);
    gl.glTexImage2D(
        GL3.GL_TEXTURE_2D,
        0,
        getGLInternalFormat(channels, _format),
        width,
        height,
        0,
        imageFormat,
        GL3.GL_UNSIGNED_BYTE,
        getByteBuffer(_image));

    gl.glGenerateMipmap(GL3.GL_TEXTURE_2D);
    gl.glBindTexture(GL.GL_TEXTURE_2D, 0); // Reset to default texture

    return new Texture(new GLImage(textureID, width, height));
  }