/**
   * <code>setupTexture</code> initializes a new Texture object for use with TextureRenderer.
   * Generates a valid gl texture id for this texture and inits the data type for the texture.
   */
  public void setupTexture(final Texture tex) {
    if (tex.getType() != Type.TwoDimensional) {
      throw new IllegalArgumentException("Unsupported type: " + tex.getType());
    }
    final RenderContext context = ContextManager.getCurrentContext();
    final TextureStateRecord record =
        (TextureStateRecord) context.getStateRecord(RenderState.StateType.Texture);

    // check if we are already setup... if so, throw error.
    if (tex.getTextureKey() == null) {
      tex.setTextureKey(TextureKey.getRTTKey(tex.getMinificationFilter()));
    } else if (tex.getTextureIdForContext(context.getGlContextRep()) != 0) {
      throw new Ardor3dException("Texture is already setup and has id.");
    }

    // Create the texture
    final IntBuffer ibuf = BufferUtils.createIntBuffer(1);
    GL11.glGenTextures(ibuf);
    final int textureId = ibuf.get(0);
    tex.setTextureIdForContext(context.getGlContextRep(), textureId);

    LwjglTextureStateUtil.doTextureBind(tex, 0, true);

    // Initialize our texture with some default data.
    final int internalFormat = LwjglTextureUtil.getGLInternalFormat(tex.getTextureStoreFormat());
    final int dataFormat =
        LwjglTextureUtil.getGLPixelFormatFromStoreFormat(tex.getTextureStoreFormat());
    final int pixelDataType =
        LwjglTextureUtil.getGLPixelDataType(tex.getRenderedTexturePixelDataType());

    GL11.glTexImage2D(
        GL11.GL_TEXTURE_2D,
        0,
        internalFormat,
        _width,
        _height,
        0,
        dataFormat,
        pixelDataType,
        (ByteBuffer) null);

    // Setup filtering and wrap
    final TextureRecord texRecord = record.getTextureRecord(textureId, tex.getType());
    LwjglTextureStateUtil.applyFilter(tex, texRecord, 0, record, context.getCapabilities());
    LwjglTextureStateUtil.applyWrap(tex, texRecord, 0, record, context.getCapabilities());

    logger.fine("setup pbuffer tex" + textureId + ": " + _width + "," + _height);
  }
  private void render(
      final List<? extends Spatial> toDrawA,
      final Spatial toDrawB,
      final Scene toDrawC,
      final List<Texture> texs,
      final int clear) {
    try {
      if (_pbuffer == null || _pbuffer.isBufferLost()) {
        if (_pbuffer != null && _pbuffer.isBufferLost()) {
          logger.warning("PBuffer contents lost - will recreate the buffer");
          deactivate();
          _pbuffer.destroy();
        }
        initPbuffer();
      }

      if (texs.size() == 1
          && _useDirectRender
          && !texs.get(0).getTextureStoreFormat().isDepthFormat()) {
        // setup and render directly to a 2d texture.
        LwjglTextureStateUtil.doTextureBind(texs.get(0), 0, true);
        activate();
        switchCameraIn(clear);
        _pbuffer.releaseTexImage(Pbuffer.FRONT_LEFT_BUFFER);

        if (toDrawA != null) {
          doDraw(toDrawA);
        } else {
          doDraw(toDrawB);
        }

        switchCameraOut();

        deactivate();
        _pbuffer.bindTexImage(Pbuffer.FRONT_LEFT_BUFFER);
      } else {
        // render and copy to a texture
        activate();
        switchCameraIn(clear);

        if (toDrawA != null) {
          doDraw(toDrawA);
        } else {
          doDraw(toDrawB);
        }

        switchCameraOut();

        for (int i = 0; i < texs.size(); i++) {
          copyToTexture(texs.get(i), 0, 0, _width, _height, 0, 0);
        }

        deactivate();
      }

    } catch (final Exception e) {
      logger.logp(
          Level.SEVERE, this.getClass().toString(), "render(Spatial, Texture)", "Exception", e);
    }
  }
  public void copyToTexture(
      final Texture tex,
      final int x,
      final int y,
      final int width,
      final int height,
      final int xoffset,
      final int yoffset) {
    LwjglTextureStateUtil.doTextureBind(tex, 0, true);

    GL11.glCopyTexSubImage2D(GL11.GL_TEXTURE_2D, 0, xoffset, yoffset, x, y, width, height);
  }